Decompiled source of AshlandsDvergrBuff v2.0.2

AshlandsDvergrMod.dll

Decompiled 8 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AshlandsDvergrMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+bd39431325514f5d050d94df7deabe501d858f87")]
[assembly: AssemblyProduct("AshlandsDvergrMod")]
[assembly: AssemblyTitle("AshlandsDvergrMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 AshlandsDvergrMod
{
	[BepInPlugin("com.valheim.ashlandsdvergrmod", "Ashlands Dvergr Boost", "2.0.0")]
	public class AshlandsDvergrPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.valheim.ashlandsdvergrmod";

		public const string PluginName = "Ashlands Dvergr Boost";

		public const string PluginVersion = "2.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<float> SpawnRateMultiplier;

		internal static ConfigEntry<float> CampRespawnIntervalMinutes;

		internal static ConfigEntry<float> VarietyDvergrSpawnChance;

		internal static ConfigEntry<bool> EnableAmbientAshlandsSpawns;

		internal static ConfigEntry<int> AmbientMaxSpawned;

		internal static ConfigEntry<float> AmbientSpawnInterval;

		internal static ConfigEntry<float> AmbientSpawnChance;

		internal static ConfigEntry<int> AmbientGroupMin;

		internal static ConfigEntry<int> AmbientGroupMax;

		internal static ConfigEntry<float> AmbientSpawnRadiusMin;

		internal static ConfigEntry<float> AmbientSpawnRadiusMax;

		internal static ConfigEntry<float> HealthMultiplier;

		internal static ConfigEntry<float> DamageMultiplier;

		internal static ConfigEntry<float> MageHealthMultiplier;

		internal static ConfigEntry<float> MageDamageMultiplier;

		internal static ConfigEntry<bool> UseAshlandsBloodWeapons;

		internal static ConfigEntry<float> PassiveHealPercentPerTick;

		internal static ConfigEntry<float> PassiveHealIntervalSeconds;

		internal static ConfigEntry<int> MinLevel;

		internal static ConfigEntry<int> MaxLevel;

		internal static ConfigEntry<float> LevelUpChance;

		internal static ConfigEntry<float> VisualScale1Star;

		internal static ConfigEntry<float> VisualScale2Star;

		internal static ConfigEntry<bool> EnableCoolVisuals;

		internal static ConfigEntry<bool> Enable2StarBossEffects;

		internal static ConfigEntry<float> AuraLightIntensity;

		internal static readonly string[] VarietyDvergrPrefabNames = new string[3] { "DvergerMageFire", "DvergerMageIce", "DvergerMageSupport" };

		private static readonly HashSet<int> PatchedSpawnLists = new HashSet<int>();

		private static readonly HashSet<int> PatchedCreatureSpawners = new HashSet<int>();

		private static readonly HashSet<int> PatchedSpawnAreas = new HashSet<int>();

		private static readonly Dictionary<int, float> OriginalPrefabHealth = new Dictionary<int, float>();

		private static readonly Dictionary<string, GameObject> CachedSoftRefPrefabs = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);

		private static FileSystemWatcher _configFileWatcher;

		private static DateTime _lastConfigReloadTime = DateTime.MinValue;

		private void Awake()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Expected O, but got Unknown
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Expected O, but got Unknown
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Expected O, but got Unknown
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Expected O, but got Unknown
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Expected O, but got Unknown
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Expected O, but got Unknown
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Expected O, but got Unknown
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Expected O, but got Unknown
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Expected O, but got Unknown
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Expected O, but got Unknown
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Expected O, but got Unknown
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_057a: Expected O, but got Unknown
			//IL_05c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Expected O, but got Unknown
			//IL_0610: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Expected O, but got Unknown
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Expected O, but got Unknown
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ba: Expected O, but got Unknown
			//IL_0706: Unknown result type (might be due to invalid IL or missing references)
			//IL_0710: Expected O, but got Unknown
			//IL_075c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0766: Expected O, but got Unknown
			//IL_07a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07aa: Expected O, but got Unknown
			//IL_07e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ee: Expected O, but got Unknown
			//IL_083a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0844: Expected O, but got Unknown
			//IL_08d2: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			int num = 100;
			SpawnRateMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("1. Spawning", "SpawnRateMultiplier", 3f, new ConfigDescription("Global multiplier for Ashlands Dvergr spawn rate, spawn chance, group sizes, and spawner weights.\nDefault: 3.0 (3x faster spawns, 3x capacity).\nRange: 0.5 to 10.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			CampRespawnIntervalMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("1. Spawning", "CampRespawnIntervalMinutes", 6.7f, new ConfigDescription("Base respawn interval in minutes for Ashlands Dvergr ruin/camp spawners (divided by SpawnRateMultiplier).\nDefault: 6.7 minutes.\nRange: 0.5 to 60.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			VarietyDvergrSpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("1. Spawning", "VarietyDvergrSpawnChance", 30f, new ConfigDescription("Percentage chance (0-100) for Ashlands Dvergr spawns to be a variety type (Fire Mage, Ice Mage, or Support Mage) instead of standard DvergerAshlands.\nDefault: 30% (giving a 70% / 10% / 10% / 10% split among Crossbow / Fire / Ice / Support).\nRange: 0.0 to 100.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			EnableAmbientAshlandsSpawns = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Ambient Spawns", "EnableAmbientAshlandsSpawns", true, new ConfigDescription("Add ambient Dvergr patrol spawns throughout the Ashlands biome in addition to camp/ruin spawners.\nSpawns are server/zone-owner authoritative outside lava.\nDefault: true", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AmbientMaxSpawned = ((BaseUnityPlugin)this).Config.Bind<int>("2. Ambient Spawns", "AmbientMaxSpawned", 6, new ConfigDescription("Maximum active ambient Dvergrs allowed per Ashlands sector.\nDefault: 6.\nRange: 1 to 30", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AmbientSpawnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("2. Ambient Spawns", "AmbientSpawnInterval", 100f, new ConfigDescription("Base seconds between ambient spawn checks (divided by SpawnRateMultiplier).\nDefault: 100 seconds.\nRange: 10.0 to 600.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 600f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AmbientSpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("2. Ambient Spawns", "AmbientSpawnChance", 50f, new ConfigDescription("Percentage chance (0-100) to spawn ambient Dvergrs each interval check.\nDefault: 50%.\nRange: 1.0 to 100.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AmbientGroupMin = ((BaseUnityPlugin)this).Config.Bind<int>("2. Ambient Spawns", "AmbientGroupMin", 2, new ConfigDescription("Minimum group size for ambient Ashlands Dvergr patrols.\nDefault: 2.\nRange: 1 to 10", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AmbientGroupMax = ((BaseUnityPlugin)this).Config.Bind<int>("2. Ambient Spawns", "AmbientGroupMax", 4, new ConfigDescription("Maximum group size for ambient Ashlands Dvergr patrols.\nDefault: 4.\nRange: 1 to 15", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 15), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AmbientSpawnRadiusMin = ((BaseUnityPlugin)this).Config.Bind<float>("2. Ambient Spawns", "AmbientSpawnRadiusMin", 40f, new ConfigDescription("Minimum distance in meters from players to spawn ambient Dvergrs.\nDefault: 40 meters.\nRange: 10.0 to 100.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 100f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AmbientSpawnRadiusMax = ((BaseUnityPlugin)this).Config.Bind<float>("2. Ambient Spawns", "AmbientSpawnRadiusMax", 80f, new ConfigDescription("Maximum distance in meters from players to spawn ambient Dvergrs.\nDefault: 80 meters.\nRange: 40.0 to 200.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(40f, 200f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			HealthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("3. Combat Stats", "HealthMultiplier", 1.2f, new ConfigDescription("Base health multiplier for Dvergrs in the Ashlands (default: 1.20 = +20% base HP: 600 -> 720).\nStar levels add +25% HP per star (0-star: 720 HP, 1-star: 900 HP, 2-star: 1080 HP).\nRange: 0.5 to 3.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			DamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("3. Combat Stats", "DamageMultiplier", 1.25f, new ConfigDescription("Outgoing damage multiplier for Ashlands Dvergrs when UseAshlandsBloodWeapons is false (melee strikes, arbalest bolts, and magic AOEs).\nDefault: 1.25 (+25% base damage, +25% at 1-star; 2-star skips default star damage scaling due to weapon buff).\nRange: 0.5 to 3.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			MageHealthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("3. Combat Stats", "MageHealthMultiplier", 1.08f, new ConfigDescription("Separate base health multiplier for Dvergr Mages in the Ashlands (Fire, Ice, Support).\nSet lower than warriors/crossbowmen by default to balance glass-cannon magic power (default: 1.08 = +8% base HP: 450 -> 486).\nRange: 0.5 to 3.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			MageDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("3. Combat Stats", "MageDamageMultiplier", 1.1f, new ConfigDescription("Separate outgoing damage multiplier for Dvergr Mages in the Ashlands.\nSets lower spell/AOE scaling by default (default: 1.10 = +10% base damage, or baseline staff ratio modifier).\nRange: 0.5 to 3.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			UseAshlandsBloodWeapons = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Combat Stats", "UseAshlandsBloodWeapons", true, new ConfigDescription("Equip 2-star Ashlands Dvergrs with their equivalent Ashlands Blood Weapon / upgraded magic staff (Wound Ripper for crossbowmen, Staff of Fracturing / Dundr / fully upgraded Staff of Frost for mages) with Bloodstone missing-HP damage scaling (0 and 1-star Dvergrs wield default weapons).\nDefault: true", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			PassiveHealPercentPerTick = ((BaseUnityPlugin)this).Config.Bind<float>("3. Combat Stats", "PassiveHealPercentPerTick", 1f, new ConfigDescription("Percentage of max health regenerated per heal tick by Ashlands Dvergrs (0 = disabled).\nDefault: 1.0% every 5 seconds (~8 HP/tick at 0-star, ~15 HP/tick at 2-star).\nRange: 0.0 to 10.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			PassiveHealIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("3. Combat Stats", "PassiveHealIntervalSeconds", 5f, new ConfigDescription("Seconds between passive regeneration ticks for Ashlands Dvergrs.\nDefault: 5.0 seconds.\nRange: 1.0 to 60.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			MinLevel = ((BaseUnityPlugin)this).Config.Bind<int>("4. Stars & Levels", "MinLevel", 1, new ConfigDescription("Minimum level for Ashlands Dvergrs (1 = 0 stars, 2 = 1 star, 3 = 2 stars).\nDefault: 1 (0 stars).\nRange: 1 to 3", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			MaxLevel = ((BaseUnityPlugin)this).Config.Bind<int>("4. Stars & Levels", "MaxLevel", 3, new ConfigDescription("Maximum level for Ashlands Dvergrs (1 = 0 stars, 2 = 1 star, 3 = 2 stars).\nDefault: 3 (2 stars).\nRange: 1 to 3", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			LevelUpChance = ((BaseUnityPlugin)this).Config.Bind<float>("4. Stars & Levels", "LevelUpChance", 50f, new ConfigDescription("Percentage chance (0-100) per star roll to upgrade to next rank.\nDefault: 50%.\nRange: 0.0 to 100.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			VisualScale1Star = ((BaseUnityPlugin)this).Config.Bind<float>("4. Stars & Levels", "VisualScale1Star", 1.05f, new ConfigDescription("Visual body scale multiplier for 1-star Ashlands Dvergrs.\nDefault: 1.05 (5% larger).\nRange: 1.0 to 1.5", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1.5f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			VisualScale2Star = ((BaseUnityPlugin)this).Config.Bind<float>("4. Stars & Levels", "VisualScale2Star", 1.1f, new ConfigDescription("Visual body scale multiplier for 2-star Ashlands Dvergrs.\nDefault: 1.10 (10% larger).\nRange: 1.0 to 2.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			EnableCoolVisuals = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Stars & Levels", "EnableCoolVisuals", true, new ConfigDescription("Enhances starred Ashlands Dvergrs with subtle veteran armor shading and a soft warm rim light while preserving their original textures.\nDefault: true", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			Enable2StarBossEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Stars & Levels", "Enable2StarBossEffects", true, new ConfigDescription("Adds boss visual effects (glowing boss aura, hand & chest boss energy particles, and arcane boss runes) to 2-star Ashlands Dvergrs.\nDefault: true", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			AuraLightIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("4. Stars & Levels", "AuraLightIntensity", 0.6f, new ConfigDescription("Intensity multiplier for the subtle warm rim light on Ashlands Dvergrs (0 = disable light).\nDefault: 0.6.\nRange: 0.0 to 3.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
			((BaseUnityPlugin)this).Config.ConfigReloaded += OnConfigReloaded;
			SetupConfigFileWatcher();
			if (Environment.GetEnvironmentVariable("RENDER_DVERGR_VALIDATION") == "1")
			{
				Runtime.MakeAllAssetsLoadable();
				((MonoBehaviour)this).StartCoroutine(RenderDvergrValidationCoroutine());
			}
			new Harmony("com.valheim.ashlandsdvergrmod").PatchAll(typeof(AshlandsDvergrPlugin));
			Log.LogInfo((object)"Ashlands Dvergr Boost 2.0.0 loaded.");
		}

		private void SetupConfigFileWatcher()
		{
			try
			{
				string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
				string directoryName = Path.GetDirectoryName(configFilePath);
				string fileName = Path.GetFileName(configFilePath);
				if (!string.IsNullOrEmpty(directoryName) && !string.IsNullOrEmpty(fileName))
				{
					_configFileWatcher = new FileSystemWatcher(directoryName, fileName)
					{
						NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite),
						IncludeSubdirectories = false,
						EnableRaisingEvents = true
					};
					_configFileWatcher.Changed += OnConfigFileDiskChanged;
					_configFileWatcher.Created += OnConfigFileDiskChanged;
					_configFileWatcher.Renamed += OnConfigFileDiskChanged;
					Log.LogInfo((object)("Watching text config file for edits: " + configFilePath));
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not set up text config file watcher: " + ex.Message));
			}
		}

		private static void OnConfigFileDiskChanged(object sender, FileSystemEventArgs e)
		{
			if ((DateTime.Now - _lastConfigReloadTime).TotalMilliseconds < 1000.0)
			{
				return;
			}
			_lastConfigReloadTime = DateTime.Now;
			try
			{
				Log.LogInfo((object)"Text config file modified on disk. Reloading settings...");
				((BaseUnityPlugin)(AshlandsDvergrPlugin)(object)Chainloader.PluginInfos["com.valheim.ashlandsdvergrmod"].Instance).Config.Reload();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to reload text config file: " + ex.Message));
			}
		}

		private static void OnConfigReloaded(object sender, EventArgs e)
		{
			RefreshPrefabStats();
		}

		private static void OnSettingChanged(object sender, SettingChangedEventArgs e)
		{
			RefreshPrefabStats();
		}

		private static void RefreshPrefabStats()
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			string[] array = new string[5] { "DvergerAshlands", "DvergerMageFire", "DvergerMageIce", "DvergerMageSupport", "Dverger" };
			foreach (string text in array)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if ((Object)(object)prefab != (Object)null)
				{
					Character component = prefab.GetComponent<Character>();
					if ((Object)(object)component != (Object)null && OriginalPrefabHealth.TryGetValue(((Object)prefab).GetInstanceID(), out var value))
					{
						float healthMultiplierFor = GetHealthMultiplierFor(component);
						component.m_health = value * healthMultiplierFor;
						EnsureVisualStarSetups(component);
						Log.LogInfo((object)$"Refreshed {text} prefab base health to {component.m_health} (mult={healthMultiplierFor}).");
					}
				}
			}
			AshlandsDvergrEnhancer[] array2 = Object.FindObjectsByType<AshlandsDvergrEnhancer>((FindObjectsSortMode)0);
			foreach (AshlandsDvergrEnhancer ashlandsDvergrEnhancer in array2)
			{
				if ((Object)(object)ashlandsDvergrEnhancer != (Object)null)
				{
					ashlandsDvergrEnhancer.ApplyCoolVisuals();
				}
			}
		}

		internal static bool IsDvergrPrefab(GameObject go)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			if ((Object)(object)go == (Object)null)
			{
				return false;
			}
			Character component = go.GetComponent<Character>();
			if ((Object)(object)component != (Object)null && (int)component.m_faction == 10)
			{
				return true;
			}
			string name = ((Object)go).name;
			if (name.IndexOf("Dverger", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return name.IndexOf("Dvergr", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		internal static bool IsInAshlands(Vector3 pos)
		{
			//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_0021: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			if (WorldGenerator.IsAshlands(pos.x, pos.z))
			{
				return true;
			}
			if (WorldGenerator.instance != null && (WorldGenerator.instance.GetBiome(pos) & 0x20) != 0)
			{
				return true;
			}
			return false;
		}

		internal static bool IsAshlandsDvergr(Character ch)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ch == (Object)null || ch.IsPlayer())
			{
				return false;
			}
			if ((int)ch.m_faction != 10 && ((Object)((Component)ch).gameObject).name.IndexOf("Dverger", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)((Component)ch).gameObject).name.IndexOf("Dvergr", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return false;
			}
			if (((Object)((Component)ch).gameObject).name.IndexOf("Ashlands", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			return IsInAshlands(((Component)ch).transform.position);
		}

		internal static bool IsDvergrMage(Character ch)
		{
			if ((Object)(object)ch == (Object)null)
			{
				return false;
			}
			return IsDvergrMageName(((Object)((Component)ch).gameObject).name);
		}

		internal static bool IsDvergrMageName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			return name.IndexOf("Mage", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		internal static float GetHealthMultiplierFor(Character ch)
		{
			if (!IsDvergrMage(ch))
			{
				return Mathf.Max(0.1f, HealthMultiplier.Value);
			}
			return Mathf.Max(0.1f, MageHealthMultiplier.Value);
		}

		internal static float GetDamageMultiplierFor(Character ch)
		{
			if (!IsDvergrMage(ch))
			{
				return Mathf.Max(0.1f, DamageMultiplier.Value);
			}
			return Mathf.Max(0.1f, MageDamageMultiplier.Value);
		}

		internal static int RollConfiguredLevel()
		{
			int num = Mathf.Max(1, MinLevel.Value);
			int num2 = Mathf.Max(num, MaxLevel.Value);
			float num3 = Mathf.Clamp(LevelUpChance.Value, 0f, 100f);
			int i;
			for (i = num; i < num2; i++)
			{
				if (!(Random.Range(0f, 100f) <= num3))
				{
					break;
				}
			}
			return i;
		}

		internal static void EnsureVisualStarSetups(Character ch)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_012c: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			LevelEffects componentInChildren = ((Component)ch).GetComponentInChildren<LevelEffects>();
			if (!((Object)(object)componentInChildren == (Object)null) && componentInChildren.m_levelSetups != null)
			{
				if ((Object)(object)componentInChildren.m_mainRender == (Object)null)
				{
					componentInChildren.m_mainRender = (Renderer)(object)((Component)ch).GetComponentInChildren<SkinnedMeshRenderer>();
				}
				float num = Mathf.Max(1f, VisualScale1Star.Value);
				float scale = Mathf.Max(num, VisualScale2Star.Value);
				_ = EnableCoolVisuals.Value;
				if (componentInChildren.m_levelSetups.Count == 0)
				{
					componentInChildren.m_levelSetups.Add(new LevelSetup
					{
						m_scale = num,
						m_hue = 0f,
						m_saturation = 0f,
						m_value = 0f,
						m_setEmissiveColor = false
					});
				}
				else
				{
					componentInChildren.m_levelSetups[0].m_scale = num;
					componentInChildren.m_levelSetups[0].m_hue = 0f;
					componentInChildren.m_levelSetups[0].m_saturation = 0f;
					componentInChildren.m_levelSetups[0].m_value = 0f;
					componentInChildren.m_levelSetups[0].m_setEmissiveColor = false;
				}
				if (componentInChildren.m_levelSetups.Count == 1)
				{
					componentInChildren.m_levelSetups.Add(new LevelSetup
					{
						m_scale = scale,
						m_hue = 0f,
						m_saturation = 0f,
						m_value = 0f,
						m_setEmissiveColor = false
					});
				}
				else if (componentInChildren.m_levelSetups.Count >= 2)
				{
					componentInChildren.m_levelSetups[1].m_scale = scale;
					componentInChildren.m_levelSetups[1].m_hue = 0f;
					componentInChildren.m_levelSetups[1].m_saturation = 0f;
					componentInChildren.m_levelSetups[1].m_value = 0f;
					componentInChildren.m_levelSetups[1].m_setEmissiveColor = false;
				}
			}
		}

		internal static string GetEquivalentBloodWeaponPrefabName(string characterName)
		{
			if (string.IsNullOrEmpty(characterName))
			{
				return "CrossbowRipperBlood";
			}
			if (characterName.IndexOf("MageFire", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "StaffClusterbomb";
			}
			if (characterName.IndexOf("MageIce", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "StaffLightning";
			}
			if (characterName.IndexOf("MageSupport", StringComparison.OrdinalIgnoreCase) >= 0 || characterName.IndexOf("Mage", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "StaffIceShards";
			}
			if (string.Equals(characterName, "Dverger", StringComparison.OrdinalIgnoreCase) || (characterName.IndexOf("Dverger", StringComparison.OrdinalIgnoreCase) >= 0 && characterName.IndexOf("Ashlands", StringComparison.OrdinalIgnoreCase) < 0 && characterName.IndexOf("Mage", StringComparison.OrdinalIgnoreCase) < 0))
			{
				return "BattleaxeSkullSplittur";
			}
			return "CrossbowRipperBlood";
		}

		internal static GameObject ResolvePrefabByNameOrAssetId(string prefabName, string assetIdHex = null)
		{
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(prefabName))
			{
				return null;
			}
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
				if ((Object)(object)itemPrefab != (Object)null)
				{
					return itemPrefab;
				}
			}
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
				if ((Object)(object)prefab != (Object)null)
				{
					return prefab;
				}
			}
			if (CachedSoftRefPrefabs.TryGetValue(prefabName, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			if (string.IsNullOrEmpty(assetIdHex))
			{
				assetIdHex = prefabName switch
				{
					"DvergerAshlands" => "2ece1cf15f2885a4da6da84af9d5c542", 
					"DvergerMageFire" => "1ed38d388ceda5f4e89f5be4d1768fab", 
					"DvergerMageIce" => "8ad104a536dd94d4bb764f8a9f3d8ee7", 
					"DvergerMageSupport" => "c0e85e3d180619047bdf97cd98271a4d", 
					"Dverger" => "b780f1078c33d2344836ccefd3bf9352", 
					"CrossbowRipperBlood" => "483a950c53776e74ea40aef310fefbb2", 
					"StaffClusterbomb" => "d4812897e4412e540b7fa649d25b99d5", 
					"StaffLightning" => "90f15fa074aa08a478750566117d84d0", 
					"StaffRedTroll" => "87eebe8749379744eacfa37ea818aeab", 
					"StaffIceShards" => "d268d47613aec2963b1878ed2a224e1e", 
					"BattleaxeSkullSplittur" => "131b6e64eaee51547a0b76f472190581", 
					"fx_fader_chestfire" => "affcfc1b631dafe4ba5eb9388ec6196a", 
					"fx_goblinking_nova_hand" => "ebf058290cad64993843155e16b4b6f6", 
					"fx_DvergerMage_Nova_ring" => "c1b9194e4cba6e648aacfd970dd12da9", 
					"vfx_crossbow_blood_fire" => "50280cda7c9d5f64b96020f59ae3f945", 
					_ => null, 
				};
			}
			AssetID val = default(AssetID);
			if (!string.IsNullOrEmpty(assetIdHex) && AssetID.TryParse(assetIdHex, ref val))
			{
				try
				{
					SoftReference<GameObject> val2 = default(SoftReference<GameObject>);
					val2..ctor(val);
					val2.Load();
					if ((Object)(object)val2.Asset != (Object)null)
					{
						CachedSoftRefPrefabs[prefabName] = val2.Asset;
						return val2.Asset;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		[HarmonyPostfix]
		private static void ZNetScene_Awake_Postfix(ZNetScene __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			string[] array = new string[5] { "DvergerAshlands", "DvergerMageFire", "DvergerMageIce", "DvergerMageSupport", "Dverger" };
			foreach (string text in array)
			{
				GameObject prefab = __instance.GetPrefab(text);
				if (!((Object)(object)prefab != (Object)null))
				{
					continue;
				}
				Character component = prefab.GetComponent<Character>();
				if ((Object)(object)component != (Object)null)
				{
					int instanceID = ((Object)prefab).GetInstanceID();
					if (!OriginalPrefabHealth.TryGetValue(instanceID, out var value))
					{
						value = component.m_health;
						OriginalPrefabHealth[instanceID] = value;
					}
					float healthMultiplierFor = GetHealthMultiplierFor(component);
					component.m_health = value * healthMultiplierFor;
					EnsureVisualStarSetups(component);
					Log.LogInfo((object)$"Configured {text} prefab base health: {value} -> {component.m_health} (mult={healthMultiplierFor})");
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Awake")]
		[HarmonyPrefix]
		private static void Character_Awake_Prefix(Character __instance)
		{
			if (IsAshlandsDvergr(__instance))
			{
				EnsureVisualStarSetups(__instance);
				if (((Object)((Component)__instance).gameObject).name.IndexOf("Ashlands", StringComparison.OrdinalIgnoreCase) < 0)
				{
					float num = (IsDvergrMage(__instance) ? 450f : 600f);
					float healthMultiplierFor = GetHealthMultiplierFor(__instance);
					float num2 = Mathf.Max(__instance.m_health, num);
					__instance.m_health = num2 * healthMultiplierFor;
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Awake")]
		[HarmonyPostfix]
		private static void Character_Awake_Postfix(Character __instance, ZNetView ___m_nview)
		{
			if (!IsAshlandsDvergr(__instance))
			{
				return;
			}
			if ((Object)(object)((Component)__instance).GetComponent<AshlandsDvergrEnhancer>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<AshlandsDvergrEnhancer>();
			}
			if ((Object)(object)___m_nview == (Object)null || !___m_nview.IsValid() || !___m_nview.IsOwner())
			{
				return;
			}
			ZDO zDO = ___m_nview.GetZDO();
			if (zDO != null && !zDO.GetBool("AshlandsDvergrMod_Initialized", false))
			{
				zDO.Set("AshlandsDvergrMod_Initialized", true);
				int num = RollConfiguredLevel();
				if (num > __instance.GetLevel())
				{
					__instance.SetLevel(num);
				}
				float num2 = CalculateScaledMaxHealth(__instance);
				__instance.SetMaxHealth(num2);
				__instance.SetHealth(num2);
			}
		}

		private static float CalculateScaledMaxHealth(Character ch)
		{
			int num = Mathf.Max(0, ch.GetLevel() - 1);
			float num2 = 1f + (float)num * 0.25f;
			return ch.GetMaxHealthBase() * num2;
		}

		[HarmonyPatch(typeof(Character), "SetLevel")]
		[HarmonyPostfix]
		private static void Character_SetLevel_Postfix(Character __instance)
		{
			if (IsAshlandsDvergr(__instance))
			{
				if (__instance.IsOwner())
				{
					float num = CalculateScaledMaxHealth(__instance);
					__instance.SetMaxHealth(num);
					__instance.SetHealth(num);
				}
				AshlandsDvergrEnhancer component = ((Component)__instance).GetComponent<AshlandsDvergrEnhancer>();
				if ((Object)(object)component != (Object)null)
				{
					component.ApplyCoolVisuals();
				}
			}
		}

		[HarmonyPatch(typeof(CreatureSpawner), "Awake")]
		[HarmonyPrefix]
		private static void CreatureSpawner_Awake_Prefix(CreatureSpawner __instance)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_creaturePrefab == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			if (!PatchedCreatureSpawners.Contains(instanceID) && (((Object)((Component)__instance).gameObject).name.IndexOf("DvergerAshlands", StringComparison.OrdinalIgnoreCase) >= 0 || (IsDvergrPrefab(__instance.m_creaturePrefab) && (((Object)__instance.m_creaturePrefab).name.IndexOf("Ashlands", StringComparison.OrdinalIgnoreCase) >= 0 || IsInAshlands(((Component)__instance).transform.position)))))
			{
				PatchedCreatureSpawners.Add(instanceID);
				float num = Mathf.Max(0.1f, SpawnRateMultiplier.Value);
				__instance.m_minLevel = Mathf.Max(__instance.m_minLevel, MinLevel.Value);
				__instance.m_maxLevel = Mathf.Max(__instance.m_maxLevel, MaxLevel.Value);
				__instance.m_levelupChance = Mathf.Max(__instance.m_levelupChance, LevelUpChance.Value);
				float num2 = Mathf.Max(0.5f, CampRespawnIntervalMinutes.Value);
				__instance.m_respawnTimeMinuts = Mathf.Max(0.2f, num2 / num);
				__instance.m_spawnInterval = Mathf.Max(1, Mathf.RoundToInt((float)__instance.m_spawnInterval / num));
				if (__instance.m_maxGroupSpawned > 0)
				{
					__instance.m_maxGroupSpawned = Mathf.CeilToInt((float)__instance.m_maxGroupSpawned * num);
				}
				__instance.m_spawnerWeight *= num;
			}
		}

		[HarmonyPatch(typeof(CreatureSpawner), "Spawn")]
		[HarmonyPrefix]
		private static void CreatureSpawner_Spawn_Prefix(CreatureSpawner __instance, Location ___m_location, out GameObject __state)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			__state = null;
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_creaturePrefab == (Object)null || !IsDvergrPrefab(__instance.m_creaturePrefab) || (((Object)__instance.m_creaturePrefab).name.IndexOf("Ashlands", StringComparison.OrdinalIgnoreCase) < 0 && !IsInAshlands(((Component)__instance).transform.position)))
			{
				return;
			}
			if ((Object)(object)___m_location != (Object)null)
			{
				if (___m_location.m_enemyMinLevelOverride >= 0)
				{
					___m_location.m_enemyMinLevelOverride = Mathf.Max(___m_location.m_enemyMinLevelOverride, MinLevel.Value);
				}
				if (___m_location.m_enemyMaxLevelOverride >= 0)
				{
					___m_location.m_enemyMaxLevelOverride = Mathf.Max(___m_location.m_enemyMaxLevelOverride, MaxLevel.Value);
				}
				if (___m_location.m_enemyLevelUpOverride >= 0f)
				{
					___m_location.m_enemyLevelUpOverride = Mathf.Max(___m_location.m_enemyLevelUpOverride, LevelUpChance.Value);
				}
			}
			float num = Mathf.Clamp(VarietyDvergrSpawnChance.Value, 0f, 100f);
			if (num > 0f && (Object)(object)ZNetScene.instance != (Object)null && Random.Range(0f, 100f) < num)
			{
				string text = VarietyDvergrPrefabNames[Random.Range(0, VarietyDvergrPrefabNames.Length)];
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if ((Object)(object)prefab != (Object)null)
				{
					__state = __instance.m_creaturePrefab;
					__instance.m_creaturePrefab = prefab;
				}
			}
		}

		[HarmonyPatch(typeof(CreatureSpawner), "Spawn")]
		[HarmonyPostfix]
		private static void CreatureSpawner_Spawn_Postfix(CreatureSpawner __instance, GameObject __state)
		{
			if ((Object)(object)__instance != (Object)null && (Object)(object)__state != (Object)null)
			{
				__instance.m_creaturePrefab = __state;
			}
		}

		[HarmonyPatch(typeof(RandomSpawn), "Randomize")]
		[HarmonyPrefix]
		private static void RandomSpawn_Randomize_Prefix(RandomSpawn __instance, Vector3 pos)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			bool flag = ((Object)((Component)__instance).gameObject).name.IndexOf("Dverg", StringComparison.OrdinalIgnoreCase) >= 0;
			if (!flag)
			{
				CreatureSpawner componentInChildren = ((Component)__instance).GetComponentInChildren<CreatureSpawner>(true);
				if ((Object)(object)componentInChildren != (Object)null && IsDvergrPrefab(componentInChildren.m_creaturePrefab))
				{
					flag = true;
				}
			}
			if (flag && IsInAshlands(pos))
			{
				__instance.m_chanceToSpawn = Mathf.Min(100f, __instance.m_chanceToSpawn * Mathf.Max(1f, SpawnRateMultiplier.Value));
			}
		}

		[HarmonyPatch(typeof(SpawnArea), "Awake")]
		[HarmonyPostfix]
		private static void SpawnArea_Awake_Postfix(SpawnArea __instance)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null || __instance.m_prefabs == null)
			{
				return;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			if (PatchedSpawnAreas.Contains(instanceID))
			{
				return;
			}
			bool flag = false;
			float num = 1f;
			foreach (SpawnData prefab2 in __instance.m_prefabs)
			{
				if (prefab2 != null && IsDvergrPrefab(prefab2.m_prefab) && (((Object)prefab2.m_prefab).name.IndexOf("Ashlands", StringComparison.OrdinalIgnoreCase) >= 0 || IsInAshlands(((Component)__instance).transform.position)))
				{
					flag = true;
					prefab2.m_minLevel = Mathf.Max(prefab2.m_minLevel, MinLevel.Value);
					prefab2.m_maxLevel = Mathf.Max(prefab2.m_maxLevel, MaxLevel.Value);
					prefab2.m_weight *= Mathf.Max(1f, SpawnRateMultiplier.Value);
					num = Mathf.Max(num, prefab2.m_weight);
				}
			}
			if (!flag)
			{
				return;
			}
			PatchedSpawnAreas.Add(instanceID);
			float num2 = Mathf.Max(0.1f, SpawnRateMultiplier.Value);
			__instance.m_levelupChance = Mathf.Max(__instance.m_levelupChance, LevelUpChance.Value);
			__instance.m_spawnIntervalSec = Mathf.Max(1f, __instance.m_spawnIntervalSec / num2);
			__instance.m_maxNear = Mathf.CeilToInt((float)__instance.m_maxNear * num2);
			__instance.m_maxTotal = Mathf.CeilToInt((float)__instance.m_maxTotal * num2);
			float num3 = Mathf.Clamp(VarietyDvergrSpawnChance.Value, 0f, 100f);
			if (!(num3 > 0f) || !((Object)(object)ZNetScene.instance != (Object)null))
			{
				return;
			}
			float weight = Mathf.Max(0.05f, num * (num3 / 100f) / (float)VarietyDvergrPrefabNames.Length);
			string[] varietyDvergrPrefabNames = VarietyDvergrPrefabNames;
			foreach (string text in varietyDvergrPrefabNames)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if ((Object)(object)prefab != (Object)null)
				{
					__instance.m_prefabs.Add(new SpawnData
					{
						m_prefab = prefab,
						m_weight = weight,
						m_minLevel = Mathf.Max(1, MinLevel.Value),
						m_maxLevel = Mathf.Max(MinLevel.Value, MaxLevel.Value)
					});
				}
			}
		}

		[HarmonyPatch(typeof(SpawnSystem), "Awake")]
		[HarmonyPostfix]
		private static void SpawnSystem_Awake_Postfix(SpawnSystem __instance)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: 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_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Expected O, but got Unknown
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_057a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_0633: Unknown result type (might be due to invalid IL or missing references)
			//IL_0654: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null || __instance.m_spawnLists == null || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			float num = Mathf.Max(0.1f, SpawnRateMultiplier.Value);
			GameObject prefab = ZNetScene.instance.GetPrefab("DvergerAshlands");
			foreach (SpawnSystemList spawnList in __instance.m_spawnLists)
			{
				if ((Object)(object)spawnList == (Object)null || spawnList.m_spawners == null)
				{
					continue;
				}
				int instanceID = ((Object)spawnList).GetInstanceID();
				if (PatchedSpawnLists.Contains(instanceID))
				{
					continue;
				}
				PatchedSpawnLists.Add(instanceID);
				bool flag = false;
				foreach (SpawnData spawner in spawnList.m_spawners)
				{
					if (spawner != null && !((Object)(object)spawner.m_prefab == (Object)null) && IsDvergrPrefab(spawner.m_prefab) && (spawner.m_biome & 0x20) != 0)
					{
						flag = true;
						spawner.m_enabled = true;
						spawner.m_maxSpawned = Mathf.Max(1, Mathf.CeilToInt((float)spawner.m_maxSpawned * num));
						spawner.m_spawnInterval = Mathf.Max(5f, spawner.m_spawnInterval / num);
						spawner.m_spawnChance = Mathf.Min(100f, spawner.m_spawnChance * num);
						spawner.m_groupSizeMin = Mathf.Max(1, Mathf.CeilToInt((float)spawner.m_groupSizeMin * num));
						spawner.m_groupSizeMax = Mathf.Max(spawner.m_groupSizeMin, Mathf.CeilToInt((float)spawner.m_groupSizeMax * num));
						spawner.m_minLevel = Mathf.Max(spawner.m_minLevel, MinLevel.Value);
						spawner.m_maxLevel = Mathf.Max(spawner.m_maxLevel, MaxLevel.Value);
						spawner.m_overrideLevelupChance = Mathf.Max(spawner.m_overrideLevelupChance, LevelUpChance.Value);
					}
				}
				if (flag || !EnableAmbientAshlandsSpawns.Value || !((Object)(object)prefab != (Object)null) || spawnList.m_spawners.Count <= 0)
				{
					continue;
				}
				float num2 = Mathf.Max(10f, AmbientSpawnRadiusMin.Value);
				float spawnRadiusMax = Mathf.Max(num2 + 5f, AmbientSpawnRadiusMax.Value);
				SpawnData val = new SpawnData
				{
					m_name = "Ashlands_Dvergr_Ambient",
					m_enabled = true,
					m_prefab = prefab,
					m_biome = (Biome)32,
					m_biomeArea = (BiomeArea)3,
					m_maxSpawned = Mathf.Max(1, AmbientMaxSpawned.Value),
					m_spawnInterval = Mathf.Max(5f, AmbientSpawnInterval.Value / num),
					m_spawnChance = Mathf.Clamp(AmbientSpawnChance.Value, 0f, 100f),
					m_spawnDistance = 15f,
					m_spawnRadiusMin = num2,
					m_spawnRadiusMax = spawnRadiusMax,
					m_groupSizeMin = Mathf.Max(1, AmbientGroupMin.Value),
					m_groupSizeMax = Mathf.Max(AmbientGroupMin.Value, AmbientGroupMax.Value),
					m_groupRadius = 6f,
					m_spawnAtDay = true,
					m_spawnAtNight = true,
					m_minAltitude = 1f,
					m_maxAltitude = 1000f,
					m_minTilt = 0f,
					m_maxTilt = 35f,
					m_inForest = true,
					m_outsideForest = true,
					m_inLava = false,
					m_outsideLava = true,
					m_groundOffset = 0.5f,
					m_minLevel = Mathf.Max(1, MinLevel.Value),
					m_maxLevel = Mathf.Max(MinLevel.Value, MaxLevel.Value),
					m_overrideLevelupChance = Mathf.Clamp(LevelUpChance.Value, 0f, 100f)
				};
				spawnList.m_spawners.Add(val);
				Log.LogInfo((object)$"Added ambient DvergerAshlands SpawnData (max={val.m_maxSpawned}, interval={val.m_spawnInterval}s, chance={val.m_spawnChance}%, levels={val.m_minLevel}-{val.m_maxLevel}).");
				float num3 = Mathf.Clamp(VarietyDvergrSpawnChance.Value, 0f, 100f);
				if (!(num3 > 0f))
				{
					continue;
				}
				float spawnChance = Mathf.Clamp(AmbientSpawnChance.Value * (num3 / 100f), 1f, 100f);
				int maxSpawned = Mathf.Max(1, AmbientMaxSpawned.Value / 2);
				string[] varietyDvergrPrefabNames = VarietyDvergrPrefabNames;
				foreach (string text in varietyDvergrPrefabNames)
				{
					GameObject prefab2 = ZNetScene.instance.GetPrefab(text);
					if (!((Object)(object)prefab2 == (Object)null))
					{
						SpawnData item = new SpawnData
						{
							m_name = "Ashlands_Dvergr_Variety_" + text,
							m_enabled = true,
							m_prefab = prefab2,
							m_biome = (Biome)32,
							m_biomeArea = (BiomeArea)3,
							m_maxSpawned = maxSpawned,
							m_spawnInterval = Mathf.Max(10f, AmbientSpawnInterval.Value * 1.5f / num),
							m_spawnChance = spawnChance,
							m_spawnDistance = 18f,
							m_spawnRadiusMin = num2,
							m_spawnRadiusMax = spawnRadiusMax,
							m_groupSizeMin = 1,
							m_groupSizeMax = Mathf.Max(1, AmbientGroupMax.Value / 2),
							m_groupRadius = 6f,
							m_spawnAtDay = true,
							m_spawnAtNight = true,
							m_minAltitude = 1f,
							m_maxAltitude = 1000f,
							m_minTilt = 0f,
							m_maxTilt = 35f,
							m_inForest = true,
							m_outsideForest = true,
							m_inLava = false,
							m_outsideLava = true,
							m_groundOffset = 0.5f,
							m_minLevel = Mathf.Max(1, MinLevel.Value),
							m_maxLevel = Mathf.Max(MinLevel.Value, MaxLevel.Value),
							m_overrideLevelupChance = Mathf.Clamp(LevelUpChance.Value, 0f, 100f)
						};
						spawnList.m_spawners.Add(item);
					}
				}
				Log.LogInfo((object)string.Format("Added Ashlands variety Dvergr ambient spawns ({0}) with {1}% variety ratio.", string.Join(", ", VarietyDvergrPrefabNames), num3));
			}
		}

		private static float CalculateBloodWeaponDamageMultiplier(Character ch)
		{
			float num = (IsDvergrMage(ch) ? (1.2f * (MageDamageMultiplier.Value / 1.1f)) : (1.35f * (DamageMultiplier.Value / 1.25f)));
			float num2 = (((Object)(object)ch != (Object)null) ? Mathf.Clamp01(1f - ch.GetHealthPercentage()) : 0f);
			float num3 = 1f + num2 * 0.5f;
			return num * num3;
		}

		[HarmonyPatch(typeof(SEMan), "ModifyAttack")]
		[HarmonyPostfix]
		private static void SEMan_ModifyAttack_Postfix(Character ___m_character, ref HitData hitData)
		{
			if (hitData != null && IsAshlandsDvergr(___m_character))
			{
				int num = Mathf.Max(0, ___m_character.GetLevel() - 1);
				int num2 = Mathf.Min(num, 1);
				float num3 = 1f + (float)num * 0.5f;
				float num4 = 1f + (float)num2 * 0.25f;
				float num5 = ((UseAshlandsBloodWeapons.Value && num >= 2) ? CalculateBloodWeaponDamageMultiplier(___m_character) : GetDamageMultiplierFor(___m_character)) * (num4 / num3);
				((DamageTypes)(ref hitData.m_damage)).Modify(num5);
			}
		}

		[HarmonyPatch(typeof(Aoe), "Setup")]
		[HarmonyPostfix]
		private static void Aoe_Setup_Postfix(Aoe __instance, Character owner, HitData hitData)
		{
			if (!((Object)(object)__instance == (Object)null) && IsAshlandsDvergr(owner) && (hitData == null || !__instance.m_useAttackSettings))
			{
				int num = Mathf.Max(0, owner.GetLevel() - 1);
				int num2 = Mathf.Min(num, 1);
				float num3 = ((UseAshlandsBloodWeapons.Value && num >= 2) ? CalculateBloodWeaponDamageMultiplier(owner) : GetDamageMultiplierFor(owner)) * (1f + (float)num2 * 0.25f);
				((DamageTypes)(ref __instance.m_damage)).Modify(num3);
			}
		}

		[HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")]
		[HarmonyPostfix]
		private static void VisEquipment_UpdateEquipmentVisuals_Postfix(VisEquipment __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				AshlandsDvergrEnhancer component = ((Component)__instance).GetComponent<AshlandsDvergrEnhancer>();
				if ((Object)(object)component != (Object)null)
				{
					component.CheckEquipmentVisualsChanged();
				}
			}
		}

		private static IEnumerator RenderDvergrValidationCoroutine()
		{
			yield return (object)new WaitForSeconds(1f);
			Log.LogInfo((object)"=== Starting DvergerAshlands Visual Validation Render ===");
			try
			{
				AssetID val = default(AssetID);
				if (!AssetID.TryParse("2ece1cf15f2885a4da6da84af9d5c542", ref val))
				{
					Log.LogError((object)"Failed to parse DvergerAshlands AssetID");
					yield break;
				}
				SoftReference<GameObject> val2 = default(SoftReference<GameObject>);
				val2..ctor(val);
				LoadResult val3 = val2.Load();
				Log.LogInfo((object)$"Loaded DvergerAshlands SoftReference: {val3}");
				GameObject asset = val2.Asset;
				if ((Object)(object)asset == (Object)null)
				{
					Log.LogError((object)"DvergerAshlands prefab is null");
					yield break;
				}
				Renderer[] componentsInChildren = asset.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val4 in componentsInChildren)
				{
					Material[] sharedMaterials = val4.sharedMaterials;
					foreach (Material val5 in sharedMaterials)
					{
						if (!((Object)(object)val5 == (Object)null))
						{
							int num = (((Object)(object)val5.shader != (Object)null) ? val5.shader.GetPropertyCount() : 0);
							List<string> list = new List<string>();
							for (int k = 0; k < num; k++)
							{
								list.Add($"{val5.shader.GetPropertyName(k)}({val5.shader.GetPropertyType(k)})");
							}
							ManualLogSource log = Log;
							object[] obj = new object[7]
							{
								((Object)val4).name,
								((Component)val4).gameObject.activeInHierarchy,
								val4.enabled,
								((object)val4).GetType().Name,
								((Object)val5).name,
								null,
								null
							};
							Shader shader = val5.shader;
							obj[5] = ((shader != null) ? ((Object)shader).name : null);
							obj[6] = string.Join(", ", list);
							log.LogInfo((object)string.Format("[Prefab Renderer] {0} (active={1}, enabled={2}, {3}) | Mat={4} | Shader={5} | Props=[{6}]", obj));
						}
					}
				}
				List<GameObject> list2 = new List<GameObject>();
				Humanoid component = asset.GetComponent<Humanoid>();
				if ((Object)(object)component != (Object)null)
				{
					if (component.m_defaultItems != null)
					{
						GameObject[] defaultItems = component.m_defaultItems;
						foreach (GameObject val6 in defaultItems)
						{
							if ((Object)(object)val6 != (Object)null)
							{
								Log.LogInfo((object)("[Humanoid defaultItem] " + ((Object)val6).name));
								list2.Add(val6);
							}
						}
					}
					if (component.m_randomArmor != null && component.m_randomArmor.Length != 0)
					{
						GameObject[] defaultItems = component.m_randomArmor;
						foreach (GameObject val7 in defaultItems)
						{
							if ((Object)(object)val7 != (Object)null)
							{
								Log.LogInfo((object)("[Humanoid randomArmor] " + ((Object)val7).name));
							}
						}
						if ((Object)(object)component.m_randomArmor[0] != (Object)null)
						{
							list2.Add(component.m_randomArmor[0]);
						}
					}
					if (component.m_randomSets != null && component.m_randomSets.Length != 0)
					{
						ItemSet[] randomSets = component.m_randomSets;
						foreach (ItemSet val8 in randomSets)
						{
							if (val8?.m_items == null)
							{
								continue;
							}
							GameObject[] defaultItems = val8.m_items;
							foreach (GameObject val9 in defaultItems)
							{
								if ((Object)(object)val9 != (Object)null)
								{
									Log.LogInfo((object)("[Humanoid randomSet " + val8.m_name + "] " + ((Object)val9).name));
								}
							}
						}
						if (component.m_randomSets[0]?.m_items != null)
						{
							GameObject[] defaultItems = component.m_randomSets[0].m_items;
							foreach (GameObject val10 in defaultItems)
							{
								if ((Object)(object)val10 != (Object)null)
								{
									list2.Add(val10);
								}
							}
						}
					}
				}
				LevelEffects componentInChildren = asset.GetComponentInChildren<LevelEffects>(true);
				if ((Object)(object)componentInChildren != (Object)null && componentInChildren.m_levelSetups != null)
				{
					for (int l = 0; l < componentInChildren.m_levelSetups.Count; l++)
					{
						LevelSetup val11 = componentInChildren.m_levelSetups[l];
						ManualLogSource log2 = Log;
						object[] obj2 = new object[8] { l, val11.m_scale, val11.m_hue, val11.m_saturation, val11.m_value, val11.m_setEmissiveColor, val11.m_emissiveColor, null };
						GameObject enableObject = val11.m_enableObject;
						obj2[7] = ((enableObject != null) ? ((Object)enableObject).name : null);
						log2.LogInfo((object)string.Format("[Prefab LevelSetup {0}] scale={1}, hue={2}, sat={3}, val={4}, setEmissive={5}, emissive={6}, enableObj={7}", obj2));
					}
				}
				VisEquipment component2 = asset.GetComponent<VisEquipment>();
				if ((Object)(object)component2 != (Object)null)
				{
					ManualLogSource log3 = Log;
					string[] obj3 = new string[8] { "[Prefab VisEquipment] rightHand=", null, null, null, null, null, null, null };
					Transform rightHand = component2.m_rightHand;
					obj3[1] = ((rightHand != null) ? ((Object)rightHand).name : null);
					obj3[2] = ", leftHand=";
					Transform leftHand = component2.m_leftHand;
					obj3[3] = ((leftHand != null) ? ((Object)leftHand).name : null);
					obj3[4] = ", helmet=";
					Transform helmet = component2.m_helmet;
					obj3[5] = ((helmet != null) ? ((Object)helmet).name : null);
					obj3[6] = ", backBow=";
					Transform backBow = component2.m_backBow;
					obj3[7] = ((backBow != null) ? ((Object)backBow).name : null);
					log3.LogInfo((object)string.Concat(obj3));
				}
				foreach (GameObject item in list2)
				{
					List<string> list3 = new List<string>();
					Transform[] componentsInChildren2 = item.GetComponentsInChildren<Transform>(true);
					foreach (Transform val12 in componentsInChildren2)
					{
						list3.Add(((Object)val12).name);
					}
					Log.LogInfo((object)("[EquipItem " + ((Object)item).name + "] children=[" + string.Join(", ", list3) + "]"));
				}
				if ((Object)(object)asset.transform.Find("Visual") == (Object)null)
				{
					_ = asset.transform;
				}
				Vector3 val13 = default(Vector3);
				((Vector3)(ref val13))..ctor(0f, 500f, 0f);
				GameObject val14 = new GameObject("DvergrValidationStage");
				val14.transform.position = val13;
				float[] array = new float[4] { -2.7f, -0.9f, 0.9f, 2.7f };
				int[] array2 = new int[4] { 3, 3, 3, 3 };
				string[] array3 = new string[4] { "DvergerAshlands", "DvergerMageFire", "DvergerMageIce", "DvergerMageSupport" };
				for (int m = 0; m < 4; m++)
				{
					int num2 = array2[m];
					string text = array3[m];
					GameObject val15 = ResolvePrefabByNameOrAssetId(text) ?? asset;
					GameObject val16 = Object.Instantiate<GameObject>(((Component)(val15.transform.Find("Visual") ?? val15.transform)).gameObject, val14.transform);
					((Object)val16).name = text;
					val16.transform.localPosition = new Vector3(array[m], 0f, 0f);
					val16.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
					float num3 = num2 switch
					{
						2 => VisualScale1Star.Value, 
						1 => 1f, 
						_ => VisualScale2Star.Value, 
					};
					val16.transform.localScale = Vector3.one * num3;
					VisEquipment component3 = val15.GetComponent<VisEquipment>();
					string b = (((Object)(object)component3?.m_rightHand != (Object)null) ? ((Object)component3.m_rightHand).name : "RightHand_Attach");
					List<GameObject> list4 = new List<GameObject>();
					Humanoid component4 = val15.GetComponent<Humanoid>();
					if ((Object)(object)component4 != (Object)null)
					{
						if (component4.m_defaultItems != null)
						{
							GameObject[] defaultItems = component4.m_defaultItems;
							foreach (GameObject val17 in defaultItems)
							{
								if ((Object)(object)val17 != (Object)null)
								{
									list4.Add(val17);
								}
							}
						}
						if (component4.m_randomArmor != null && component4.m_randomArmor.Length != 0 && (Object)(object)component4.m_randomArmor[0] != (Object)null)
						{
							list4.Add(component4.m_randomArmor[0]);
						}
						if (component4.m_randomSets != null && component4.m_randomSets.Length != 0 && component4.m_randomSets[0]?.m_items != null)
						{
							GameObject[] defaultItems = component4.m_randomSets[0].m_items;
							foreach (GameObject val18 in defaultItems)
							{
								if ((Object)(object)val18 != (Object)null)
								{
									list4.Add(val18);
								}
							}
						}
					}
					SkinnedMeshRenderer componentInChildren2 = val16.GetComponentInChildren<SkinnedMeshRenderer>(true);
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						Transform val19 = null;
						Transform[] componentsInChildren2 = val16.GetComponentsInChildren<Transform>(true);
						foreach (Transform val20 in componentsInChildren2)
						{
							if (string.Equals(((Object)val20).name, b, StringComparison.OrdinalIgnoreCase) || ((Object)(object)val19 == (Object)null && ((Object)val20).name.IndexOf("Hand", StringComparison.OrdinalIgnoreCase) >= 0))
							{
								val19 = val20;
								if (string.Equals(((Object)val20).name, b, StringComparison.OrdinalIgnoreCase))
								{
									break;
								}
							}
						}
						foreach (GameObject item2 in list4)
						{
							Transform val21 = item2.transform.Find("attach_skin");
							if ((Object)(object)val21 != (Object)null)
							{
								GameObject obj4 = Object.Instantiate<GameObject>(((Component)val21).gameObject, ((Component)componentInChildren2).transform.parent);
								obj4.SetActive(true);
								SkinnedMeshRenderer[] componentsInChildren3 = obj4.GetComponentsInChildren<SkinnedMeshRenderer>(true);
								foreach (SkinnedMeshRenderer obj5 in componentsInChildren3)
								{
									obj5.rootBone = componentInChildren2.rootBone;
									obj5.bones = componentInChildren2.bones;
								}
							}
							Transform val22 = item2.transform.Find("attach") ?? item2.transform.Find("attach_r.hand");
							if ((Object)(object)val22 != (Object)null && (Object)(object)val19 != (Object)null)
							{
								GameObject obj6 = Object.Instantiate<GameObject>(((Component)val22).gameObject);
								((Object)obj6).name = "attach_" + ((Object)item2).name;
								obj6.transform.SetParent(val19, true);
								obj6.transform.localPosition = Vector3.zero;
								obj6.transform.localRotation = Quaternion.identity;
								obj6.SetActive(true);
								Transform val23 = obj6.transform.Find("Cube");
								if ((Object)(object)val23 != (Object)null)
								{
									((Component)val23).gameObject.SetActive(false);
								}
							}
						}
					}
					Light auraLight = null;
					AshlandsDvergrEnhancer.ApplyStyleToHierarchy(val16.transform, num2, ref auraLight, out var _);
				}
				ParticleSystem[] componentsInChildren4 = val14.GetComponentsInChildren<ParticleSystem>(false);
				foreach (ParticleSystem val24 in componentsInChildren4)
				{
					if ((Object)(object)((Component)val24).transform.parent == (Object)null || (Object)(object)((Component)((Component)val24).transform.parent).GetComponentInParent<ParticleSystem>() == (Object)null)
					{
						val24.Simulate(0.85f, true, true);
					}
				}
				GameObject val25 = new GameObject("KeyLight");
				val25.transform.SetParent(val14.transform, false);
				val25.transform.localPosition = new Vector3(1.5f, 3.2f, -3.5f);
				val25.transform.LookAt(val13 + new Vector3(0f, 1.1f, 0f));
				Light obj7 = val25.AddComponent<Light>();
				obj7.type = (LightType)1;
				obj7.color = new Color(1f, 0.96f, 0.9f);
				obj7.intensity = 1.1f;
				GameObject val26 = new GameObject("ValidationCamera");
				val26.transform.SetParent(val14.transform, false);
				val26.transform.localPosition = new Vector3(0f, 1.15f, -4.8f);
				val26.transform.LookAt(val13 + new Vector3(0f, 1.05f, 0f));
				Camera obj8 = val26.AddComponent<Camera>();
				obj8.clearFlags = (CameraClearFlags)2;
				obj8.backgroundColor = new Color(0.11f, 0.1f, 0.12f, 1f);
				obj8.fieldOfView = 44f;
				obj8.nearClipPlane = 0.1f;
				obj8.farClipPlane = 50f;
				int num4 = 1920;
				int num5 = 800;
				RenderTexture active = (obj8.targetTexture = new RenderTexture(num4, num5, 24, (RenderTextureFormat)0));
				obj8.Render();
				RenderTexture.active = active;
				Texture2D val28 = new Texture2D(num4, num5, (TextureFormat)3, false);
				val28.ReadPixels(new Rect(0f, 0f, (float)num4, (float)num5), 0, 0);
				val28.Apply();
				RenderTexture.active = null;
				byte[] array4 = ImageConversion.EncodeToPNG(val28);
				string text2 = "/tmp/dvergr_render_validation.png";
				File.WriteAllBytes(text2, array4);
				Log.LogInfo((object)$"=== Saved validation render ({array4.Length} bytes) to {text2} ===");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Validation render failed: {arg}");
			}
			Process.GetCurrentProcess().Kill();
		}
	}
	internal class AshlandsDvergrEnhancer : MonoBehaviour
	{
		private static readonly Dictionary<int, Color> OriginalMaterialColors = new Dictionary<int, Color>();

		private static readonly Dictionary<int, Color> OriginalMaterialEmissions = new Dictionary<int, Color>();

		private Character _character;

		private ZNetView _nview;

		private Light _auraLight;

		private float _healTimer;

		private float _noiseSeed;

		private float _baseLightIntensity = 1f;

		private int _lastRendererCount;

		private int _lastAppliedLevel;

		private void Awake()
		{
			_character = ((Component)this).GetComponent<Character>();
			_nview = ((Component)this).GetComponent<ZNetView>();
			_noiseSeed = Random.Range(0f, 100f);
		}

		private void Start()
		{
			ApplyCoolVisuals();
		}

		internal void CheckEquipmentVisualsChanged()
		{
			if (!((Object)(object)_character == (Object)null))
			{
				Renderer[] componentsInChildren = ((Component)_character).GetComponentsInChildren<Renderer>(true);
				int num = Mathf.Max(1, _character.GetLevel());
				if (componentsInChildren.Length != _lastRendererCount || num != _lastAppliedLevel)
				{
					ApplyCoolVisuals();
				}
			}
		}

		private void Update()
		{
			if ((Object)(object)_character == (Object)null || _character.IsDead())
			{
				if ((Object)(object)_auraLight != (Object)null)
				{
					((Behaviour)_auraLight).enabled = false;
				}
				return;
			}
			if ((Object)(object)_auraLight != (Object)null && ((Behaviour)_auraLight).enabled)
			{
				float num = 0.85f + 0.3f * Mathf.PerlinNoise(Time.time * 3.5f, _noiseSeed);
				_auraLight.intensity = _baseLightIntensity * num;
			}
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner())
			{
				return;
			}
			float value = AshlandsDvergrPlugin.PassiveHealPercentPerTick.Value;
			if (value <= 0f)
			{
				return;
			}
			float num2 = Mathf.Max(1f, AshlandsDvergrPlugin.PassiveHealIntervalSeconds.Value);
			_healTimer += Time.deltaTime;
			if (!(_healTimer < num2))
			{
				_healTimer = 0f;
				float health = _character.GetHealth();
				float maxHealth = _character.GetMaxHealth();
				if (health > 0f && health < maxHealth)
				{
					float num3 = maxHealth * (value / 100f);
					_character.Heal(num3, false);
				}
			}
		}

		internal void ApplyCoolVisuals()
		{
			if (!((Object)(object)_character == (Object)null))
			{
				AshlandsDvergrPlugin.EnsureVisualStarSetups(_character);
				int num = (_lastAppliedLevel = Mathf.Max(1, _character.GetLevel()));
				LevelEffects componentInChildren = ((Component)_character).GetComponentInChildren<LevelEffects>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.SetupLevelVisualization(num);
				}
				_lastRendererCount = ApplyStyleToHierarchy(((Component)_character).transform, num, ref _auraLight, out _baseLightIntensity);
			}
		}

		private static bool IsWeaponRenderer(Renderer r, Material m, VisEquipment visEq)
		{
			if ((Object)(object)r == (Object)null)
			{
				return false;
			}
			if ((Object)(object)visEq != (Object)null)
			{
				Transform transform = ((Component)r).transform;
				if (((Object)(object)visEq.m_rightHand != (Object)null && transform.IsChildOf(visEq.m_rightHand)) || ((Object)(object)visEq.m_leftHand != (Object)null && transform.IsChildOf(visEq.m_leftHand)) || ((Object)(object)visEq.m_backMelee != (Object)null && transform.IsChildOf(visEq.m_backMelee)) || ((Object)(object)visEq.m_backBow != (Object)null && transform.IsChildOf(visEq.m_backBow)) || ((Object)(object)visEq.m_backTool != (Object)null && transform.IsChildOf(visEq.m_backTool)) || ((Object)(object)visEq.m_backAtgeir != (Object)null && transform.IsChildOf(visEq.m_backAtgeir)))
				{
					return true;
				}
			}
			string text = ((Object)r).name ?? string.Empty;
			string text2 = (((Object)(object)m != (Object)null) ? (((Object)m).name ?? string.Empty) : string.Empty);
			if (text.IndexOf("Arbalest", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Staff", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Crossbow", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("Arbalest", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("Staff", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("Crossbow", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			Transform val = ((Component)r).transform;
			while ((Object)(object)val != (Object)null)
			{
				string text3 = ((Object)val).name ?? string.Empty;
				if (text3.IndexOf("Hand", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("BackBow", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("BackMelee", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("BackTool", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("attach_Dverger", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("AshlandsDvergr_BloodWeapon", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static Transform FindBone(Transform root, params string[] names)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				foreach (string b in names)
				{
					if (string.Equals(((Object)val).name, b, StringComparison.OrdinalIgnoreCase))
					{
						return val;
					}
				}
			}
			return null;
		}

		private static void EnsureBloodWeaponVisual(Transform root, VisEquipment visEq, int level)
		{
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			bool flag = AshlandsDvergrPlugin.UseAshlandsBloodWeapons.Value && level >= 3;
			Transform val = (((Object)(object)visEq != (Object)null && (Object)(object)visEq.m_rightHand != (Object)null) ? visEq.m_rightHand : FindBone(root, "r.hand", "RightHand_Attach", "RightHand"));
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = val.Find("AshlandsDvergr_BloodWeapon");
			if (!flag)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					((Component)val2).gameObject.SetActive(false);
				}
				for (int i = 0; i < val.childCount; i++)
				{
					Transform child = val.GetChild(i);
					if (!((Object)(object)child != (Object)(object)val2) || ((Object)child).name.IndexOf("AshlandsDvergr_", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						continue;
					}
					Renderer[] componentsInChildren = ((Component)child).GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val3 in componentsInChildren)
					{
						if (((Object)val3).name != "Cube")
						{
							val3.enabled = true;
						}
					}
				}
				return;
			}
			for (int k = 0; k < val.childCount; k++)
			{
				Transform child2 = val.GetChild(k);
				if (!((Object)(object)child2 == (Object)(object)val2) && ((Object)child2).name.IndexOf("AshlandsDvergr_", StringComparison.OrdinalIgnoreCase) < 0)
				{
					Renderer[] componentsInChildren = ((Component)child2).GetComponentsInChildren<Renderer>(true);
					for (int j = 0; j < componentsInChildren.Length; j++)
					{
						componentsInChildren[j].enabled = false;
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(true);
				return;
			}
			Character val4 = ((Component)root).GetComponentInParent<Character>() ?? ((Component)root).GetComponentInChildren<Character>();
			string text = (((Object)(object)val4 != (Object)null) ? ((Object)((Component)val4).gameObject).name : ((Object)root).name);
			string equivalentBloodWeaponPrefabName = AshlandsDvergrPlugin.GetEquivalentBloodWeaponPrefabName(text);
			GameObject val5 = AshlandsDvergrPlugin.ResolvePrefabByNameOrAssetId(equivalentBloodWeaponPrefabName);
			if ((Object)(object)val5 == (Object)null)
			{
				AshlandsDvergrPlugin.Log.LogError((object)("[EnsureBloodWeaponVisual] Failed to resolve weaponPrefab '" + equivalentBloodWeaponPrefabName + "' for character '" + text + "'"));
				return;
			}
			Transform val6 = val5.transform.Find("attach") ?? val5.transform.Find("attach_r.hand");
			if ((Object)(object)val6 == (Object)null)
			{
				Transform[] componentsInChildren2 = val5.GetComponentsInChildren<Transform>(true);
				foreach (Transform val7 in componentsInChildren2)
				{
					if (((Object)val7).name.IndexOf("attach", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						val6 = val7;
						break;
					}
				}
			}
			if ((Object)(object)val6 == (Object)null)
			{
				List<string> list = new List<string>();
				Transform[] componentsInChildren2 = val5.GetComponentsInChildren<Transform>(true);
				foreach (Transform val8 in componentsInChildren2)
				{
					list.Add(((Object)val8).name);
				}
				AshlandsDvergrPlugin.Log.LogError((object)("[EnsureBloodWeaponVisual] No attach transform on '" + ((Object)val5).name + "', children=[" + string.Join(", ", list) + "]"));
				return;
			}
			AshlandsDvergrPlugin.Log.LogInfo((object)("[EnsureBloodWeaponVisual] Equipping '" + ((Object)val5).name + "' via attach '" + ((Object)val6).name + "' to '" + ((Object)val).name + "' on '" + text + "'"));
			GameObject obj = Object.Instantiate<GameObject>(((Component)val6).gameObject);
			((Object)obj).name = "AshlandsDvergr_BloodWeapon";
			obj.transform.SetParent(val, true);
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localRotation = Quaternion.identity;
			obj.SetActive(true);
			Transform val9 = obj.transform.Find("Cube");
			if ((Object)(object)val9 != (Object)null)
			{
				((Component)val9).gameObject.SetActive(false);
			}
		}

		private static void Ensure2StarBossEffects(Transform root, int level, bool coolEnabled, float lightMult)
		{
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: 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_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: 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_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			bool flag = coolEnabled && level >= 3 && AshlandsDvergrPlugin.Enable2StarBossEffects.Value;
			Transform val = root.Find("AshlandsDvergr_BossFX");
			Transform val2 = FindBone(root, "l.hand", "LeftHand_Attach", "LeftHand");
			Transform val3 = FindBone(root, "r.hand", "RightHand_Attach", "RightHand");
			Transform val4 = FindBone(root, "spine2", "spine1", "chest", "Spine");
			Transform val5 = (((Object)(object)val2 != (Object)null) ? val2.Find("AshlandsDvergr_BossHandFX") : null);
			Transform val6 = (((Object)(object)val3 != (Object)null) ? val3.Find("AshlandsDvergr_BossHandFX") : null);
			Transform val7 = (((Object)(object)val4 != (Object)null) ? val4.Find("AshlandsDvergr_BossChestFX") : null);
			if (!flag)
			{
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(false);
				}
				if ((Object)(object)val5 != (Object)null)
				{
					((Component)val5).gameObject.SetActive(false);
				}
				if ((Object)(object)val6 != (Object)null)
				{
					((Component)val6).gameObject.SetActive(false);
				}
				if ((Object)(object)val7 != (Object)null)
				{
					((Component)val7).gameObject.SetActive(false);
				}
				return;
			}
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(true);
				if ((Object)(object)val5 != (Object)null)
				{
					((Component)val5).gameObject.SetActive(true);
				}
				if ((Object)(object)val6 != (Object)null)
				{
					((Component)val6).gameObject.SetActive(true);
				}
				if ((Object)(object)val7 != (Object)null)
				{
					((Component)val7).gameObject.SetActive(true);
				}
				return;
			}
			GameObject val8 = new GameObject("AshlandsDvergr_BossFX");
			val8.transform.SetParent(root, false);
			val8.transform.localPosition = Vector3.zero;
			val8.transform.localRotation = Quaternion.identity;
			GameObject val9 = AshlandsDvergrPlugin.ResolvePrefabByNameOrAssetId("fx_DvergerMage_Nova_ring");
			if ((Object)(object)val9 != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(val9, val8.transform);
				((Object)obj).name = "BossArcaneRing";
				obj.transform.localPosition = new Vector3(0f, 0.85f, 0f);
				obj.transform.localRotation = Quaternion.identity;
				obj.transform.localScale = Vector3.one * 0.25f;
				ConfigureBossParticlePrefab(obj, new Color(0.85f, 0.22f, 1f, 0.55f), 0.35f);
			}
			GameObject val10 = AshlandsDvergrPlugin.ResolvePrefabByNameOrAssetId("vfx_crossbow_blood_fire");
			if ((Object)(object)val10 != (Object)null && (Object)(object)val4 != (Object)null)
			{
				GameObject obj2 = Object.Instantiate<GameObject>(val10);
				((Object)obj2).name = "AshlandsDvergr_BossChestFX";
				obj2.transform.SetParent(val4, true);
				obj2.transform.localPosition = Vector3.zero;
				obj2.transform.localRotation = Quaternion.identity;
				obj2.transform.localScale = Vector3.one * 0.0052f;
				ConfigureBossParticlePrefab(obj2, new Color(0.95f, 0.18f, 0.72f, 0.85f), 0.55f);
			}
			if ((Object)(object)val10 != (Object)null)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					GameObject obj3 = Object.Instantiate<GameObject>(val10);
					((Object)obj3).name = "AshlandsDvergr_BossHandFX";
					obj3.transform.SetParent(val2, true);
					obj3.transform.localPosition = Vector3.zero;
					obj3.transform.localRotation = Quaternion.identity;
					obj3.transform.localScale = Vector3.one * 0.0042f;
					ConfigureBossParticlePrefab(obj3, new Color(0.85f, 0.22f, 1f, 0.88f), 0.45f);
				}
				if ((Object)(object)val3 != (Object)null)
				{
					GameObject obj4 = Object.Instantiate<GameObject>(val10);
					((Object)obj4).name = "AshlandsDvergr_BossHandFX";
					obj4.transform.SetParent(val3, true);
					obj4.transform.localPosition = Vector3.zero;
					obj4.transform.localRotation = Quaternion.identity;
					obj4.transform.localScale = Vector3.one * 0.0042f;
					ConfigureBossParticlePrefab(obj4, new Color(1f, 0.18f, 0.58f, 0.88f), 0.45f);
				}
			}
		}

		private static void ConfigureBossParticlePrefab(GameObject fxInstance, Color tintColor, float sizeMult = 0.25f, bool disableBrightFlareChildren = true)
		{
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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)
			//IL_02d3: 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)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Invalid comparison between Unknown and I4
			if ((Object)(object)fxInstance == (Object)null)
			{
				return;
			}
			fxInstance.SetActive(true);
			TimedDestruction[] componentsInChildren = fxInstance.GetComponentsInChildren<TimedDestruction>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			ZNetView[] componentsInChildren2 = fxInstance.GetComponentsInChildren<ZNetView>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Behaviour)componentsInChildren2[i]).enabled = false;
			}
			AudioSource[] componentsInChildren3 = fxInstance.GetComponentsInChildren<AudioSource>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				((Behaviour)componentsInChildren3[i]).enabled = false;
			}
			ZSFX[] componentsInChildren4 = fxInstance.GetComponentsInChildren<ZSFX>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				((Behaviour)componentsInChildren4[i]).enabled = false;
			}
			Light[] componentsInChildren5 = fxInstance.GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				((Behaviour)componentsInChildren5[i]).enabled = false;
			}
			Renderer[] componentsInChildren6 = fxInstance.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren6)
			{
				if (!(val is ParticleSystemRenderer))
				{
					val.enabled = false;
				}
			}
			ParticleSystem[] componentsInChildren7 = fxInstance.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val2 in componentsInChildren7)
			{
				string text = ((Object)((Component)val2).gameObject).name ?? string.Empty;
				ParticleSystemRenderer component = ((Component)val2).GetComponent<ParticleSystemRenderer>();
				string text2 = (((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).sharedMaterial != (Object)null) ? ((Object)((Renderer)component).sharedMaterial).name : string.Empty);
				MainModule main = val2.main;
				ShapeModule shape = val2.shape;
				MinMaxCurve val3;
				int num;
				if (!((ShapeModule)(ref shape)).enabled)
				{
					val3 = ((MainModule)(ref main)).startSpeed;
					if (((MinMaxCurve)(ref val3)).constantMax <= 0.05f)
					{
						val3 = ((MainModule)(ref main)).startSize;
						num = ((((MinMaxCurve)(ref val3)).constantMax >= 0.4f) ? 1 : 0);
						goto IL_0194;
					}
				}
				num = 0;
				goto IL_0194;
				IL_0194:
				bool flag = (byte)num != 0;
				if (disableBrightFlareChildren && (text.IndexOf("flare", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("flash", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("glow", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("light", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("shockwave", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("refract", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("sphere", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("core", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("orb", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("flare", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)(object)component != (Object)null && (int)component.renderMode == 4) || flag))
				{
					((Component)val2).gameObject.SetActive(false);
				}
				else
				{
					((MainModule)(ref main)).loop = true;
					((MainModule)(ref main)).playOnAwake = true;
					((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
					((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * sizeMult;
					((MainModule)(ref main)).startSpeedMultiplier = ((MainModule)(ref main)).startSpeedMultiplier * sizeMult;
					((MainModule)(ref main)).maxParticles = Mathf.Min(((MainModule)(ref main)).maxParticles, 28);
					((MainModule)(ref main)).startColor = new MinMaxGradient(tintColor, new Color(1f, 0.22f, 0.42f, tintColor.a * 0.85f));
					EmissionModule emission = val2.emission;
					((EmissionModule)(ref emission)).rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier * 0.7f;
					for (int j = 0; j < ((EmissionModule)(ref emission)).burstCount; j++)
					{
						Burst burst = ((EmissionModule)(ref emission)).GetBurst(j);
						val3 = ((Burst)(ref burst)).count;
						((Burst)(ref burst)).count = new MinMaxCurve(Mathf.Min(6f, Mathf.Max(2f, ((MinMaxCurve)(ref val3)).constant * 0.35f)));
						((EmissionModule)(ref emission)).SetBurst(j, burst);
					}
					val2.Play(false);
				}
			}
		}

		internal static int ApplyStyleToHierarchy(Transform root, int level, ref Light auraLight, out float baseLightIntensity)
		{
			//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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Expected O, but got Unknown
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a3: 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_022b: 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_024b: 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_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: 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_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			baseLightIntensity = 0f;
			bool value = AshlandsDvergrPlugin.EnableCoolVisuals.Value;
			float num = Mathf.Max(0f, AshlandsDvergrPlugin.AuraLightIntensity.Value);
			VisEquipment visEq = ((Component)root).GetComponentInParent<VisEquipment>() ?? ((Component)root).GetComponentInChildren<VisEquipment>();
			EnsureBloodWeaponVisual(root, visEq, level);
			Ensure2StarBossEffects(root, level, value, num);
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			Color val = (Color)(value ? (level switch
			{
				3 => new Color(1.18f, 0.46f, 0.42f, 1f), 
				2 => new Color(1.28f, 0.88f, 0.55f, 1f), 
				_ => Color.white, 
			}) : Color.white);
			Color val2 = val;
			val = (Color)(value ? (level switch
			{
				3 => new Color(0.7f, 0.74f, 0.86f, 1f), 
				2 => new Color(0.88f, 0.92f, 1f, 1f), 
				_ => Color.white, 
			}) : Color.white);
			Color val3 = val;
			Color val4 = (Color)((!value || level < 3) ? Color.white : new Color(1.08f, 0.92f, 1.18f, 1f));
			Renderer[] array = componentsInChildren;
			foreach (Renderer val5 in array)
			{
				if ((Object)(object)val5 == (Object)null || (!(val5 is SkinnedMeshRenderer) && !(val5 is MeshRenderer)) || val5.sharedMaterials == null)
				{
					continue;
				}
				Material[] materials = val5.materials;
				bool flag = false;
				foreach (Material val6 in materials)
				{
					if ((Object)(object)val6 == (Object)null)
					{
						continue;
					}
					int instanceID = ((Object)val6).GetInstanceID();
					bool flag2 = val6.HasProperty("_EmissionMap") && (Object)(object)val6.GetTexture("_EmissionMap") != (Object)null;
					bool flag3 = ((Object)val6).name.IndexOf("Body", StringComparison.OrdinalIgnoreCase) >= 0;
					bool flag4 = !flag3 && IsWeaponRenderer(val5, val6, visEq);
					if (flag4)
					{
						flag = true;
					}
					if (val6.HasProperty("_Color"))
					{
						if (!OriginalMaterialColors.TryGetValue(instanceID, out var value2))
						{
							value2 = val6.GetColor("_Color");
							OriginalMaterialColors[instanceID] = value2;
						}
						Color val7 = (flag3 ? val3 : (flag4 ? val4 : val2));
						val6.SetColor("_Color", new Color(value2.r * val7.r, value2.g * val7.g, value2.b * val7.b, value2.a));
					}
					if (val6.HasProperty("_Hue"))
					{
						val6.SetFloat("_Hue", 0f);
					}
					if (val6.HasProperty("_Saturation"))
					{
						val6.SetFloat("_Saturation", 0f);
					}
					if (val6.HasProperty("_Value"))
					{
						val6.SetFloat("_Value", 0f);
					}
					if (val6.HasProperty("_EmissionColor"))
					{
						if (!OriginalMaterialEmissions.TryGetValue(instanceID, out var value3))
						{
							value3 = val6.GetColor("_EmissionColor");
							OriginalMaterialEmissions[instanceID] = value3;
						}
						if (flag3 && flag2)
						{
							val = (Color)(value ? (level switch
							{
								3 => new Color(0.8f, -0.65f, 1.45f, 1f), 
								2 => new Color(1.2f, -0.15f, -0.85f, 1f), 
								_ => value3, 
							}) : value3);
							Color val8 = val;
							val6.SetColor("_EmissionColor", val8);
						}
						else if (flag4)
						{
							if (value && level >= 3)
							{
								val6.EnableKeyword("_EMISSION");
								Color val9 = (flag2 ? new Color(1.6f, 0.35f, 2.4f, 1f) : new Color(0.22f, 0.06f, 0.34f, 1f));
								val6.SetColor("_EmissionColor", val9);
							}
							else
							{
								val6.SetColor("_EmissionColor", value3);
							}
						}
						else
						{
							val6.SetColor("_EmissionColor", Color.black);
						}
					}
					if (!val6.HasProperty("_NoiseGlowEnabled"))