Decompiled source of BlightedWorldHeart v1.1.4

plugins/BlightedHeart.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("BlightedHeart")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A Valheim mod that adds the Blighted World Heart boss.")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: AssemblyInformationalVersion("1.1.3+da31fed5f0858afc1edb5e4d0fd5557d3cff946f")]
[assembly: AssemblyProduct("BlightedHeart")]
[assembly: AssemblyTitle("BlightedHeart")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BlightedHeart
{
	public static class BarrkBotExport
	{
		private static Coroutine _routine;

		private static HashSet<Biome> _previouslyActive = new HashSet<Biome>();

		private static readonly int BlightedHeartPrefabHash = StringExtensionMethods.GetStableHashCode("BlightedWorldHeart");

		private static bool _subscribedToZDODestroyed;

		private static string ExportDir => Path.Combine(Paths.ConfigPath, "BlightedHeart");

		private static string ExportPath => Path.Combine(ExportDir, "barrkbot_blightedheart.json");

		public static void OnZNetStart()
		{
			try
			{
				Reset();
				if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && BlightedConfigManager.EnableBarrkBotExport.Value)
				{
					_routine = ((MonoBehaviour)BlightedHeartPlugin.Instance).StartCoroutine(ExportRoutine());
					if (ZDOMan.instance != null)
					{
						ZDOMan instance = ZDOMan.instance;
						instance.m_onZDODestroyed = (Action<ZDO>)Delegate.Combine(instance.m_onZDODestroyed, new Action<ZDO>(OnZDODestroyed));
						_subscribedToZDODestroyed = true;
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"BlightedHeart: could not start the BarrkBOT export (non-fatal). Reason: {arg}");
			}
		}

		public static void Reset()
		{
			if (_routine != null && (Object)(object)BlightedHeartPlugin.Instance != (Object)null)
			{
				((MonoBehaviour)BlightedHeartPlugin.Instance).StopCoroutine(_routine);
			}
			_routine = null;
			_previouslyActive = new HashSet<Biome>();
			if (_subscribedToZDODestroyed && ZDOMan.instance != null)
			{
				ZDOMan instance = ZDOMan.instance;
				instance.m_onZDODestroyed = (Action<ZDO>)Delegate.Remove(instance.m_onZDODestroyed, new Action<ZDO>(OnZDODestroyed));
			}
			_subscribedToZDODestroyed = false;
		}

		private static void OnZDODestroyed(ZDO zdo)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (zdo != null && zdo.GetPrefab() == BlightedHeartPrefabHash)
				{
					BlightedHeartStats.RecordDefeat(BiomeAt(zdo.GetPosition()));
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("BlightedHeart: could not record a Heart defeat (non-fatal). Reason: " + ex.Message));
			}
		}

		private static Biome BiomeAt(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Biome val = Heightmap.FindBiome(position);
			if ((int)val == 0 && WorldGenerator.instance != null)
			{
				val = WorldGenerator.instance.GetBiome(position);
			}
			return val;
		}

		private static IEnumerator ExportRoutine()
		{
			yield return (object)new WaitForSeconds(5f);
			while (true)
			{
				Write();
				yield return (object)new WaitForSeconds(Mathf.Max(15f, BlightedConfigManager.BarrkBotExportIntervalSeconds.Value));
			}
		}

		private unsafe static void Write()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Dictionary<Biome, BlightedWorldHeartAI> dictionary = new Dictionary<Biome, BlightedWorldHeartAI>();
				BlightedWorldHeartAI[] array = Object.FindObjectsOfType<BlightedWorldHeartAI>();
				foreach (BlightedWorldHeartAI blightedWorldHeartAI in array)
				{
					if (!((Object)(object)blightedWorldHeartAI == (Object)null))
					{
						Biome key = BiomeAt(((Component)blightedWorldHeartAI).transform.position);
						dictionary[key] = blightedWorldHeartAI;
					}
				}
				HashSet<Biome> hashSet = new HashSet<Biome>(dictionary.Keys);
				foreach (Biome item in hashSet)
				{
					if (!_previouslyActive.Contains(item))
					{
						BlightedHeartStats.RecordSummon(item);
					}
				}
				_previouslyActive = hashSet;
				Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
				HashSet<Biome> hashSet2 = new HashSet<Biome>(hashSet);
				foreach (Biome key2 in BlightedHeartStats.Records.Keys)
				{
					hashSet2.Add(key2);
				}
				foreach (Biome item2 in hashSet2)
				{
					BlightedWorldHeartAI value;
					bool flag = dictionary.TryGetValue(item2, out value);
					BlightedHeartStats.Records.TryGetValue(item2, out var value2);
					dictionary2[((object)(*(Biome*)(&item2))/*cast due to .constrained prefix*/).ToString()] = new Dictionary<string, object>
					{
						["active"] = flag,
						["current_hp_percent"] = ((flag && value.m_maxHealth > 0f) ? ((object)Math.Round((double)(value.m_health / value.m_maxHealth) * 100.0, 1)) : null),
						["subboss_1_active"] = flag && value.SubBoss1Active,
						["subboss_2_active"] = flag && value.SubBoss2Active,
						["times_summoned"] = value2?.TimesSummoned ?? 0,
						["times_defeated"] = value2?.TimesDefeated ?? 0,
						["last_defeated"] = value2?.LastDefeatedUtc?.ToString("o", CultureInfo.InvariantCulture)
					};
				}
				Save(JsonConvert.SerializeObject((object)new Dictionary<string, object>
				{
					["generated_at"] = DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
					["source"] = "BlightedWorldHeart 1.1.3",
					["biomes"] = dictionary2
				}, (Formatting)1));
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"BlightedHeart: the BarrkBOT export could not be built (non-fatal, the previous file stands). Reason: {arg}");
			}
		}

		private static void Save(string json)
		{
			Directory.CreateDirectory(ExportDir);
			string text = ExportPath + ".tmp";
			File.WriteAllText(text, json);
			if (File.Exists(ExportPath))
			{
				File.Replace(text, ExportPath, null);
			}
			else
			{
				File.Move(text, ExportPath);
			}
		}
	}
	[HarmonyPatch]
	public static class BarrkBotExportPatches
	{
		[HarmonyPatch(typeof(ZNet), "Start")]
		[HarmonyPostfix]
		public static void ZNet_Start_Postfix()
		{
			BarrkBotExport.OnZNetStart();
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		[HarmonyPostfix]
		public static void ZNet_Shutdown_Postfix()
		{
			BarrkBotExport.Reset();
		}
	}
	[HarmonyPatch(typeof(Character), "OnDeath")]
	public static class BlightedHeartLoot
	{
		public static void Prefix(Character __instance)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			BlightedWorldHeartAI component = ((Component)__instance).GetComponent<BlightedWorldHeartAI>();
			if ((Object)(object)component != (Object)null && __instance.IsOwner())
			{
				Logger.LogInfo((object)"Blighted World Heart defeated! Dropping loot...");
				DropLoot(component.CurrentBiome, ((Component)__instance).transform.position + Vector3.up * 2f);
			}
		}

		private static void DropLoot(Biome biome, Vector3 dropPosition)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_00b0: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (!BlightedConfigManager.BiomeConfigs.TryGetValue(biome, out var value))
			{
				return;
			}
			float value2 = value.LootScaleFactor.Value;
			List<string> list = new List<string>();
			if (BlightedItemsManager.BiomeWeaponDrops.TryGetValue(biome, out var value3))
			{
				list.AddRange(value3);
			}
			if (BlightedItemsManager.BiomeArmorDrops.TryGetValue(biome, out var value4))
			{
				list.AddRange(value4);
			}
			if (list.Count == 0)
			{
				return;
			}
			int num = Mathf.CeilToInt(2f * value2);
			for (int i = 0; i < num; i++)
			{
				string text = list[Random.Range(0, list.Count)];
				GameObject val = ZNetScene.instance.GetPrefab(text);
				if ((Object)(object)val == (Object)null)
				{
					val = ObjectDB.instance.GetItemPrefab(text);
				}
				if ((Object)(object)val != (Object)null)
				{
					Vector3 val2 = dropPosition + Random.insideUnitSphere * 2f;
					Object.Instantiate<GameObject>(val, val2, Quaternion.identity);
				}
			}
		}
	}
	[HarmonyPatch(typeof(OfferingBowl))]
	public static class BlightedHeartSpawning
	{
		[HarmonyPatch("Interact")]
		[HarmonyPrefix]
		public static bool InteractPrefix(OfferingBowl __instance, Humanoid user, bool hold, bool alt)
		{
			if (hold)
			{
				return true;
			}
			_ = (Object)(object)__instance.m_bossPrefab == (Object)null;
			return true;
		}

		[HarmonyPatch("UseItem")]
		[HarmonyPrefix]
		public static bool UseItemPrefix(OfferingBowl __instance, Humanoid user, ItemData item, ref bool __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.m_bossPrefab == (Object)null)
			{
				return true;
			}
			Biome key = Heightmap.FindBiome(((Component)__instance).transform.position);
			if (!BlightedConfigManager.BiomeConfigs.TryGetValue(key, out var value))
			{
				return true;
			}
			string value2 = value.AltarSummonItem.Value;
			int value3 = value.AltarSummonAmount.Value;
			if (((Object)item.m_dropPrefab).name == value2)
			{
				if (item.m_stack < value3)
				{
					((Character)user).Message((MessageType)2, $"Need {value3} {item.m_shared.m_name}", 0, (Sprite)null, false);
					__result = true;
					return false;
				}
				user.GetInventory().RemoveItem(item, value3);
				((Character)user).Message((MessageType)2, "The Blighted World Heart awakens!", 0, (Sprite)null, false);
				SpawnBlightedHeart(__instance, user);
				__result = true;
				return false;
			}
			return true;
		}

		private static void SpawnBlightedHeart(OfferingBowl bowl, Humanoid user)
		{
			((MonoBehaviour)bowl).StartCoroutine(SpawnBlightedHeartCoroutine(bowl, user));
		}

		private static IEnumerator SpawnBlightedHeartCoroutine(OfferingBowl bowl, Humanoid user)
		{
			GameObject heartPrefab = PrefabManager.Instance.GetPrefab("BlightedWorldHeart");
			if ((Object)(object)heartPrefab == (Object)null)
			{
				Logger.LogError((object)"Failed to get BlightedWorldHeart prefab for spawning.");
				yield break;
			}
			bool flag = bowl.m_spawnPoints != null && bowl.m_spawnPoints.Count > 0 && (Object)(object)bowl.m_spawnPoints[0] != (Object)null;
			Vector3 spawnPos;
			if (flag)
			{
				spawnPos = bowl.m_spawnPoints[0].transform.position;
			}
			else
			{
				Vector3 val = Vector4.op_Implicit(((Component)bowl).transform.localToWorldMatrix * Vector4.op_Implicit(bowl.m_spawnAreaOffset));
				spawnPos = ((Component)bowl).transform.position + val + Vector3.up * 1f;
			}
			if ((int)Heightmap.FindBiome(spawnPos) == 2 && (Object)(object)user != (Object)null && !flag)
			{
				Vector3 val2 = ((Component)user).transform.position - ((Component)bowl).transform.position;
				val2.y = 0f;
				spawnPos += ((Vector3)(ref val2)).normalized * 12f;
			}
			float num = default(float);
			if (bowl.m_enableSolidHeightCheck && ZoneSystem.instance.GetSolidHeight(spawnPos, ref num, bowl.m_getSolidHeightMargin))
			{
				spawnPos.y = num + bowl.m_spawnYOffset;
			}
			if (bowl.m_spawnBossStartEffects != null)
			{
				bowl.m_spawnBossStartEffects.Create(spawnPos, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			yield return (object)new WaitForSeconds((bowl.m_spawnBossDelay > 0f) ? bowl.m_spawnBossDelay : 8f);
			GameObject obj = Object.Instantiate<GameObject>(heartPrefab, spawnPos, Quaternion.identity);
			Biome biome = Heightmap.FindBiome(spawnPos);
			BlightedWorldHeartAI component = obj.GetComponent<BlightedWorldHeartAI>();
			if ((Object)(object)component != (Object)null)
			{
				component.Initialize(biome);
			}
		}
	}
	public static class BlightedHeartStats
	{
		public class BiomeRecord
		{
			public int TimesSummoned;

			public int TimesDefeated;

			public DateTime? LastDefeatedUtc;
		}

		private class RawRecord
		{
			public int times_summoned;

			public int times_defeated;

			public string last_defeated;
		}

		private static Dictionary<Biome, BiomeRecord> _records;

		private static string StatsPath => Path.Combine(Paths.ConfigPath, "BlightedHeart", "stats.json");

		public static IReadOnlyDictionary<Biome, BiomeRecord> Records
		{
			get
			{
				EnsureLoaded();
				return _records;
			}
		}

		public static void RecordSummon(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			EnsureLoaded();
			GetOrAdd(biome).TimesSummoned++;
			Save();
		}

		public static void RecordDefeat(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			EnsureLoaded();
			BiomeRecord orAdd = GetOrAdd(biome);
			orAdd.TimesDefeated++;
			orAdd.LastDefeatedUtc = DateTime.UtcNow;
			Save();
		}

		private static BiomeRecord GetOrAdd(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!_records.TryGetValue(biome, out var value))
			{
				value = new BiomeRecord();
				_records[biome] = value;
			}
			return value;
		}

		private static void EnsureLoaded()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (_records != null)
			{
				return;
			}
			_records = new Dictionary<Biome, BiomeRecord>();
			try
			{
				if (!File.Exists(StatsPath))
				{
					return;
				}
				Dictionary<string, RawRecord> dictionary = JsonConvert.DeserializeObject<Dictionary<string, RawRecord>>(File.ReadAllText(StatsPath));
				if (dictionary == null)
				{
					return;
				}
				foreach (KeyValuePair<string, RawRecord> item in dictionary)
				{
					if (Enum.TryParse<Biome>(item.Key, out Biome result))
					{
						_records[result] = new BiomeRecord
						{
							TimesSummoned = item.Value.times_summoned,
							TimesDefeated = item.Value.times_defeated,
							LastDefeatedUtc = (string.IsNullOrEmpty(item.Value.last_defeated) ? ((DateTime?)null) : new DateTime?(DateTime.Parse(item.Value.last_defeated, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal)))
						};
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("BlightedHeart: could not read stats.json (non-fatal, starting fresh). Reason: " + ex.Message));
				_records = new Dictionary<Biome, BiomeRecord>();
			}
		}

		private static void Save()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Dictionary<string, RawRecord> dictionary = new Dictionary<string, RawRecord>();
				foreach (KeyValuePair<Biome, BiomeRecord> record in _records)
				{
					dictionary[((object)record.Key/*cast due to .constrained prefix*/).ToString()] = new RawRecord
					{
						times_summoned = record.Value.TimesSummoned,
						times_defeated = record.Value.TimesDefeated,
						last_defeated = record.Value.LastDefeatedUtc?.ToString("o", CultureInfo.InvariantCulture)
					};
				}
				Directory.CreateDirectory(Path.Combine(Paths.ConfigPath, "BlightedHeart"));
				string text = StatsPath + ".tmp";
				File.WriteAllText(text, JsonConvert.SerializeObject((object)dictionary, (Formatting)1));
				if (File.Exists(StatsPath))
				{
					File.Replace(text, StatsPath, null);
				}
				else
				{
					File.Move(text, StatsPath);
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("BlightedHeart: could not save stats.json (non-fatal, previous file stands). Reason: " + ex.Message));
			}
		}
	}
	public static class BlightedItemsManager
	{
		public static Dictionary<Biome, List<string>> BiomeWeaponDrops = new Dictionary<Biome, List<string>>();

		public static Dictionary<Biome, List<string>> BiomeArmorDrops = new Dictionary<Biome, List<string>>();

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

		private static Dictionary<string, Biome> _deferredRecipeBiomes = new Dictionary<string, Biome>();

		private static bool _recipesResolved = false;

		public static void Setup()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Setup;
			Logger.LogInfo((object)"Setting up Blighted custom items...");
			CreateBiomeItems((Biome)1, new string[5] { "Club", "SpearFlint", "Bow", "AxeFlint", "KnifeFlint" }, new string[6] { "ArmorLeatherChest", "ArmorLeatherLegs", "HelmetLeather", "CapeDeerHide", "ShieldWood", "ShieldWoodTower" });
			CreateBiomeItems((Biome)8, new string[7] { "SwordBronze", "MaceBronze", "AxeBronze", "AtgeirBronze", "SpearBronze", "KnifeCopper", "BowFineWood" }, new string[5] { "ArmorBronzeChest", "ArmorBronzeLegs", "HelmetBronze", "CapeTrollHide", "ShieldBronzeBuckler" });
			CreateBiomeItems((Biome)2, new string[5] { "SwordIron", "MaceIron", "Battleaxe", "AtgeirIron", "BowHuntsman" }, new string[8] { "ArmorIronChest", "ArmorIronLegs", "HelmetIron", "ShieldBanded", "ShieldIronTower", "ShieldIronSquare", "ShieldBoneTower", "ShieldSerpentscale" });
			CreateBiomeItems((Biome)4, new string[5] { "SwordSilver", "BowDraugrFang", "MaceSilver", "KnifeSilver", "SpearWolfFang" }, new string[5] { "ArmorWolfChest", "ArmorWolfLegs", "HelmetDrake", "CapeWolf", "ShieldSilver" });
			CreateBiomeItems((Biome)16, new string[4] { "SwordBlackmetal", "MaceNeedle", "AtgeirBlackmetal", "AxeBlackMetal" }, new string[6] { "ArmorPaddedCuirass", "ArmorPaddedGreaves", "HelmetPadded", "CapeLox", "ShieldBlackmetal", "ShieldBlackmetalTower" });
			CreateBiomeItems((Biome)512, new string[4] { "SwordMistwalker", "BowSpineSnap", "AtgeirHimminAfl", "CrossbowArbalest" }, new string[6] { "ArmorCarapaceChest", "ArmorCarapaceLegs", "HelmetCarapace", "CapeFeather", "ShieldCarapace", "ShieldCarapaceBuckler" });
			CreateBiomeItems((Biome)32, new string[7] { "AxeJotunBane", "THSwordKrom", "AxeBerzerkr", "MaceEldner", "SwordNiedhogg", "SpearSplitner", "BowAshlands" }, new string[9] { "ArmorFlametalChest", "ArmorFlametalLegs", "HelmetFlametal", "CapeAsh", "ShieldFlametal", "ShieldFlametalTower", "ArmorAshlandsMediumChest", "ArmorAshlandsMediumlegs", "HelmetAshlandsMediumHood" });
			CreateBiomeItems((Biome)64, new string[12]
			{
				"SwordGold_FrostFire", "MaceGold_FrostFire", "AxeGold_FrostFire", "AtgeirGold_FrostFire", "SpearGold_FrostFire", "KnifeGold_FrostFire", "BowGold_FrostFire", "CrossbowGold_FrostFire", "THSwordGold_FrostFire", "BattleaxeGold_FrostFire",
				"FistGold_FrostFire", "SledgeGold_FrostFire"
			}, new string[10] { "ArmorDeepNorthHeavyChest", "ArmorDeepNorthHeavylegs", "HelmetDNHeavy", "ArmorDeepNorthMediumChest", "ArmorDeepNorthMediumlegs", "HelmetDNMediumHood", "CapeDeepNorth", "ShieldGold", "ShieldGoldBuckler", "ShieldGoldTower" });
			Logger.LogInfo((object)"Blighted custom items created.");
		}

		private static void CreateBiomeItems(Biome biome, string[] weapons, string[] armors)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			float scale = 1f;
			if (BlightedConfigManager.BiomeConfigs.TryGetValue(biome, out var value))
			{
				scale = value.LootScaleFactor.Value;
			}
			BiomeWeaponDrops[biome] = new List<string>();
			BiomeArmorDrops[biome] = new List<string>();
			string[] array = weapons;
			foreach (string basePrefab in array)
			{
				string text = CreateWeaponVariant(biome, basePrefab, "Serpent", "of the Serpent", "Attacks deal additional poison damage.", scale, delegate(SharedData shared)
				{
					shared.m_damages.m_poison += 10f * scale;
				});
				if (text != null)
				{
					BiomeWeaponDrops[biome].Add(text);
				}
				string text2 = CreateWeaponVariant(biome, basePrefab, "Wraith", "of the Wraith", "Attacks deal additional spirit damage.", scale, delegate(SharedData shared)
				{
					shared.m_damages.m_spirit += 10f * scale;
				});
				if (text2 != null)
				{
					BiomeWeaponDrops[biome].Add(text2);
				}
				string text3 = CreateWeaponVariant(biome, basePrefab, "Blight", "of the Blight", "Attacks deal increased physical, poison, and spirit damage.", scale, delegate(SharedData shared)
				{
					shared.m_damages.m_poison += 5f * scale;
					shared.m_damages.m_spirit += 5f * scale;
					shared.m_damages.m_slash *= 1f + 0.05f * scale;
					shared.m_damages.m_blunt *= 1f + 0.05f * scale;
					shared.m_damages.m_pierce *= 1f + 0.05f * scale;
				});
				if (text3 != null)
				{
					BiomeWeaponDrops[biome].Add(text3);
				}
			}
			array = armors;
			foreach (string basePrefab2 in array)
			{
				string text4 = CreateArmorVariant(biome, basePrefab2, "Bastion", "of the Bastion", "Increased armor rating and durability.", scale, delegate(SharedData shared)
				{
					shared.m_armor *= 1f + 0.1f * scale;
					shared.m_maxDurability *= 1.5f;
				});
				if (text4 != null)
				{
					BiomeArmorDrops[biome].Add(text4);
				}
				string text5 = CreateArmorVariant(biome, basePrefab2, "Serpent", "of the Serpent", "Grants resistance to Poison.", scale, delegate(SharedData shared)
				{
					//IL_001b: 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_0030: 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)
					if (shared.m_damageModifiers == null)
					{
						shared.m_damageModifiers = new List<DamageModPair>();
					}
					shared.m_damageModifiers.Add(new DamageModPair
					{
						m_type = (DamageType)256,
						m_modifier = (DamageModifier)1
					});
				});
				if (text5 != null)
				{
					BiomeArmorDrops[biome].Add(text5);
				}
				string text6 = CreateArmorVariant(biome, basePrefab2, "Wraith", "of the Wraith", "Grants resistance to Spirit damage.", scale, delegate(SharedData shared)
				{
					//IL_001b: 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_0030: 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)
					if (shared.m_damageModifiers == null)
					{
						shared.m_damageModifiers = new List<DamageModPair>();
					}
					shared.m_damageModifiers.Add(new DamageModPair
					{
						m_type = (DamageType)512,
						m_modifier = (DamageModifier)1
					});
				});
				if (text6 != null)
				{
					BiomeArmorDrops[biome].Add(text6);
				}
				string text7 = CreateArmorVariant(biome, basePrefab2, "Blight", "of the Blight", "Increased armor and resistance to Poison and Spirit.", scale, delegate(SharedData shared)
				{
					//IL_003a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0047: Unknown result type (might be due to invalid IL or missing references)
					//IL_004f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0054: Unknown result type (might be due to invalid IL or missing references)
					//IL_0062: 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_0077: Unknown result type (might be due to invalid IL or missing references)
					//IL_007c: Unknown result type (might be due to invalid IL or missing references)
					shared.m_armor *= 1f + 0.05f * scale;
					if (shared.m_damageModifiers == null)
					{
						shared.m_damageModifiers = new List<DamageModPair>();
					}
					shared.m_damageModifiers.Add(new DamageModPair
					{
						m_type = (DamageType)256,
						m_modifier = (DamageModifier)1
					});
					shared.m_damageModifiers.Add(new DamageModPair
					{
						m_type = (DamageType)512,
						m_modifier = (DamageModifier)1
					});
				});
				if (text7 != null)
				{
					BiomeArmorDrops[biome].Add(text7);
				}
			}
		}

		private static string GetStationName(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			if ((int)biome <= 32)
			{
				if ((int)biome == 1)
				{
					return "piece_workbench";
				}
				if ((int)biome == 32)
				{
					goto IL_0025;
				}
			}
			else if ((int)biome == 64 || (int)biome == 512)
			{
				goto IL_0025;
			}
			return "forge";
			IL_0025:
			return "blackforge";
		}

		private static string[] GetBiomeTrophies(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0005: 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_001d: Expected I4, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				default:
					if ((int)biome != 8)
					{
						if ((int)biome != 16)
						{
							break;
						}
						return new string[2] { "TrophyGoblin", "TrophyDeathsquito" };
					}
					return new string[2] { "TrophyGreydwarfBrute", "TrophyGreydwarfShaman" };
				case 0:
					return new string[2] { "TrophyBoar", "TrophyNeck" };
				case 1:
					return new string[2] { "TrophyDraugr", "TrophyLeech" };
				case 3:
					return new string[2] { "TrophyWolf", "TrophyHatchling" };
				case 2:
					break;
				}
			}
			else
			{
				if ((int)biome == 32)
				{
					return new string[2] { "TrophyCharredMelee", "TrophyCharredArcher" };
				}
				if ((int)biome == 64)
				{
					return new string[2] { "TrophyElaking", "TrophyWrithan" };
				}
				if ((int)biome == 512)
				{
					return new string[2] { "TrophySeeker", "TrophyTick" };
				}
			}
			return new string[2] { "TrophyBoar", "TrophyNeck" };
		}

		public static void ResolveVanillaRecipeMaterials()
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			if (_recipesResolved)
			{
				return;
			}
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				Logger.LogWarning((object)"ResolveVanillaRecipeMaterials called but ObjectDB.instance is null!");
				return;
			}
			_recipesResolved = true;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			bool isWackyDBInstalled = BlightedHeartPlugin.IsWackyDBInstalled;
			if (isWackyDBInstalled)
			{
				Logger.LogInfo((object)$"WackyDB detected: {WackyDbCompat.RecipeYamlCount} recipe YAML(s) under '{WackyDbCompat.RecipesDir}'. Blighted recipes named there are left to the YAML.");
			}
			foreach (KeyValuePair<string, string> deferredRecipeLookup in _deferredRecipeLookups)
			{
				string blightedName = deferredRecipeLookup.Key;
				string basePrefab = deferredRecipeLookup.Value;
				Recipe val = ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)((Component)r.m_item).gameObject).name == blightedName));
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if (isWackyDBInstalled)
				{
					if (WackyDbCompat.HasRecipeYaml("Recipe_" + blightedName) || WackyDbCompat.HasRecipeYaml(((Object)val).name))
					{
						num3++;
						continue;
					}
					if (_deferredRecipeBiomes.TryGetValue(blightedName, out var value) && !IsUntouchedTrophyOnlyRecipe(val, value))
					{
						num4++;
						continue;
					}
				}
				Recipe val2 = ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)((Component)r.m_item).gameObject).name == basePrefab));
				if ((Object)(object)val2 == (Object)null || val2.m_resources == null)
				{
					Logger.LogWarning((object)("Could not find vanilla recipe for '" + basePrefab + "', upgrade for '" + blightedName + "' will only require trophies."));
					num2++;
					continue;
				}
				List<Requirement> list = ((val.m_resources != null) ? new List<Requirement>(val.m_resources) : new List<Requirement>());
				bool value2 = BlightedConfigManager.AllowRefinementForgeUpgrades.Value;
				Requirement[] resources = val2.m_resources;
				foreach (Requirement val3 in resources)
				{
					if ((Object)(object)val3.m_resItem == (Object)null)
					{
						continue;
					}
					if (val3.m_upgraderResource)
					{
						if (value2)
						{
							list.Add(new Requirement
							{
								m_resItem = val3.m_resItem,
								m_amount = val3.m_amount,
								m_amountPerLevel = val3.m_amountPerLevel,
								m_upgraderResource = true,
								m_recover = val3.m_recover
							});
						}
					}
					else if (val3.m_amountPerLevel > 0)
					{
						list.Add(new Requirement
						{
							m_resItem = val3.m_resItem,
							m_amount = 0,
							m_amountPerLevel = val3.m_amountPerLevel,
							m_recover = true
						});
					}
				}
				val.m_resources = list.ToArray();
				num++;
			}
			if (isWackyDBInstalled)
			{
				Logger.LogInfo((object)$"Resolved vanilla recipe materials for {num} blighted items ({num2} could not be resolved, {num3} left to WackyDB YAML on disk, {num4} left to WackyDB server-synced YAML).");
			}
			else
			{
				Logger.LogInfo((object)$"Resolved vanilla recipe materials for {num} blighted items ({num2} could not be resolved).");
			}
			ValidateBlightedRecipes();
		}

		private static void ValidateBlightedRecipes()
		{
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			int removed = 0;
			ObjectDB.instance.m_recipes.RemoveAll(delegate(Recipe r)
			{
				if ((Object)(object)r == (Object)null)
				{
					return false;
				}
				if ((Object)(object)r.m_item == (Object)null)
				{
					return false;
				}
				if (!((Object)((Component)r.m_item).gameObject).name.StartsWith("Blighted"))
				{
					return false;
				}
				bool flag = false;
				try
				{
					ItemData itemData = r.m_item.m_itemData;
					if (itemData == null || itemData.m_shared == null)
					{
						flag = true;
					}
					else if (itemData.m_shared.m_dlc == null)
					{
						itemData.m_shared.m_dlc = string.Empty;
					}
					if (itemData == null || itemData.m_shared?.m_name == null)
					{
						flag = true;
					}
				}
				catch
				{
					flag = true;
				}
				if (flag)
				{
					Logger.LogWarning((object)("Removing corrupted blighted recipe for '" + ((Object)((Component)r.m_item).gameObject).name + "' to prevent crafting list crash."));
					removed++;
				}
				return flag;
			});
			if (removed > 0)
			{
				Logger.LogWarning((object)$"Removed {removed} corrupted blighted recipe(s) from ObjectDB.");
			}
		}

		private static bool IsUntouchedTrophyOnlyRecipe(Recipe recipe, Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			string[] biomeTrophies = GetBiomeTrophies(biome);
			Requirement[] resources = recipe.m_resources;
			if (resources == null || resources.Length != biomeTrophies.Length)
			{
				return false;
			}
			HashSet<string> hashSet = new HashSet<string>();
			Requirement[] array = resources;
			foreach (Requirement val in array)
			{
				if (val == null || (Object)(object)val.m_resItem == (Object)null)
				{
					return false;
				}
				if (val.m_amount != 0 || val.m_amountPerLevel != 2)
				{
					return false;
				}
				string name = ((Object)((Component)val.m_resItem).gameObject).name;
				if (Array.IndexOf(biomeTrophies, name) < 0 || !hashSet.Add(name))
				{
					return false;
				}
			}
			return true;
		}

		private static string CreateWeaponVariant(Biome biome, string basePrefab, string suffixId, string suffixName, string effectDescription, float scale, Action<SharedData> modify)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			string text = $"Blighted{biome}_{basePrefab}_{suffixId}";
			if ((Object)(object)PrefabManager.Instance.GetPrefab(basePrefab) == (Object)null)
			{
				return null;
			}
			CustomItem val = new CustomItem(text, basePrefab);
			SharedData shared = val.ItemDrop.m_itemData.m_shared;
			if (shared.m_dlc == null)
			{
				shared.m_dlc = string.Empty;
			}
			shared.m_name = "Blighted " + shared.m_name + " " + suffixName;
			shared.m_description = "<color=yellow>" + effectDescription + "</color>\n" + shared.m_description;
			shared.m_damages.m_blunt *= 1f + 0.05f * scale;
			shared.m_damages.m_slash *= 1f + 0.05f * scale;
			shared.m_damages.m_pierce *= 1f + 0.05f * scale;
			modify?.Invoke(shared);
			TintItemPrefab(val);
			ItemManager.Instance.AddItem(val);
			string[] biomeTrophies = GetBiomeTrophies(biome);
			List<RequirementConfig> list = new List<RequirementConfig>();
			_deferredRecipeLookups[text] = basePrefab;
			_deferredRecipeBiomes[text] = biome;
			string[] array = biomeTrophies;
			foreach (string item in array)
			{
				list.Add(new RequirementConfig
				{
					Item = item,
					Amount = 0,
					AmountPerLevel = 2
				});
			}
			CustomRecipe val2 = new CustomRecipe(new RecipeConfig
			{
				Item = text,
				Amount = 1,
				CraftingStation = GetStationName(biome),
				Enabled = true,
				Requirements = list.ToArray()
			});
			ItemManager.Instance.AddRecipe(val2);
			return text;
		}

		private static string CreateArmorVariant(Biome biome, string basePrefab, string suffixId, string suffixName, string effectDescription, float scale, Action<SharedData> modify)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			string text = $"Blighted{biome}_{basePrefab}_{suffixId}";
			if ((Object)(object)PrefabManager.Instance.GetPrefab(basePrefab) == (Object)null)
			{
				return null;
			}
			CustomItem val = new CustomItem(text, basePrefab);
			SharedData shared = val.ItemDrop.m_itemData.m_shared;
			if (shared.m_dlc == null)
			{
				shared.m_dlc = string.Empty;
			}
			shared.m_name = "Blighted " + shared.m_name + " " + suffixName;
			shared.m_description = "<color=yellow>" + effectDescription + "</color>\n" + shared.m_description;
			shared.m_armor *= 1f + 0.05f * scale;
			modify?.Invoke(shared);
			TintItemPrefab(val);
			ItemManager.Instance.AddItem(val);
			string[] biomeTrophies = GetBiomeTrophies(biome);
			List<RequirementConfig> list = new List<RequirementConfig>();
			_deferredRecipeLookups[text] = basePrefab;
			_deferredRecipeBiomes[text] = biome;
			string[] array = biomeTrophies;
			foreach (string item in array)
			{
				list.Add(new RequirementConfig
				{
					Item = item,
					Amount = 0,
					AmountPerLevel = 2
				});
			}
			CustomRecipe val2 = new CustomRecipe(new RecipeConfig
			{
				Item = text,
				Amount = 1,
				CraftingStation = GetStationName(biome),
				Enabled = true,
				Requirements = list.ToArray()
			});
			ItemManager.Instance.AddRecipe(val2);
			return text;
		}

		private static void TintItemPrefab(CustomItem customItem)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			Color blightedTint = default(Color);
			((Color)(ref blightedTint))..ctor(0.1f, 0.4f, 0.1f, 1f);
			Renderer[] componentsInChildren = customItem.ItemPrefab.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material[] materials = componentsInChildren[i].materials;
				for (int j = 0; j < materials.Length; j++)
				{
					TintMaterial(materials[j], blightedTint);
				}
			}
			SharedData shared = customItem.ItemDrop.m_itemData.m_shared;
			if (shared != null && (Object)(object)shared.m_armorMaterial != (Object)null)
			{
				shared.m_armorMaterial = new Material(shared.m_armorMaterial);
				TintMaterial(shared.m_armorMaterial, blightedTint);
			}
		}

		private static void TintMaterial(Material mat, Color blightedTint)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)mat == (Object)null))
			{
				if (mat.HasProperty("_Color"))
				{
					mat.color = Color.Lerp(mat.color, blightedTint, 0.8f);
				}
				if (mat.HasProperty("_EmissionColor") && mat.IsKeywordEnabled("_EMISSION"))
				{
					mat.SetColor("_EmissionColor", mat.GetColor("_EmissionColor") * blightedTint);
				}
			}
		}
	}
	[HarmonyPatch]
	public static class BlightedMechanicsPatches
	{
		[HarmonyPatch(typeof(Player), "OnSpawned")]
		[HarmonyPostfix]
		public static void PlayerOnSpawnedPostfix()
		{
			BlightedItemsManager.ResolveVanillaRecipeMaterials();
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		[HarmonyPrefix]
		public static bool DamagePrefix(Character __instance, HitData hit)
		{
			if ((Object)(object)((Component)__instance).GetComponent<BlightedWorldHeartAI>() != (Object)null && hit != null && ((Object)(object)hit.GetAttacker() == (Object)null || !hit.GetAttacker().IsPlayer()))
			{
				return false;
			}
			if (hit != null && !((Object)(object)hit.GetAttacker() == (Object)null))
			{
				hit.GetAttacker().IsPlayer();
			}
			return true;
		}

		[HarmonyPatch(typeof(Player), "GetAvailableRecipes")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		public static void HideBlightedCrafting(Player __instance, ref List<Recipe> available)
		{
			try
			{
				if ((!((Object)(object)__instance != (Object)null) || !__instance.NoCostCheat()) && available != null && (Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.InCraftTab())
				{
					available.RemoveAll((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)((Component)r.m_item).gameObject).name.StartsWith("Blighted") && IsRecipeFreeAtLevel1(r));
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("HideBlightedCrafting postfix failed (non-fatal): " + ex.Message));
			}
		}

		private static bool IsRecipeFreeAtLevel1(Recipe r)
		{
			if (r.m_resources == null || r.m_resources.Length == 0)
			{
				return true;
			}
			Requirement[] resources = r.m_resources;
			foreach (Requirement val in resources)
			{
				if (val != null && !val.m_upgraderResource && val.m_amount > 0)
				{
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Player), "AddKnownRecipe")]
		[HarmonyPrefix]
		public static bool AddKnownRecipePrefix(Player __instance, Recipe recipe)
		{
			try
			{
				if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null)
				{
					return true;
				}
				if (!((Object)((Component)recipe.m_item).gameObject).name.StartsWith("Blighted"))
				{
					return true;
				}
				SharedData val = ((recipe.m_item.m_itemData != null) ? recipe.m_item.m_itemData.m_shared : null);
				if (val == null || string.IsNullOrEmpty(val.m_name))
				{
					return true;
				}
				__instance.m_knownRecipes.Add(val.m_name);
				return false;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("AddKnownRecipePrefix failed (non-fatal, using vanilla behaviour): " + ex.Message));
				return true;
			}
		}

		[HarmonyPatch(typeof(Player), "AddKnownItem", new Type[] { typeof(ItemData) })]
		[HarmonyPrefix]
		public static void AddKnownItemPrefix(Player __instance, ItemData item)
		{
			if (item == null || (Object)(object)item.m_dropPrefab == (Object)null || !((Object)item.m_dropPrefab).name.StartsWith("Blighted"))
			{
				return;
			}
			string prefabName = ((Object)item.m_dropPrefab).name;
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			Recipe val = ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)((Component)r.m_item).gameObject).name == prefabName));
			if ((Object)(object)val == (Object)null || val.m_resources == null)
			{
				return;
			}
			Requirement[] resources = val.m_resources;
			foreach (Requirement val2 in resources)
			{
				if ((Object)(object)val2.m_resItem != (Object)null && val2.m_resItem.m_itemData != null && val2.m_resItem.m_itemData.m_shared != null)
				{
					__instance.m_knownMaterial.Add(val2.m_resItem.m_itemData.m_shared.m_name);
				}
			}
		}
	}
	public class BlightedUIManager : MonoBehaviour
	{
		private static BlightedUIManager _instance;

		private GameObject _uiRoot;

		private BlightedWorldHeartAI _activeHeart;

		private Character _trackedSubBoss1;

		private Character _trackedSubBoss2;

		private Vector3 _heartPosition;

		private RectTransform _mainBossBar;

		private Image _mainBossFill;

		private Text _mainBossName;

		private RectTransform _subBoss1Bar;

		private Image _subBoss1Fill;

		private Text _subBoss1Name;

		private RectTransform _subBoss2Bar;

		private Image _subBoss2Fill;

		private Text _subBoss2Name;

		private Font _valheimFont;

		public static BlightedUIManager Instance => _instance;

		public void Awake()
		{
			_instance = this;
		}

		public void RegisterHeart(BlightedWorldHeartAI heart)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			_activeHeart = heart;
			if ((Object)(object)_activeHeart != (Object)null)
			{
				_heartPosition = ((Component)_activeHeart).transform.position;
			}
			if ((Object)(object)_uiRoot == (Object)null && (Object)(object)Hud.instance != (Object)null)
			{
				CreateUI();
			}
		}

		public void UnregisterHeart(BlightedWorldHeartAI heart)
		{
			if ((Object)(object)_activeHeart == (Object)(object)heart)
			{
				_activeHeart = null;
			}
		}

		private void CreateUI()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_008c: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Hud.instance == (Object)null) && !((Object)(object)Hud.instance.m_rootObject == (Object)null))
			{
				Text componentInChildren = Hud.instance.m_rootObject.GetComponentInChildren<Text>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					_valheimFont = componentInChildren.font;
				}
				_uiRoot = new GameObject("BlightedCustomBossUI");
				_uiRoot.transform.SetParent(Hud.instance.m_rootObject.transform, false);
				RectTransform obj = _uiRoot.AddComponent<RectTransform>();
				obj.anchorMin = new Vector2(0.5f, 1f);
				obj.anchorMax = new Vector2(0.5f, 1f);
				obj.pivot = new Vector2(0.5f, 1f);
				obj.anchoredPosition = new Vector2(0f, -50f);
				CreateHealthBar("MainBossBar", _uiRoot.transform, new Vector2(0f, 0f), new Vector2(600f, 30f), out _mainBossBar, out _mainBossFill, out _mainBossName);
				CreateHealthBar("SubBoss1Bar", _uiRoot.transform, new Vector2(-200f, -50f), new Vector2(250f, 20f), out _subBoss1Bar, out _subBoss1Fill, out _subBoss1Name);
				CreateHealthBar("SubBoss2Bar", _uiRoot.transform, new Vector2(200f, -50f), new Vector2(250f, 20f), out _subBoss2Bar, out _subBoss2Fill, out _subBoss2Name);
				_uiRoot.SetActive(false);
			}
		}

		private void CreateHealthBar(string name, Transform parent, Vector2 anchoredPos, Vector2 size, out RectTransform rootRt, out Image fill, out Text nameText)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_018c: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			rootRt = val.AddComponent<RectTransform>();
			rootRt.anchorMin = new Vector2(0.5f, 1f);
			rootRt.anchorMax = new Vector2(0.5f, 1f);
			rootRt.pivot = new Vector2(0.5f, 1f);
			rootRt.anchoredPosition = anchoredPos;
			rootRt.sizeDelta = size;
			GameObject val2 = new GameObject("Trim");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj = val2.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(-2f, -2f);
			obj.offsetMax = new Vector2(2f, 2f);
			((Graphic)val2.AddComponent<Image>()).color = new Color(1f, 0.84f, 0f, 1f);
			GameObject val3 = new GameObject("Bkg");
			val3.transform.SetParent(val.transform, false);
			RectTransform obj2 = val3.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.sizeDelta = Vector2.zero;
			((Graphic)val3.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.9f);
			GameObject val4 = new GameObject("Fill");
			val4.transform.SetParent(val.transform, false);
			RectTransform obj3 = val4.AddComponent<RectTransform>();
			obj3.anchorMin = new Vector2(0f, 0f);
			obj3.anchorMax = new Vector2(1f, 1f);
			obj3.sizeDelta = Vector2.zero;
			obj3.pivot = new Vector2(0f, 0.5f);
			fill = val4.AddComponent<Image>();
			((Graphic)fill).color = Color.magenta;
			GameObject val5 = new GameObject("NameText");
			val5.transform.SetParent(val.transform, false);
			RectTransform obj4 = val5.AddComponent<RectTransform>();
			obj4.anchorMin = new Vector2(0.5f, 0.5f);
			obj4.anchorMax = new Vector2(0.5f, 0.5f);
			obj4.pivot = new Vector2(0.5f, 0.5f);
			obj4.anchoredPosition = new Vector2(0f, 0f);
			obj4.sizeDelta = new Vector2(500f, 30f);
			nameText = val5.AddComponent<Text>();
			nameText.alignment = (TextAnchor)4;
			((Graphic)nameText).color = Color.white;
			nameText.fontSize = 20;
			if ((Object)(object)_valheimFont != (Object)null)
			{
				nameText.font = _valheimFont;
			}
			else
			{
				nameText.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			Shadow obj5 = val5.AddComponent<Shadow>();
			obj5.effectColor = Color.black;
			obj5.effectDistance = new Vector2(1f, -1f);
		}

		public void LateUpdate()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Hud.instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)_activeHeart != (Object)null && _activeHeart.m_health > 0f)
			{
				_heartPosition = ((Component)_activeHeart).transform.position;
				if ((Object)(object)_activeHeart.m_subBoss1 != (Object)null)
				{
					_trackedSubBoss1 = _activeHeart.m_subBoss1;
				}
				if ((Object)(object)_activeHeart.m_subBoss2 != (Object)null)
				{
					_trackedSubBoss2 = _activeHeart.m_subBoss2;
				}
			}
			bool flag = (Object)(object)_activeHeart != (Object)null && _activeHeart.m_health > 0f;
			bool flag2 = (Object)(object)_trackedSubBoss1 != (Object)null && !_trackedSubBoss1.IsDead();
			bool flag3 = (Object)(object)_trackedSubBoss2 != (Object)null && !_trackedSubBoss2.IsDead();
			if (!flag && !flag2 && !flag3)
			{
				if ((Object)(object)_uiRoot != (Object)null && _uiRoot.activeSelf)
				{
					_uiRoot.SetActive(false);
				}
				return;
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null && Vector3.Distance(((Component)Player.m_localPlayer).transform.position, _heartPosition) > 100f)
			{
				if ((Object)(object)_uiRoot != (Object)null && _uiRoot.activeSelf)
				{
					_uiRoot.SetActive(false);
				}
				return;
			}
			if ((Object)(object)_uiRoot == (Object)null)
			{
				CreateUI();
			}
			if (!((Object)(object)_uiRoot == (Object)null))
			{
				if (!_uiRoot.activeSelf)
				{
					_uiRoot.SetActive(true);
				}
				UpdateBars(flag, flag2, flag3);
			}
		}

		private void UpdateBars(bool heartAlive, bool sb1Alive, bool sb2Alive)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			if (heartAlive)
			{
				((Component)_mainBossBar).gameObject.SetActive(true);
				float health = _activeHeart.m_health;
				float maxHealth = _activeHeart.m_maxHealth;
				((Graphic)_mainBossFill).color = GetBiomeColor(_activeHeart.CurrentBiome);
				_mainBossName.text = "Blighted World Heart";
				UpdateFill(_mainBossFill, health, maxHealth);
			}
			else
			{
				((Component)_mainBossBar).gameObject.SetActive(false);
			}
			float num = (heartAlive ? (-50f) : 0f);
			if (sb1Alive)
			{
				((Component)_subBoss1Bar).gameObject.SetActive(true);
				_subBoss1Name.text = GetLocalizedBlightedName(_trackedSubBoss1.m_name);
				((Graphic)_subBoss1Fill).color = new Color(0.2f, 0.6f, 1f, 1f);
				UpdateFill(_subBoss1Fill, _trackedSubBoss1.GetHealth(), _trackedSubBoss1.GetMaxHealth());
			}
			else
			{
				((Component)_subBoss1Bar).gameObject.SetActive(false);
			}
			if (sb2Alive)
			{
				((Component)_subBoss2Bar).gameObject.SetActive(true);
				_subBoss2Name.text = GetLocalizedBlightedName(_trackedSubBoss2.m_name);
				((Graphic)_subBoss2Fill).color = new Color(0.2f, 0.6f, 1f, 1f);
				UpdateFill(_subBoss2Fill, _trackedSubBoss2.GetHealth(), _trackedSubBoss2.GetMaxHealth());
			}
			else
			{
				((Component)_subBoss2Bar).gameObject.SetActive(false);
			}
			if (sb1Alive && sb2Alive)
			{
				_subBoss1Bar.sizeDelta = new Vector2(250f, 20f);
				_subBoss1Bar.anchoredPosition = new Vector2(-200f, num);
				_subBoss1Name.fontSize = 20;
				_subBoss2Bar.sizeDelta = new Vector2(250f, 20f);
				_subBoss2Bar.anchoredPosition = new Vector2(200f, num);
				_subBoss2Name.fontSize = 20;
			}
			else if (sb1Alive && !sb2Alive && !heartAlive)
			{
				_subBoss1Bar.sizeDelta = new Vector2(600f, 30f);
				_subBoss1Bar.anchoredPosition = new Vector2(0f, 0f);
				_subBoss1Name.fontSize = 24;
			}
			else if (!sb1Alive && sb2Alive && !heartAlive)
			{
				_subBoss2Bar.sizeDelta = new Vector2(600f, 30f);
				_subBoss2Bar.anchoredPosition = new Vector2(0f, 0f);
				_subBoss2Name.fontSize = 24;
			}
			else if (sb1Alive && !sb2Alive && heartAlive)
			{
				_subBoss1Bar.sizeDelta = new Vector2(250f, 20f);
				_subBoss1Bar.anchoredPosition = new Vector2(0f, num);
				_subBoss1Name.fontSize = 20;
			}
			else if (!sb1Alive && sb2Alive && heartAlive)
			{
				_subBoss2Bar.sizeDelta = new Vector2(250f, 20f);
				_subBoss2Bar.anchoredPosition = new Vector2(0f, num);
				_subBoss2Name.fontSize = 20;
			}
		}

		private void UpdateFill(Image fill, float current, float max)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01((max > 0f) ? (current / max) : 0f);
			((Component)fill).transform.localScale = new Vector3(num, 1f, 1f);
		}

		private string GetLocalizedBlightedName(string rawName)
		{
			if (string.IsNullOrEmpty(rawName))
			{
				return "Blighted Unknown";
			}
			if (rawName.StartsWith("Blighted"))
			{
				return rawName;
			}
			string text = Localization.instance.Localize(rawName);
			return "Blighted " + text;
		}

		private Color GetBiomeColor(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0005: 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_001d: Expected I4, but got Unknown
			//IL_00d5: 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: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				default:
					if ((int)biome != 8)
					{
						if ((int)biome != 16)
						{
							break;
						}
						return new Color(0.9f, 0.7f, 0.2f);
					}
					return new Color(0.5f, 0.1f, 0.8f);
				case 0:
					return new Color(0.2f, 0.8f, 0.2f);
				case 1:
					return new Color(0.4f, 0.3f, 0.1f);
				case 3:
					return new Color(0.8f, 0.9f, 1f);
				case 2:
					break;
				}
			}
			else
			{
				if ((int)biome == 32)
				{
					return new Color(1f, 0.2f, 0f);
				}
				if ((int)biome == 64)
				{
					return new Color(0.9f, 0.9f, 1f);
				}
				if ((int)biome == 512)
				{
					return new Color(0.3f, 0.1f, 0.5f);
				}
			}
			return Color.white;
		}
	}
	public class BlightedWorldHeartAI : MonoBehaviour, IDestructible
	{
		private static readonly int RPC_BlightedDamage = StringExtensionMethods.GetStableHashCode("RPC_BlightedHeartDamage");

		public float m_health;

		public float m_maxHealth = 2000f;

		private bool m_isDead;

		public Biome CurrentBiome;

		private float _lastWaveTime;

		private float _waveInterval = 30f;

		private bool _subBoss1Spawned;

		private bool _subBoss2Spawned;

		public Character m_subBoss1;

		public Character m_subBoss2;

		public ZNetView m_nview;

		private float _lastLogTime;

		private static readonly int ZDO_Health = StringExtensionMethods.GetStableHashCode("blighted_health");

		private static readonly int ZDO_MaxHealth = StringExtensionMethods.GetStableHashCode("blighted_max_health");

		private static readonly string ZDO_SubBoss1 = "blighted_subboss1";

		private static readonly string ZDO_SubBoss2 = "blighted_subboss2";

		private List<GameObject> m_spawnedEnemies = new List<GameObject>();

		private const int IndoorSolidHeightMargin = 4;

		public bool SubBoss1Active
		{
			get
			{
				if ((Object)(object)m_subBoss1 != (Object)null)
				{
					return !m_subBoss1.IsDead();
				}
				return false;
			}
		}

		public bool SubBoss2Active
		{
			get
			{
				if ((Object)(object)m_subBoss2 != (Object)null)
				{
					return !m_subBoss2.IsDead();
				}
				return false;
			}
		}

		public void Awake()
		{
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			m_nview = ((Component)this).GetComponent<ZNetView>();
			CharacterAnimEvent[] componentsInChildren = ((Component)this).GetComponentsInChildren<CharacterAnimEvent>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			CharacterDrop[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<CharacterDrop>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			BaseAI[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<BaseAI>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			FootStep[] componentsInChildren4 = ((Component)this).GetComponentsInChildren<FootStep>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
			}
			VisEquipment[] componentsInChildren5 = ((Component)this).GetComponentsInChildren<VisEquipment>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren5[i]);
			}
			Character[] componentsInChildren6 = ((Component)this).GetComponentsInChildren<Character>(true);
			foreach (Character val in componentsInChildren6)
			{
				Logger.LogInfo((object)("[BlightedHeart] Stripping Character: " + ((Object)((Component)val).gameObject).name));
				Object.DestroyImmediate((Object)(object)val);
			}
			ZSyncAnimation[] componentsInChildren7 = ((Component)this).GetComponentsInChildren<ZSyncAnimation>(true);
			for (int i = 0; i < componentsInChildren7.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren7[i]);
			}
			Animator[] componentsInChildren8 = ((Component)this).GetComponentsInChildren<Animator>(true);
			for (int i = 0; i < componentsInChildren8.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren8[i]);
			}
			Rigidbody[] componentsInChildren9 = ((Component)this).GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren9.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren9[i]);
			}
			Aoe[] componentsInChildren10 = ((Component)this).GetComponentsInChildren<Aoe>(true);
			foreach (Aoe val2 in componentsInChildren10)
			{
				Logger.LogInfo((object)("[BlightedHeart] Stripping Aoe: " + ((Object)((Component)val2).gameObject).name));
				Object.DestroyImmediate((Object)(object)val2);
			}
			MineRock5[] componentsInChildren11 = ((Component)this).GetComponentsInChildren<MineRock5>(true);
			for (int i = 0; i < componentsInChildren11.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren11[i]);
			}
			HitArea[] componentsInChildren12 = ((Component)this).GetComponentsInChildren<HitArea>(true);
			for (int i = 0; i < componentsInChildren12.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren12[i]);
			}
			Destructible[] componentsInChildren13 = ((Component)this).GetComponentsInChildren<Destructible>(true);
			for (int i = 0; i < componentsInChildren13.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren13[i]);
			}
			Collider[] componentsInChildren14 = ((Component)this).GetComponentsInChildren<Collider>(true);
			foreach (Collider val3 in componentsInChildren14)
			{
				if ((Object)(object)val3 != (Object)null && val3.isTrigger)
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
			}
			MonoBehaviour[] componentsInChildren15 = ((Component)this).GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val4 in componentsInChildren15)
			{
				if (!((Object)(object)val4 == (Object)null) && !(val4 is ZNetView) && !(val4 is BlightedWorldHeartAI) && !(val4 is BlightedDamageForwarder))
				{
					Object.DestroyImmediate((Object)(object)val4);
				}
			}
			if ((Object)(object)m_nview != (Object)null)
			{
				m_nview.Register<HitData>("RPC_BlightedHeartDamage", (Action<long, HitData>)RPC_HandleDamage);
			}
			m_health = m_maxHealth;
			if ((Object)(object)m_nview != (Object)null && m_nview.GetZDO() != null)
			{
				float num = m_nview.GetZDO().GetFloat(ZDO_Health, 0f);
				if (num > 0f)
				{
					m_health = num;
				}
				float num2 = m_nview.GetZDO().GetFloat(ZDO_MaxHealth, 0f);
				if (num2 > 0f)
				{
					m_maxHealth = num2;
				}
			}
			componentsInChildren14 = ((Component)this).GetComponentsInChildren<Collider>(true);
			foreach (Collider val5 in componentsInChildren14)
			{
				if ((Object)(object)val5 != (Object)null && (Object)(object)((Component)val5).gameObject != (Object)(object)((Component)this).gameObject)
				{
					BlightedDamageForwarder blightedDamageForwarder = ((Component)val5).gameObject.GetComponent<BlightedDamageForwarder>();
					if ((Object)(object)blightedDamageForwarder == (Object)null)
					{
						blightedDamageForwarder = ((Component)val5).gameObject.AddComponent<BlightedDamageForwarder>();
					}
					blightedDamageForwarder.m_heart = this;
				}
			}
			if ((Object)(object)((Component)this).gameObject.GetComponent<Collider>() == (Object)null)
			{
				BoxCollider obj = ((Component)this).gameObject.AddComponent<BoxCollider>();
				obj.size = new Vector3(10f, 10f, 10f);
				obj.center = Vector3.zero;
			}
			if ((Object)(object)BlightedUIManager.Instance != (Object)null)
			{
				BlightedUIManager.Instance.RegisterHeart(this);
			}
			Logger.LogInfo((object)"[BlightedHeart] Runtime cleanup complete. Custom IDestructible active.");
		}

		public DestructibleType GetDestructibleType()
		{
			return (DestructibleType)1;
		}

		public void Damage(HitData hit)
		{
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (m_isDead || (Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return;
			}
			if (hit != null)
			{
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker == (Object)null || (!attacker.IsPlayer() && !attacker.IsTamed()))
				{
					return;
				}
			}
			if (!m_nview.IsOwner())
			{
				m_nview.InvokeRPC("RPC_BlightedHeartDamage", new object[1] { hit });
				return;
			}
			float num = hit.m_damage.m_blunt + hit.m_damage.m_slash + hit.m_damage.m_pierce + hit.m_damage.m_chop + hit.m_damage.m_pickaxe;
			float num2 = hit.m_damage.m_fire + hit.m_damage.m_frost + hit.m_damage.m_lightning + hit.m_damage.m_poison + hit.m_damage.m_spirit + hit.m_damage.m_damage;
			float num3 = ((BlightedConfigManager.MagicDamageMultiplier != null) ? BlightedConfigManager.MagicDamageMultiplier.Value : 0.25f);
			float num4 = num + num2 * num3;
			if (!(num4 <= 0f))
			{
				m_health -= num4;
				m_nview.GetZDO().Set(ZDO_Health, m_health);
				if ((Object)(object)DamageText.instance != (Object)null)
				{
					DamageText.instance.ShowText((TextType)0, hit.m_point, num4, false);
				}
				if (BlightedConfigManager.DebugMode != null && BlightedConfigManager.DebugMode.Value)
				{
					Logger.LogInfo((object)$"[BlightedHeart] Took {num4:F1} damage. Health: {m_health:F0}/{m_maxHealth:F0}");
				}
				if (m_health <= 0f)
				{
					m_health = 0f;
					m_isDead = true;
					OnDeath();
				}
			}
		}

		private void RPC_HandleDamage(long sender, HitData hit)
		{
			Damage(hit);
		}

		private void OnDeath()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogInfo((object)"[BlightedHeart] The Blighted World Heart has been destroyed!");
			DropLoot();
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				Player.MessageAllInRange(((Component)this).transform.position, 200f, (MessageType)2, "The Blighted World Heart has been purified!", (Sprite)null);
			}
			if ((Object)(object)m_nview != (Object)null && m_nview.IsOwner())
			{
				m_nview.Destroy();
			}
		}

		private void DropLoot()
		{
			//IL_0006: 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_0055: 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)
			if (!BlightedConfigManager.BiomeConfigs.TryGetValue(CurrentBiome, out var _))
			{
				return;
			}
			int num = 1;
			List<Player> list = new List<Player>();
			Player.GetPlayersInRange(((Component)this).transform.position, 100f, list);
			if (list.Count > 0)
			{
				num = list.Count;
			}
			int num2 = 3 + (num - 1);
			if (num2 < 3)
			{
				num2 = 3;
			}
			List<string> value2;
			bool flag = BlightedItemsManager.BiomeWeaponDrops.TryGetValue(CurrentBiome, out value2) && value2.Count > 0;
			List<string> value3;
			bool flag2 = BlightedItemsManager.BiomeArmorDrops.TryGetValue(CurrentBiome, out value3) && value3.Count > 0;
			if (!flag && !flag2)
			{
				return;
			}
			for (int i = 0; i < num2; i++)
			{
				if ((Random.value > 0.5f && flag) || !flag2)
				{
					string prefabName = value2[Random.Range(0, value2.Count)];
					SpawnDrop(prefabName);
				}
				else if (flag2)
				{
					string prefabName2 = value3[Random.Range(0, value3.Count)];
					SpawnDrop(prefabName2);
				}
			}
		}

		private void SpawnDrop(string prefabName)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.GetPrefab(prefabName) : null);
			if ((Object)(object)val != (Object)null)
			{
				Vector3 val2 = ((Component)this).transform.position + Vector3.up * 1f + Random.insideUnitSphere * 0.5f;
				Object.Instantiate<GameObject>(val, val2, Quaternion.identity);
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)BlightedUIManager.Instance != (Object)null)
			{
				BlightedUIManager.Instance.UnregisterHeart(this);
			}
		}

		public void Initialize(Biome biome)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0064: 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)
			CurrentBiome = biome;
			if (BlightedConfigManager.BiomeConfigs.TryGetValue(biome, out var value))
			{
				float num = ((value.WaveTimerSeconds != null) ? value.WaveTimerSeconds.Value : _waveInterval);
				_lastWaveTime = Time.time - num + 1f;
			}
			else
			{
				_lastWaveTime = Time.time - _waveInterval + 1f;
			}
			if (BlightedConfigManager.BiomeConfigs.TryGetValue(biome, out var value2))
			{
				m_maxHealth = value2.BossHP.Value;
				m_health = m_maxHealth;
				if ((Object)(object)m_nview != (Object)null && m_nview.GetZDO() != null)
				{
					m_nview.GetZDO().Set(ZDO_Health, m_health);
					m_nview.GetZDO().Set(ZDO_MaxHealth, m_maxHealth);
				}
			}
			ApplyBiomeVisuals(biome);
		}

		private void ApplyBiomeVisuals(Biome biome)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
			Color biomeColor = GetBiomeColor(biome);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				if ((Object)(object)val.material != (Object)null)
				{
					val.material.SetColor("_Color", biomeColor);
					if (val.material.HasProperty("_EmissionColor"))
					{
						val.material.SetColor("_EmissionColor", biomeColor * 2f);
						val.material.EnableKeyword("_EMISSION");
					}
				}
			}
		}

		private Color GetBiomeColor(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0005: 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_001d: Expected I4, but got Unknown
			//IL_00d5: 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: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				default:
					if ((int)biome != 8)
					{
						if ((int)biome != 16)
						{
							break;
						}
						return new Color(0.9f, 0.7f, 0.2f);
					}
					return new Color(0.5f, 0.1f, 0.8f);
				case 0:
					return new Color(0.2f, 0.8f, 0.2f);
				case 1:
					return new Color(0.4f, 0.3f, 0.1f);
				case 3:
					return new Color(0.8f, 0.9f, 1f);
				case 2:
					break;
				}
			}
			else
			{
				if ((int)biome == 32)
				{
					return new Color(1f, 0.2f, 0f);
				}
				if ((int)biome == 64)
				{
					return new Color(0.9f, 0.9f, 1f);
				}
				if ((int)biome == 512)
				{
					return new Color(0.3f, 0.1f, 0.5f);
				}
			}
			return Color.white;
		}

		private void Update()
		{
			//IL_0097: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_nview == (Object)null || m_isDead)
			{
				return;
			}
			if (!m_nview.IsOwner())
			{
				if (m_nview.GetZDO() == null)
				{
					return;
				}
				m_health = m_nview.GetZDO().GetFloat(ZDO_Health, m_health);
				m_maxHealth = m_nview.GetZDO().GetFloat(ZDO_MaxHealth, m_maxHealth);
				if ((Object)(object)m_subBoss1 == (Object)null)
				{
					ZDOID zDOID = m_nview.GetZDO().GetZDOID(ZDO_SubBoss1);
					if (zDOID != ZDOID.None)
					{
						GameObject val = ZNetScene.instance.FindInstance(zDOID);
						if (Object.op_Implicit((Object)(object)val))
						{
							m_subBoss1 = val.GetComponent<Character>();
						}
					}
				}
				if (!((Object)(object)m_subBoss2 == (Object)null))
				{
					return;
				}
				ZDOID zDOID2 = m_nview.GetZDO().GetZDOID(ZDO_SubBoss2);
				if (zDOID2 != ZDOID.None)
				{
					GameObject val2 = ZNetScene.instance.FindInstance(zDOID2);
					if (Object.op_Implicit((Object)(object)val2))
					{
						m_subBoss2 = val2.GetComponent<Character>();
					}
				}
			}
			else
			{
				CheckSubBossThresholds();
				HandleWaveSpawning();
			}
		}

		private void HandleWaveSpawning()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (BlightedConfigManager.BiomeConfigs.TryGetValue(CurrentBiome, out var value))
			{
				float num = ((value.WaveTimerSeconds != null) ? value.WaveTimerSeconds.Value : _waveInterval);
				if (Time.time - _lastWaveTime > num)
				{
					_lastWaveTime = Time.time;
					SpawnWave();
				}
			}
		}

		private void SpawnWave()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			if (!BlightedConfigManager.BiomeConfigs.TryGetValue(CurrentBiome, out var value))
			{
				return;
			}
			int value2 = value.MaxEnemiesPerWave.Value;
			m_spawnedEnemies.RemoveAll((GameObject e) => (Object)(object)e == (Object)null || (Object)(object)e.GetComponent<Character>() == (Object)null || e.GetComponent<Character>().IsDead());
			int num = value2 - m_spawnedEnemies.Count;
			if (num <= 0)
			{
				return;
			}
			string[] waveEnemiesForBiome = GetWaveEnemiesForBiome(CurrentBiome);
			if (waveEnemiesForBiome.Length == 0)
			{
				return;
			}
			if (BlightedConfigManager.DebugMode.Value)
			{
				Logger.LogInfo((object)string.Format("Attempting to spawn {0} wave enemies (Current: {1}/{2}) of type {3} in {4}.", num, m_spawnedEnemies.Count, value2, string.Join(",", waveEnemiesForBiome), CurrentBiome));
			}
			int num2 = 0;
			for (int num3 = 0; num3 < num; num3++)
			{
				string text = waveEnemiesForBiome[Random.Range(0, waveEnemiesForBiome.Length)];
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if ((Object)(object)prefab != (Object)null)
				{
					Vector3 groundedSpawnPosition = GetGroundedSpawnPosition(10f);
					GameObject val = Object.Instantiate<GameObject>(prefab, groundedSpawnPosition, Quaternion.identity);
					m_spawnedEnemies.Add(val);
					num2++;
					CharacterDrop[] componentsInChildren = val.GetComponentsInChildren<CharacterDrop>(true);
					for (int num4 = 0; num4 < componentsInChildren.Length; num4++)
					{
						Object.Destroy((Object)(object)componentsInChildren[num4]);
					}
					BaseAI component = val.GetComponent<BaseAI>();
					if (!((Object)(object)component != (Object)null))
					{
						continue;
					}
					component.Alert();
					Player closestPlayer = Player.GetClosestPlayer(groundedSpawnPosition, 50f);
					if ((Object)(object)closestPlayer != (Object)null)
					{
						MonsterAI component2 = val.GetComponent<MonsterAI>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.SetTarget(((Component)closestPlayer).GetComponent<Character>());
						}
					}
				}
				else if (BlightedConfigManager.DebugMode.Value)
				{
					Logger.LogWarning((object)("Wave enemy prefab " + text + " not found in ZNetScene."));
				}
			}
			if (BlightedConfigManager.DebugMode.Value)
			{
				Logger.LogInfo((object)$"Successfully spawned {num2} wave enemies.");
			}
			if (num2 > 0 && BlightedConfigManager.EnableWaveAnnouncement.Value)
			{
				Player.MessageAllInRange(((Component)this).transform.position, 100f, BlightedConfigManager.WaveAnnouncementLocation.Value, "The Blighted World Heart cries out for the fallen...", (Sprite)null);
			}
		}

		private void CheckSubBossThresholds()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (BlightedConfigManager.BiomeConfigs.TryGetValue(CurrentBiome, out var value))
			{
				float num = m_health / m_maxHealth;
				if (BlightedConfigManager.DebugMode.Value && Time.time - _lastLogTime > 5f)
				{
					_lastLogTime = Time.time;
					Logger.LogInfo((object)$"Checking SubBoss thresholds. Current Health: {num:P0}. T1: {value.SubBossThreshold1.Value:P0}, T2: {value.SubBossThreshold2.Value:P0}. Spawned: {_subBoss1Spawned}, {_subBoss2Spawned}");
				}
				if (!_subBoss1Spawned && num <= value.SubBossThreshold1.Value)
				{
					_subBoss1Spawned = true;
					SpawnSubBoss(1, value.SubBoss1HP.Value);
				}
				if (!_subBoss2Spawned && num <= value.SubBossThreshold2.Value)
				{
					_subBoss2Spawned = true;
					SpawnSubBoss(2, value.SubBoss2HP.Value);
				}
			}
		}

		private Vector3 GetGroundedSpawnPosition(float radius)
		{
			//IL_0000: 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)
			//IL_000b: 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_0017: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = Random.insideUnitCircle * radius;
			Vector3 val2 = ((Component)this).transform.position + new Vector3(val.x, 0f, val.y);
			float y = default(float);
			if (ZoneSystem.instance.GetSolidHeight(val2, ref y, 4) || ZoneSystem.instance.GetSolidHeight(val2, ref y, 1000))
			{
				val2.y = y;
			}
			return val2;
		}

		private void SpawnSubBoss(int index, float maxHealth)
		{
			//IL_0002: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			string subBossForBiome = GetSubBossForBiome(CurrentBiome);
			if (BlightedConfigManager.DebugMode.Value)
			{
				Logger.LogInfo((object)$"Attempting to spawn subboss: {subBossForBiome} for biome {CurrentBiome}");
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(subBossForBiome);
			if (!((Object)(object)prefab != (Object)null))
			{
				return;
			}
			Vector3 groundedSpawnPosition = GetGroundedSpawnPosition(5f);
			GameObject val = Object.Instantiate<GameObject>(prefab, groundedSpawnPosition, Quaternion.identity);
			if (BlightedConfigManager.DebugMode.Value)
			{
				Logger.LogInfo((object)("Successfully spawned subboss " + subBossForBiome));
			}
			Transform transform = val.transform;
			transform.localScale *= 1.5f;
			CharacterDrop[] componentsInChildren = val.GetComponentsInChildren<CharacterDrop>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			Component[] componentsInChildren2 = val.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren2)
			{
				string name = ((object)val2).GetType().Name;
				if (name == "DropOnDestroy" || name == "SpawnOnDestroy")
				{
					Object.Destroy((Object)(object)val2);
				}
			}
			Character component = val.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetLevel(BlightedConfigManager.SubBossLevel.Value);
				component.SetMaxHealth(maxHealth);
				component.SetHealth(maxHealth);
			}
			val.AddComponent<BlightedSubBoss>();
			ZNetView component2 = val.GetComponent<ZNetView>();
			if ((Object)(object)component2 != (Object)null && component2.GetZDO() != null)
			{
				component2.GetZDO().Set("SoMStealthExempt", 1);
			}
			switch (index)
			{
			case 1:
				m_subBoss1 = component;
				if ((Object)(object)m_nview != (Object)null && m_nview.GetZDO() != null && (Object)(object)component != (Object)null)
				{
					ZNetView component4 = ((Component)component).GetComponent<ZNetView>();
					if ((Object)(object)component4 != (Object)null && component4.GetZDO() != null)
					{
						m_nview.GetZDO().Set(ZDO_SubBoss1, component4.GetZDO().m_uid);
					}
				}
				break;
			case 2:
				m_subBoss2 = component;
				if ((Object)(object)m_nview != (Object)null && m_nview.GetZDO() != null && (Object)(object)component != (Object)null)
				{
					ZNetView component3 = ((Component)component).GetComponent<ZNetView>();
					if ((Object)(object)component3 != (Object)null && component3.GetZDO() != null)
					{
						m_nview.GetZDO().Set(ZDO_SubBoss2, component3.GetZDO().m_uid);
					}
				}
				break;
			}
		}

		private string[] GetWaveEnemiesForBiome(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0005: 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_001d: Expected I4, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				default:
					if ((int)biome != 8)
					{
						if ((int)biome != 16)
						{
							break;
						}
						return new string[2] { "Goblin", "Deathsquito" };
					}
					return new string[3] { "Greydwarf", "Greydwarf_Elite", "Skeleton" };
				case 0:
					return new string[3] { "Boar", "Neck", "Greyling" };
				case 1:
					return new string[3] { "Draugr", "Blob", "Leech" };
				case 3:
					return new string[2] { "Wolf", "Hatchling" };
				case 2:
					break;
				}
			}
			else
			{
				if ((int)biome == 32)
				{
					return new string[2] { "Charred_Melee", "Charred_Archer" };
				}
				if ((int)biome == 64)
				{
					return new string[3] { "Greydwarf_Frozen", "Skeleton_DeepNorth", "Elaking" };
				}
				if ((int)biome == 512)
				{
					return new string[2] { "Seeker", "SeekerBrood" };
				}
			}
			return new string[1] { "Boar" };
		}

		private string GetSubBossForBiome(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0005: 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_001d: Expected I4, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_00