Decompiled source of HexDvergrAllies v0.0.3

plugins/HexDvergrAllies.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HexDvergrAllies.Assets;
using HexDvergrAllies.Core;
using HexDvergrAllies.Core.Companions;
using HexDvergrAllies.Core.Features.Progression;
using HexDvergrAllies.Core.HexLocalization;
using HexDvergrAllies.Core.Monoscripts;
using HexDvergrAllies.Core.Networking;
using HexDvergrAllies.Core.StatusEffects;
using HexDvergrAllies.Core.Trading;
using HexDvergrAllies.Core.UI;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HexDvergrAllies")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HexDvergrAllies")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4db451e5-9711-4541-9168-5c7c48d659d3")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HexDvergrAllies
{
	internal static class DvergrPricingConfig
	{
		internal const int FreeExtractorPurchases = 2;

		internal const int MistlandsJuteQuantity = 2;

		internal const int MistlandsJuteCoinCost = 500;

		internal const int FallenBrotherTrophyCost = 4;

		internal const int ExtractorSapCost = 10;

		internal const int ForgePactCost = 2;

		internal const int AshlandsFlametalQuantity = 10;

		internal const int AshlandsMoltenCoreCost = 1;

		internal static string FallenBrotherCostDisplay => HexLocalizationManager.Localize("$hex_dvergr_fallen_brother_cost", 4);

		internal static string ForgePactCostDisplay => HexLocalizationManager.Localize("$hex_dvergr_pact_cost", 2);

		internal static string AshlandsFlametalCostDisplay => HexLocalizationManager.Localize("$hex_dvergr_flametal_cost", 1);
	}
	internal static class HexDvergrAlliesConfiguration
	{
		internal static ConfigEntry<bool> EnablePlayerDamageImmunity;

		internal static ConfigEntry<bool> EnableDebugLogs;

		internal static ConfigEntry<bool> AllowTemporaryHomestead;

		internal static ConfigEntry<bool> CompanionEnableDungeonTargetFiltering;

		internal static ConfigEntry<bool> CompanionEnableDungeonFollowRecovery;

		internal static ConfigEntry<bool> CompanionEnableCombatCircling;

		internal static ConfigEntry<bool> CompanionEnableBloodMagicExperience;

		internal static ConfigEntry<bool> CompanionEnableAutoHealing;

		internal static ConfigEntry<bool> CompanionProtectSealPups;

		internal static ConfigEntry<KeyboardShortcut> CompanionInteractionShortcut;

		internal static ConfigEntry<KeyboardShortcut> CompanionSentryShortcut;

		internal static ConfigEntry<KeyboardShortcut> CompanionRecallShortcut;

		internal static ConfigEntry<float> CompanionMovementSpeedMultiplier;

		internal static ConfigEntry<float> CompanionFollowDistance;

		internal static ConfigEntry<float> CompanionTargetScanInterval;

		internal static ConfigEntry<float> CompanionDungeonFollowRecoveryDelay;

		internal static ConfigEntry<float> CompanionBloodMagicExperienceFactor;

		internal static ConfigEntry<float> CompanionHealthMultiplier;

		internal static ConfigEntry<float> CompanionDamageTakenMultiplier;

		internal static ConfigEntry<float> CompanionDamageDealtMultiplier;

		internal static ConfigEntry<float> CompanionAttackSpeedMultiplier;

		internal static ConfigEntry<float> CompanionAutoHealThreshold;

		internal static ConfigEntry<float> CompanionAutoHealCooldown;

		internal static ConfigEntry<KeyboardShortcut> CompanionUIShortcut;

		internal static void Init(ConfigFile config)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Expected O, but got Unknown
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			//IL_0350: 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_0383: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Expected O, but got Unknown
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Expected O, but got Unknown
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Expected O, but got Unknown
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Expected O, but got Unknown
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Expected O, but got Unknown
			//IL_0561: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Expected O, but got Unknown
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Expected O, but got Unknown
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_060d: Expected O, but got Unknown
			//IL_0654: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Expected O, but got Unknown
			//IL_0678: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Expected O, but got Unknown
			//IL_06ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f6: 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_07c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d2: Expected O, but got Unknown
			CompanionProtectSealPups = config.Bind<bool>("Dvergr Companion", "ProtectSealPups", true, new ConfigDescription("Prevents hired Dvergr from targeting or damaging baby seals. Adult seals and unhired Dvergr are unaffected.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3100
				}
			}));
			EnablePlayerDamageImmunity = config.Bind<bool>("General", "EnablePlayerDamageImmunity", true, new ConfigDescription("Prevents players from damaging Dvergr.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2910
				}
			}));
			AllowTemporaryHomestead = config.Bind<bool>("Dvergr Wards", "AllowTemporaryHomestead", true, new ConfigDescription("Allows players to place a workbench, stonecutter, wood portal, and stone portal inside Dvergr ward-protected areas. All other structures remain restricted.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2900
				}
			}));
			CompanionEnableDungeonFollowRecovery = config.Bind<bool>("Dvergr Companion", "EnableDungeonFollowRecovery", true, new ConfigDescription("Automatically recover a following companion separated by dungeon walls or floors. Does not affect outdoor following or Sentry mode.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3000
				}
			}));
			CompanionEnableDungeonTargetFiltering = config.Bind<bool>("Dvergr Companion", "EnableDungeonTargetFiltering", true, new ConfigDescription("In dungeons, keep an actionable enemy target and ignore enemies that cannot be reached or attacked with a clear view. Prevents chasing noises through walls and floors.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2980
				}
			}));
			CompanionEnableCombatCircling = config.Bind<bool>("Dvergr Companion", "EnableCombatCircling", false, new ConfigDescription("Allow hired Dvergr to periodically stop attacking and circle their enemy. Does not change movement during weapon cooldowns.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2970
				}
			}));
			CompanionEnableBloodMagicExperience = config.Bind<bool>("Dvergr Companion", "EnableBloodMagicExperience", true, new ConfigDescription("Hired Dvergr grant their owner Blood Magic experience when they deal health damage to a creature.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2950
				}
			}));
			CompanionEnableAutoHealing = config.Bind<bool>("Dvergr Companion", "EnableAutoHealing", true, new ConfigDescription("Automatically heals hired Dvergr companions when their health reaches the configured threshold.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2820
				}
			}));
			CompanionDungeonFollowRecoveryDelay = config.Bind<float>("Dvergr Companion", "DungeonFollowRecoveryDelay", 4f, new ConfigDescription("Seconds without progress before recovering a separated dungeon companion to a clear spot on your floor.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 840
				}
			}));
			CompanionTargetScanInterval = config.Bind<float>("Dvergr Companion", "TargetScanInterval", 1f, new ConfigDescription("Seconds between enemy scans for hired Dvergr in Companion and Sentry modes. Lower values scan more often. Does not change attack cooldowns or special delays after giving up a chase.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 880
				}
			}));
			CompanionBloodMagicExperienceFactor = config.Bind<float>("Dvergr Companion", "BloodMagicExperienceFactor", 1f, new ConfigDescription("Blood Magic skill experience factor per damaging hit. Uses normal skill progression, not whole skill levels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1090
				}
			}));
			CompanionRecallShortcut = config.Bind<KeyboardShortcut>("Dvergr Companion", "RecallShortcut", new KeyboardShortcut((KeyCode)111, Array.Empty<KeyCode>()), new ConfigDescription("Keyboard shortcut for Get over here. Recalls your hired Dvergr to your location and switches them to Companion mode.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 980
				}
			}));
			CompanionSentryShortcut = config.Bind<KeyboardShortcut>("Dvergr Companion", "SentryShortcut", new KeyboardShortcut((KeyCode)112, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), new ConfigDescription("Keyboard shortcut to toggle your hired Dvergr between Sentry and Companion mode. Sentry mode guards your current position.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 990
				}
			}));
			CompanionInteractionShortcut = config.Bind<KeyboardShortcut>("Dvergr Companion", "InteractionShortcut", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new ConfigDescription("Keyboard shortcut to forge or break a pact with a Dvergr companion.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1000
				}
			}));
			CompanionMovementSpeedMultiplier = config.Bind<float>("Dvergr Companion", "MovementSpeedMultiplier", 2.5f, new ConfigDescription("Movement speed multiplier for hired Dvergr companions.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 900
				}
			}));
			CompanionFollowDistance = config.Bind<float>("Dvergr Companion", "FollowDistance", 2f, new ConfigDescription("Distance in meters at which your companion stops following you. Does not limit combat range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 890
				}
			}));
			CompanionHealthMultiplier = config.Bind<float>("Dvergr Companion", "HealthMultiplier", 2f, new ConfigDescription("Maximum health multiplier for hired Dvergr companions.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 800
				}
			}));
			CompanionDamageTakenMultiplier = config.Bind<float>("Dvergr Companion", "DamageTakenMultiplier", 0.5f, new ConfigDescription("Incoming damage multiplier. 0.5 means 50% less damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 790
				}
			}));
			CompanionDamageDealtMultiplier = config.Bind<float>("Dvergr Companion", "DamageDealtMultiplier", 1.5f, new ConfigDescription("Outgoing damage multiplier for hired Dvergr companions. 1.5 means 50% more damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 780
				}
			}));
			CompanionAttackSpeedMultiplier = config.Bind<float>("Dvergr Companion", "AttackSpeedMultiplier", 3f, new ConfigDescription("Attack cooldown speed multiplier. 2.0 means 100% faster cooldown recovery.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 770
				}
			}));
			CompanionAutoHealThreshold = config.Bind<float>("Dvergr Companion", "AutoHealThreshold", 0.5f, new ConfigDescription("Health percentage that triggers automatic healing. 0.5 means 50% health.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 690
				}
			}));
			CompanionAutoHealCooldown = config.Bind<float>("Dvergr Companion", "AutoHealCooldown", 60f, new ConfigDescription("Minimum number of seconds between automatic heals for each companion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 680
				}
			}));
			CompanionUIShortcut = config.Bind<KeyboardShortcut>("Dvergr Companion", "UIShortcut", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), new ConfigDescription("Keyboard shortcut to open or close the Dvergr Companion Management UI.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1010
				}
			}));
			EnableDebugLogs = config.Bind<bool>("Debug", "EnableDebugLogs", false, new ConfigDescription("Enables all mod diagnostics, warnings, and errors. Plugin lifecycle and configuration messages remain independent.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2770,
					IsAdvanced = true
				}
			}));
			config.Bind<bool>("Debug", "StarterTestKill", false, new ConfigDescription("Temporary host-only test control: kill your loaded starter, bypassing pre-hire immunity.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1000,
					HideDefaultButton = true,
					CustomDrawer = delegate
					{
						if (GUILayout.Button(HexLocalizationManager.Localize("$hex_dvergr_test_kill"), Array.Empty<GUILayoutOption>()))
						{
							DvergrStarterEncounterManager.RequestTestControl(reset: false);
						}
					}
				}
			}));
			config.Bind<bool>("Debug", "StarterTestReset", false, new ConfigDescription("Temporary host-only test control: remove your starter and restore the free pact at the existing camp in this world. Keeps camp structures.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1000,
					HideDefaultButton = true,
					CustomDrawer = delegate
					{
						if (GUILayout.Button(HexLocalizationManager.Localize("$hex_dvergr_test_reset"), Array.Empty<GUILayoutOption>()))
						{
							DvergrStarterEncounterManager.RequestTestControl(reset: true);
						}
					}
				}
			}));
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

		public bool? ShowRangeAsPercent;

		public Action<ConfigEntryBase> CustomDrawer;

		public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

		public bool? Browsable;

		public string Category;

		public object DefaultValue;

		public bool? HideDefaultButton;

		public string Description;

		public string DispName;

		public int? Order;

		public bool? ReadOnly;

		public bool? IsAdvanced;

		public Func<object, string> ObjToStr;

		public Func<string, object> StrToObj;
	}
	[BepInPlugin("com.hex.dvergr.allies", "HexDvergrAllies", "0.0.3")]
	public class Plugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "com.hex.dvergr.allies";

		private const string PluginName = "HexDvergrAllies";

		private const string PluginVersion = "0.0.3";

		private Harmony _harmonyInstance;

		private FileSystemWatcher _configFileWatcher;

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private void Awake()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			AssetHelper.Initialize();
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			HexDvergrAlliesConfiguration.Init(((BaseUnityPlugin)this).Config);
			HexConfigurationMigration.Complete(((BaseUnityPlugin)this).Config);
			HexLocalizationManager.Initialize();
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			SetupConfigWatcher();
			_harmonyInstance = new Harmony("com.hex.dvergr.allies");
			_harmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
			DvergrTradeTerminalCommands.Register();
			((Component)this).gameObject.AddComponent<DvergrStarterEncounterManager>();
			Log.LogInfo((object)"HexDvergrAllies v0.0.3 loaded.");
		}

		private void SetupConfigWatcher()
		{
			_configFileWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath));
			_configFileWatcher.Changed += OnConfigFileChanged;
			_configFileWatcher.Created += OnConfigFileChanged;
			_configFileWatcher.Renamed += OnConfigFileChanged;
			_configFileWatcher.IncludeSubdirectories = true;
			_configFileWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			_configFileWatcher.EnableRaisingEvents = true;
		}

		private void OnConfigFileChanged(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				return;
			}
			try
			{
				Log.LogDebug((object)"Attempting to reload configuration...");
				((BaseUnityPlugin)this).Config.Reload();
				if (HexConfigurationMigration.Complete(((BaseUnityPlugin)this).Config))
				{
					((BaseUnityPlugin)this).Config.Save();
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"There was an issue loading {Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)}: {arg}");
			}
		}

		private void OnDestroy()
		{
			Log.LogInfo((object)"HexDvergrAllies v0.0.3 unloaded.");
			if (_configFileWatcher != null)
			{
				_configFileWatcher.EnableRaisingEvents = false;
				_configFileWatcher.Changed -= OnConfigFileChanged;
				_configFileWatcher.Created -= OnConfigFileChanged;
				_configFileWatcher.Renamed -= OnConfigFileChanged;
				_configFileWatcher.Dispose();
				_configFileWatcher = null;
			}
			((BaseUnityPlugin)this).Config.Save();
			Harmony harmonyInstance = _harmonyInstance;
			if (harmonyInstance != null)
			{
				harmonyInstance.UnpatchSelf();
			}
			_harmonyInstance = null;
			HexLocalizationManager.Shutdown();
			Instance = null;
			Log = null;
		}
	}
}
namespace HexDvergrAllies.Patches
{
	[HarmonyPatch(typeof(Attack), "AddHitPoint")]
	internal static class AttackAddHitPointPatch
	{
		private static bool Prefix(Humanoid ___m_character, GameObject go)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			if (!HexDvergrAlliesConfiguration.EnablePlayerDamageImmunity.Value)
			{
				return true;
			}
			if (!((Character)___m_character).IsPlayer())
			{
				return true;
			}
			Character component = go.GetComponent<Character>();
			if (!((Object)(object)component == (Object)null))
			{
				return (int)component.GetFaction() != 10;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class AttackAreaHitPatch
	{
		private static readonly FieldInfo CharacterField = AccessTools.Field(typeof(Attack), "m_character");

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(Attack), "<DoAreaAttack>g__checkHits|27_0", (Type[])null, (Type[])null);
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(Projectile), "FindHitObject", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(AttackAreaHitPatch), "IsProtectedDvergr", (Type[])null, (Type[])null);
			Label label = generator.DefineLabel();
			bool flag = false;
			bool flag2 = false;
			for (int i = 0; i < list.Count - 3; i++)
			{
				if (list[i].opcode == OpCodes.Ldloc_0 && list[i + 1].opcode == OpCodes.Ldc_I4_1 && list[i + 2].opcode == OpCodes.Add && list[i + 3].opcode == OpCodes.Stloc_0)
				{
					list[i].labels.Add(label);
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				throw new InvalidOperationException("AttackAreaHitPatch: Could not find area attack loop continuation.");
			}
			for (int j = 0; j < list.Count - 1; j++)
			{
				if (CodeInstructionExtensions.Calls(list[j], methodInfo) && !(list[j + 1].opcode != OpCodes.Stloc_2))
				{
					list.InsertRange(j + 2, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[4]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Ldloc_2, (object)null),
						new CodeInstruction(OpCodes.Call, (object)methodInfo2),
						new CodeInstruction(OpCodes.Brtrue, (object)label)
					});
					flag2 = true;
					break;
				}
			}
			if (!flag2)
			{
				throw new InvalidOperationException("AttackAreaHitPatch: Could not find area attack target registration.");
			}
			return list;
		}

		private static bool IsProtectedDvergr(Attack attack, GameObject target)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			if (!HexDvergrAlliesConfiguration.EnablePlayerDamageImmunity.Value)
			{
				return false;
			}
			object? value = CharacterField.GetValue(attack);
			if (!((Character)((value is Humanoid) ? value : null)).IsPlayer())
			{
				return false;
			}
			Character component = target.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				return (int)component.GetFaction() == 10;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Aoe), "Initiate")]
	internal static class AoeCompanionShieldPatch
	{
		private static readonly int ShieldHash = StringExtensionMethods.GetStableHashCode("Staff_shield");

		private static readonly FieldRef<Aoe, Character> OwnerField = AccessTools.FieldRefAccess<Aoe, Character>("m_owner");

		private static readonly FieldRef<Aoe, int> LevelField = AccessTools.FieldRefAccess<Aoe, int>("m_level");

		private static void Postfix(Aoe __instance)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)((Component)__instance).gameObject).name.Replace("(Clone)", "").Trim() != "staff_shield_aoe")
			{
				return;
			}
			Character obj = OwnerField.Invoke(__instance);
			Player val = (Player)(object)((obj is Player) ? obj : null);
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer || !DvergrCompanionManager.TryGetHiredCompanionId(val, out var companionId))
			{
				return;
			}
			GameObject val2 = ZNetScene.instance.FindInstance(companionId);
			if (Object.op_Implicit((Object)(object)val2))
			{
				Character component = val2.GetComponent<Character>();
				if (DvergrCompanionManager.IsHiredByPlayer(component, val) && !component.IsDead())
				{
					int num = LevelField.Invoke(__instance);
					float skillLevel = ((Character)val).GetSkillLevel(__instance.m_skill);
					component.GetSEMan().AddStatusEffect(ShieldHash, true, num, skillLevel, (short)(-1));
				}
			}
		}
	}
	[HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[]
	{
		typeof(Character),
		typeof(Character)
	})]
	internal static class BaseAICompanionBossTargetPatch
	{
		private static void Postfix(Character a, Character b, ref bool __result)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			if (!__result && !((Object)(object)a == (Object)null) && !((Object)(object)b == (Object)null) && !((Object)(object)a == (Object)(object)b) && (int)a.GetFaction() == 10 && (int)b.GetFaction() == 8 && DvergrCompanionState.IsHired(a) && !b.IsDead() && !b.m_aiSkipTarget)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch]
	internal static class BaseAICompanionCombatLeashPatch
	{
		private const float CompanionLeashDistance = 15f;

		private const float BoundaryBuffer = 0.5f;

		private const float LogInterval = 2f;

		private static readonly Dictionary<MonsterAI, float> NextBlockedLogTimes = new Dictionary<MonsterAI, float>();

		[HarmonyPatch(typeof(BaseAI), "MoveTowards")]
		[HarmonyPrefix]
		private static void MoveTowardsPrefix(BaseAI __instance, ref Vector3 dir)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			MonsterAI val = (MonsterAI)(object)((__instance is MonsterAI) ? __instance : null);
			if (!TryGetCompanion(val, out var character, out var owner))
			{
				return;
			}
			bool flag = DvergrCompanionSentryMode.IsActive(character);
			if (!flag && (Object)(object)((BaseAI)val).GetTargetCreature() == (Object)null && (Object)(object)val.GetStaticTarget() == (Object)null)
			{
				return;
			}
			float num = (flag ? 20f : 15f);
			Vector3 val2 = (flag ? DvergrCompanionSentryMode.GetAnchor(character) : owner.position);
			Vector3 val3 = ((Component)character).transform.position - val2;
			val3.y = 0f;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if (magnitude < num - 0.5f)
			{
				return;
			}
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(dir.x, 0f, dir.z);
			float num2 = Vector3.Dot(val4, normalized);
			if (!(num2 <= 0f))
			{
				Vector3 val5 = dir;
				val4 -= normalized * num2;
				dir = new Vector3(val4.x, dir.y, val4.z);
				if (HexDvergrAlliesConfiguration.EnableDebugLogs.Value && ShouldLog(NextBlockedLogTimes, val))
				{
					Character targetCreature = ((BaseAI)val).GetTargetCreature();
					float num3 = (Object.op_Implicit((Object)(object)targetCreature) ? Vector3.Distance(((Component)character).transform.position, ((Component)targetCreature).transform.position) : (-1f));
					HexLog.LogInfo("[Dvergr Companion] Combat leash movement blocked: Dvergr=" + ((Object)character).name + ", " + $"OwnerDistance={magnitude:F1}, " + $"LeashDistance={num:F1}, " + "Target=" + GetTargetName(targetCreature) + ", " + $"TargetDistance={num3:F1}, " + $"OutwardMovement={num2:F2}, " + $"OriginalDirection={val5}, " + $"AdjustedDirection={dir}");
				}
			}
		}

		[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
		[HarmonyPostfix]
		private static void UpdateAIPostfix(MonsterAI __instance)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetCompanion(__instance, out var character, out var owner))
			{
				return;
			}
			bool flag = DvergrCompanionSentryMode.IsActive(character);
			if (flag || !((Object)(object)((BaseAI)__instance).GetTargetCreature() == (Object)null) || !((Object)(object)__instance.GetStaticTarget() == (Object)null))
			{
				float num = (flag ? 20f : 15f);
				Vector3 val = (flag ? DvergrCompanionSentryMode.GetAnchor(character) : owner.position) - ((Component)character).transform.position;
				val.y = 0f;
				if (!(((Vector3)(ref val)).magnitude <= num))
				{
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					((BaseAI)__instance).MoveTowards(normalized, true);
				}
			}
		}

		private static bool ShouldLog(Dictionary<MonsterAI, float> nextLogTimes, MonsterAI monsterAI)
		{
			if (nextLogTimes.TryGetValue(monsterAI, out var value) && Time.time < value)
			{
				return false;
			}
			nextLogTimes[monsterAI] = Time.time + 2f;
			return true;
		}

		private static string GetTargetName(Character target)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				return "None";
			}
			return ((Object)target).name;
		}

		private static bool TryGetCompanion(MonsterAI monsterAI, out Character character, out Transform owner)
		{
			character = null;
			owner = null;
			if (!Object.op_Implicit((Object)(object)monsterAI))
			{
				return false;
			}
			character = ((Component)monsterAI).GetComponent<Character>();
			if (!Object.op_Implicit((Object)(object)character) || !DvergrCompanionState.IsHired(character))
			{
				return false;
			}
			ZNetView component = ((Component)character).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner())
			{
				return false;
			}
			if (DvergrCompanionSentryMode.IsActive(character))
			{
				owner = ((Component)character).transform;
				return true;
			}
			GameObject followTarget = monsterAI.GetFollowTarget();
			if (!Object.op_Implicit((Object)(object)followTarget))
			{
				return false;
			}
			owner = followTarget.transform;
			return true;
		}
	}
	[HarmonyPatch(typeof(BaseAI), "FindEnemy")]
	internal static class BaseAICompanionFindEnemyPatch
	{
		private static void Postfix(BaseAI __instance, ref Character __result)
		{
			MonsterAI val = (MonsterAI)(object)((__instance is MonsterAI) ? __instance : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				Character component = ((Component)val).GetComponent<Character>();
				__result = DvergrCompanionDungeonTargeting.SelectTarget(val, __result);
				if (DvergrCompanionSentryMode.IsActive(component) && Object.op_Implicit((Object)(object)__result) && !DvergrCompanionSentryMode.IsWithinCombatRadius(component, __result))
				{
					__result = null;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class CharacterCompanionDamageImmunityPatch
	{
		private static bool Prefix(Character __instance, HitData hit)
		{
			if (DvergrFriendlyFireRules.ShouldBlockDamage(__instance, hit) || DvergrStarterCharacterState.IsProtected(__instance))
			{
				return false;
			}
			DvergrCompanionComponent dvergrCompanionComponent = default(DvergrCompanionComponent);
			if (!((Component)__instance).TryGetComponent<DvergrCompanionComponent>(ref dvergrCompanionComponent))
			{
				return true;
			}
			return dvergrCompanionComponent.ProcessDamage(hit);
		}
	}
	[HarmonyPatch(typeof(Character), "OnDestroy")]
	internal static class CharacterCompanionCleanupPatch
	{
		private static void Prefix(Character __instance)
		{
			DvergrCompanionBehaviorManager.RemoveCharacter(__instance);
			DvergrCompanionShipManager.RemoveCharacter(__instance);
			DvergrCompanionDungeonTargeting.RemoveCharacter(__instance);
			DvergrCompanionDungeonFollowManager.RemoveCharacter(__instance);
			DvergrCompanionFollowManager.RemoveCharacter(__instance);
			MonsterAI component = ((Component)__instance).GetComponent<MonsterAI>();
			if (component != null)
			{
				DvergrCompanionSpawnerTargeting.RemoveCharacter(component);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "CustomFixedUpdate")]
	internal static class CharacterCompanionCollisionPatch
	{
		private static readonly Dictionary<Character, bool> _collisionStates = new Dictionary<Character, bool>();

		private static CapsuleCollider _playerCollider;

		private static void Postfix(Character __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || (Object)(object)__instance == (Object)(object)localPlayer || (int)__instance.GetFaction() != 10)
			{
				return;
			}
			CapsuleCollider component = ((Component)localPlayer).GetComponent<CapsuleCollider>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			if ((Object)(object)_playerCollider != (Object)(object)component)
			{
				_collisionStates.Clear();
				_playerCollider = component;
			}
			bool flag = DvergrCompanionState.IsHired(__instance);
			if (!_collisionStates.TryGetValue(__instance, out var value) || value != flag)
			{
				CapsuleCollider component2 = ((Component)__instance).GetComponent<CapsuleCollider>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					Physics.IgnoreCollision((Collider)(object)component, (Collider)(object)component2, flag);
					_collisionStates[__instance] = flag;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "GetDamageModifiers")]
	internal static class CharacterCompanionDamageModifiersPatch
	{
		private static void Postfix(Character __instance, ref DamageModifiers __result)
		{
			DvergrCompanionComponent dvergrCompanionComponent = default(DvergrCompanionComponent);
			if (((Component)__instance).TryGetComponent<DvergrCompanionComponent>(ref dvergrCompanionComponent))
			{
				dvergrCompanionComponent.ApplyDamageModifiers(ref __result);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "OnDeath")]
	internal static class CharacterCompanionDeathPatch
	{
		private static void Prefix(Character __instance)
		{
			DvergrStarterRevivalManager.OnDeath(__instance);
			DvergrStarterEncounterManager.OnCharacterDeath(__instance);
			DvergrCompanionManager.OnCompanionDeath(__instance);
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class CharacterCompanionOwnerDefensePatch
	{
		private const float MaximumDefenseDistance = 30f;

		private static readonly Action<BaseAI, bool> SetAlertedMethod = AccessTools.MethodDelegate<Action<BaseAI, bool>>(AccessTools.Method(typeof(BaseAI), "SetAlerted", new Type[1] { typeof(bool) }, (Type[])null), (object)null, true);

		private static readonly Action<MonsterAI, Character> SetTargetMethod = AccessTools.MethodDelegate<Action<MonsterAI, Character>>(AccessTools.Method(typeof(MonsterAI), "SetTarget", new Type[1] { typeof(Character) }, (Type[])null), (object)null, true);

		private static void Postfix(Character __instance, HitData hit)
		{
			//IL_00e8: 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)
			if ((Object)(object)__instance == (Object)null || !__instance.IsPlayer() || hit == null)
			{
				return;
			}
			Character attacker = hit.GetAttacker();
			if ((Object)(object)attacker == (Object)null || (Object)(object)attacker == (Object)(object)__instance || attacker.IsDead() || attacker.IsPlayer())
			{
				return;
			}
			MonsterAI[] array = Object.FindObjectsByType<MonsterAI>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			foreach (MonsterAI val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Character component = ((Component)val).GetComponent<Character>();
				if ((Object)(object)component == (Object)null || !DvergrCompanionState.IsHired(component) || component.IsDead())
				{
					continue;
				}
				ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
				if ((Object)(object)component2 == (Object)null || !component2.IsValid() || !component2.IsOwner())
				{
					continue;
				}
				GameObject followTarget = val.GetFollowTarget();
				if ((Object)(object)followTarget == (Object)null || (Object)(object)followTarget != (Object)(object)((Component)__instance).gameObject)
				{
					continue;
				}
				float num = Vector3.Distance(((Component)component).transform.position, ((Component)__instance).transform.position);
				if (num > 30f)
				{
					continue;
				}
				Character targetCreature = ((BaseAI)val).GetTargetCreature();
				if (!((Object)(object)targetCreature != (Object)null) || targetCreature.IsDead())
				{
					SetTargetMethod(val, attacker);
					SetAlertedMethod((BaseAI)(object)val, arg2: true);
					if (HexDvergrAlliesConfiguration.EnableDebugLogs.Value)
					{
						string[] obj = new string[10]
						{
							"[Dvergr Companion] Owner defense triggered: Dvergr=",
							((Object)component).name,
							", Owner=",
							((Object)__instance).name,
							", Attacker=",
							((Object)attacker).name,
							", ",
							$"Distance={num:F1}, ",
							"CombatTarget=",
							null
						};
						Character targetCreature2 = ((BaseAI)val).GetTargetCreature();
						obj[9] = ((targetCreature2 != null) ? ((Object)targetCreature2).name : null) ?? "None";
						HexLog.LogInfo(string.Concat(obj));
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "GetHoverName")]
	internal static class DvergrCompanionHoverNamePatch
	{
		private static void Postfix(Character __instance, ref string __result)
		{
			if (DvergrCompanionState.IsHired(__instance))
			{
				__result = DvergrCompanionNameManager.GetCompanionName(__instance);
			}
			__result = DvergrStarterProgressionService.AppendLevel(__instance, __result);
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	internal static class MonsterAIAttackSpeedPatch
	{
		private static readonly FieldInfo AttackIntervalField = AccessTools.Field(typeof(SharedData), "m_aiAttackInterval");

		private static readonly MethodInfo AdjustAttackIntervalMethod = AccessTools.Method(typeof(MonsterAIAttackSpeedPatch), "AdjustAttackInterval", (Type[])null, (Type[])null);

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = 0;
			if (AttackIntervalField == null || AdjustAttackIntervalMethod == null)
			{
				throw new InvalidOperationException("Unable to resolve MonsterAI attack-speed patch members.");
			}
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode != OpCodes.Ldfld) && object.Equals(list[i].operand, AttackIntervalField))
				{
					list.Insert(i + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null));
					list.Insert(i + 2, new CodeInstruction(OpCodes.Call, (object)AdjustAttackIntervalMethod));
					num++;
					i += 2;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException($"Expected one MonsterAI weapon attack interval read, found {num}.");
			}
			return list;
		}

		private static float AdjustAttackInterval(float originalInterval, MonsterAI monsterAI)
		{
			Character component = ((Component)monsterAI).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || !DvergrCompanionState.IsHired(component))
			{
				return originalInterval;
			}
			float value = HexDvergrAlliesConfiguration.CompanionAttackSpeedMultiplier.Value;
			if (value <= 0f)
			{
				return originalInterval;
			}
			return originalInterval / value;
		}
	}
	[HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[]
	{
		typeof(StatusEffect),
		typeof(bool),
		typeof(int),
		typeof(float),
		typeof(short)
	})]
	internal static class SEManCompanionDirectStatusEffectPatch
	{
		private static bool Prefix(SEMan __instance, StatusEffect statusEffect, ref StatusEffect __result)
		{
			Character value = Traverse.Create((object)__instance).Field<Character>("m_character").Value;
			DvergrCompanionComponent dvergrCompanionComponent = default(DvergrCompanionComponent);
			if (Object.op_Implicit((Object)(object)value) && ((Component)value).TryGetComponent<DvergrCompanionComponent>(ref dvergrCompanionComponent) && !dvergrCompanionComponent.CanApplyStatusEffect(statusEffect))
			{
				__result = null;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SEMan), "Internal_AddStatusEffect")]
	internal static class SEManCompanionStatusEffectPatch
	{
		private static bool Prefix(SEMan __instance, int nameHash)
		{
			Character value = Traverse.Create((object)__instance).Field<Character>("m_character").Value;
			DvergrCompanionComponent dvergrCompanionComponent = default(DvergrCompanionComponent);
			if (Object.op_Implicit((Object)(object)value) && ((Component)value).TryGetComponent<DvergrCompanionComponent>(ref dvergrCompanionComponent))
			{
				return dvergrCompanionComponent.CanApplyStatusEffect(nameHash);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TeleportWorld), "Interact")]
	internal static class TeleportWorldInteractPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(TeleportWorld __instance, Humanoid human, bool hold, ref bool __result)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (hold || !HexDvergrAlliesConfiguration.AllowTemporaryHomestead.Value)
			{
				return true;
			}
			Vector3 position = ((Component)__instance).transform.position;
			if (PrivateArea.CheckAccess(position, 0f, false, false))
			{
				return true;
			}
			if (!PrivateArea.InsideFactionArea(position, (Faction)10))
			{
				return true;
			}
			string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject);
			if (!PrefabHelper.AllowedHomesteadPieces.Contains(prefabName))
			{
				return true;
			}
			if ((Object)(object)TextInput.instance == (Object)null)
			{
				return true;
			}
			TextInput.instance.RequestText((TextReceiver)(object)__instance, "$piece_portal_tag", 10);
			__result = true;
			if (HexDvergrAlliesConfiguration.EnableDebugLogs.Value)
			{
				HexLog.LogInfo($"[Dvergr Homestead] Portal interaction allowed: Portal={prefabName}, Position={position}");
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetSceneCompanionSessionPatch
	{
		private static void Prefix()
		{
			DvergrCompanionManager.ResetSessionState();
		}
	}
	[HarmonyPatch(typeof(BaseAI), "IdleMovement")]
	internal static class BaseAIIdleMovementPatch
	{
		private static bool Prefix(BaseAI __instance)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsOwner())
			{
				return true;
			}
			if (!DvergrTradeSessionManager.IsTrading(component.GetZDO().m_uid))
			{
				return true;
			}
			__instance.StopMoving();
			return false;
		}
	}
	[HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[]
	{
		typeof(Character),
		typeof(Character)
	})]
	internal static class BaseAIIsEnemyPatch
	{
		private static bool Prefix(Character a, Character b, ref bool __result)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			if (DvergrFriendlyFireRules.AreAllies(a, b))
			{
				__result = false;
				return false;
			}
			if ((Object)(object)a == (Object)null || (Object)(object)b == (Object)null)
			{
				return true;
			}
			if (((int)a.GetFaction() != 10 || !b.IsPlayer()) && ((int)b.GetFaction() != 10 || !a.IsPlayer()))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class CharacterAwakePatch
	{
		private static void Postfix(Character __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)__instance.GetFaction() == 10)
			{
				MonsterAI component = ((Component)__instance).GetComponent<MonsterAI>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_attackPlayerObjects = false;
				}
				Humanoid val = (Humanoid)(object)((__instance is Humanoid) ? __instance : null);
				if (val != null)
				{
					DvergrTraderManager.Initialize(val);
				}
				DvergrCompanionManager.Initialize(__instance);
				SE_DvergrAlly sE_DvergrAlly = ScriptableObject.CreateInstance<SE_DvergrAlly>();
				((Object)sE_DvergrAlly).name = "SE_DvergrAlly";
				__instance.GetSEMan().AddStatusEffect((StatusEffect)(object)sE_DvergrAlly, false, 0, 0f, (short)(-1));
				Object.Destroy((Object)(object)sE_DvergrAlly);
				if (HexDvergrAlliesConfiguration.EnableDebugLogs.Value)
				{
					HexLog.LogInfo("[Dvergr Init] Name=" + ((Object)__instance).name + ", " + $"AttackPlayerObjects={component?.m_attackPlayerObjects}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Update")]
	internal static class DvergrTradeQueueUpdatePatch
	{
		private static void Postfix()
		{
			DvergrTradeRpcManager.Update();
			DvergrTradeSessionManager.Update();
		}
	}
	[HarmonyPatch(typeof(Character), "GetHoverText")]
	internal static class CharacterHoverTextPatch
	{
		private static bool Prefix(Character __instance, ref string __result)
		{
			return DvergrHoverTextManager.Init(__instance, out __result);
		}
	}
	[HarmonyPatch(typeof(Trader), "Update")]
	internal static class DvergrTraderUpdatePatch
	{
		private static bool Prefix(Trader __instance)
		{
			return !DvergrTraderManager.IsDvergrTrader(__instance);
		}
	}
	[HarmonyPatch(typeof(MineRock5), "RPC_Damage")]
	internal static class MineRock5RPCDamagePatch
	{
		private static readonly Func<PrivateArea, bool> IsAreaEnabled = AccessTools.MethodDelegate<Func<PrivateArea, bool>>(AccessTools.Method(typeof(PrivateArea), "IsEnabled", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<PrivateArea, Vector3, float, bool> IsInsideArea = AccessTools.MethodDelegate<Func<PrivateArea, Vector3, float, bool>>(AccessTools.Method(typeof(PrivateArea), "IsInside", (Type[])null, (Type[])null), (object)null, true);

		private static ref List<PrivateArea> AllAreas => ref AccessTools.StaticFieldRefAccess<List<PrivateArea>>(typeof(PrivateArea), "m_allAreas");

		private static void Prefix(MineRock5 __instance, HitData hit, out bool __state)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Invalid comparison between Unknown and I4
			__state = false;
			if (!__instance.m_triggerPrivateArea || __instance.m_name != "$piece_giant_bone" || !(hit.GetAttacker() is Player))
			{
				return;
			}
			foreach (PrivateArea allArea in AllAreas)
			{
				if (IsAreaEnabled(allArea) && IsInsideArea(allArea, ((Component)__instance).transform.position, 0f))
				{
					if ((int)allArea.m_ownerFaction == 10)
					{
						__instance.m_triggerPrivateArea = false;
						__state = true;
					}
					break;
				}
			}
		}

		private static Exception Finalizer(MineRock5 __instance, bool __state, Exception __exception)
		{
			if (__state)
			{
				__instance.m_triggerPrivateArea = true;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	internal static class MonsterAICompanionFollowPatch
	{
		private static void Prefix(MonsterAI __instance)
		{
			Character component = ((Component)__instance).GetComponent<Character>();
			if (Object.op_Implicit((Object)(object)component) && !DvergrCompanionShipManager.IsPassenger(component))
			{
				DvergrCompanionFollowManager.UpdateFollow(__instance);
				DvergrCompanionBehaviorManager.UpdateCombatLeash(__instance);
			}
		}

		private static void Postfix(MonsterAI __instance)
		{
			DvergrCompanionSpawnerTargeting.Update(__instance);
			DvergrCompanionSentryMode.Update(__instance);
		}
	}
	[HarmonyPatch(typeof(BaseAI), "Follow")]
	internal static class BaseAICompanionFollowDistancePatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			int replacements = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldc_R4 && (float)instruction.operand == 3f)
				{
					replacements++;
					instruction.opcode = OpCodes.Ldarg_0;
					instruction.operand = null;
					yield return instruction;
					yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(BaseAICompanionFollowDistancePatch), "GetFollowDistance", (Type[])null, (Type[])null));
				}
				else
				{
					yield return instruction;
				}
			}
			if (replacements != 1)
			{
				throw new InvalidOperationException("BaseAICompanionFollowDistancePatch: Expected one vanilla follow stopping distance.");
			}
		}

		private static float GetFollowDistance(BaseAI baseAI)
		{
			Character component = ((Component)baseAI).GetComponent<Character>();
			if (!Object.op_Implicit((Object)(object)component) || !DvergrCompanionState.IsHired(component))
			{
				return 3f;
			}
			return HexDvergrAlliesConfiguration.CompanionFollowDistance.Value;
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
	internal static class GameCameraCompanionCursorPatch
	{
		private static bool Prefix()
		{
			if (!DvergrCompanionUIController.IsVisible)
			{
				return true;
			}
			ZCursor.LockState = (CursorLockMode)0;
			ZCursor.Show();
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "TakeInput")]
	internal static class PlayerCompanionInputPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref bool __result)
		{
			if (DvergrCompanionUIController.IsVisible)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	internal static class PlayerCompanionShortcutPatch
	{
		private static void Postfix(Player __instance)
		{
			DvergrCompanionShortcutManager.Update(__instance);
		}
	}
	[HarmonyPatch(typeof(Player), "Interact")]
	internal static class PlayerInteractPatch
	{
		internal static void HandleCompanionInteraction(Player player, Character character)
		{
			if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)character) && DvergrCompanionManager.IsHiredByPlayer(character, player))
			{
				DvergrPactDialogController.ShowBreakPactConfirmation(player, character);
			}
		}

		private static bool Prefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (hold || !Object.op_Implicit((Object)(object)go))
			{
				return true;
			}
			Trader componentInParent = go.GetComponentInParent<Trader>();
			if (!Object.op_Implicit((Object)(object)componentInParent) || !DvergrTraderManager.IsDvergrTrader(componentInParent))
			{
				return true;
			}
			Character component = ((Component)componentInParent).GetComponent<Character>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return false;
			}
			if (Vector3.Distance(((Component)__instance).transform.position, ((Component)componentInParent).transform.position) > 2f)
			{
				return false;
			}
			KeyboardShortcut value = HexDvergrAlliesConfiguration.CompanionInteractionShortcut.Value;
			if (((KeyboardShortcut)(ref value)).IsPressed())
			{
				return false;
			}
			if (alt)
			{
				return false;
			}
			if (DvergrCompanionState.IsHired(component))
			{
				return false;
			}
			DvergrTradeSessionManager.RequestOpen(componentInParent);
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "RemovePiece")]
	internal static class PlayerRemovePiecePatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo original = AccessTools.Method(typeof(PrivateArea), "CheckAccess", (Type[])null, (Type[])null);
			MethodInfo replacement = AccessTools.Method(typeof(PlayerRemovePiecePatch), "CheckRemovalAccess", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, original))
				{
					yield return new CodeInstruction(OpCodes.Ldloc_1, (object)null);
					instruction.opcode = OpCodes.Call;
					instruction.operand = replacement;
				}
				yield return instruction;
			}
		}

		private static bool CheckRemovalAccess(Vector3 point, float radius, bool flash, bool wardCheck, Piece piece)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (PrivateArea.CheckAccess(point, radius, flash, wardCheck))
			{
				return true;
			}
			if (!HexDvergrAlliesConfiguration.AllowTemporaryHomestead.Value)
			{
				return false;
			}
			string prefabName = Utils.GetPrefabName(((Component)piece).gameObject);
			if (!PrefabHelper.AllowedHomesteadPieces.Contains(prefabName))
			{
				return false;
			}
			return PrivateArea.InsideFactionArea(point, (Faction)10);
		}
	}
	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	internal static class PlayerUpdatePlacementGhostPatch
	{
		private static readonly FieldRef<Player, PieceTable> BuildPieces = AccessTools.FieldRefAccess<Player, PieceTable>("m_buildPieces");

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo original = AccessTools.Method(typeof(PrivateArea), "CheckAccess", (Type[])null, (Type[])null);
			MethodInfo replacement = AccessTools.Method(typeof(PlayerUpdatePlacementGhostPatch), "CheckPlacementAccess", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, original))
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = replacement;
				}
				yield return instruction;
			}
		}

		private static bool CheckPlacementAccess(Vector3 point, float radius, bool flash, bool wardCheck)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (PrivateArea.CheckAccess(point, radius, flash, wardCheck))
			{
				return true;
			}
			if (!HexDvergrAlliesConfiguration.AllowTemporaryHomestead.Value)
			{
				return false;
			}
			GameObject selectedPrefab = BuildPieces.Invoke(Player.m_localPlayer).GetSelectedPrefab();
			if (!PrefabHelper.AllowedHomesteadPieces.Contains(((Object)selectedPrefab).name))
			{
				return false;
			}
			return PrivateArea.InsideFactionArea(point, (Faction)10);
		}
	}
	[HarmonyPatch(typeof(Projectile), "DoAOE")]
	internal static class ProjectileDoAOEPatch
	{
		private static readonly FieldInfo OwnerField = AccessTools.Field(typeof(Projectile), "m_owner");

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Expected O, but got Unknown
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(Projectile), "FindHitObject", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ProjectileDoAOEPatch), "IsProtectedDvergr", (Type[])null, (Type[])null);
			int num = -1;
			int num2 = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], methodInfo) && CodeInstructionExtensions.IsStloc(list[i + 1], (LocalBuilder)null))
				{
					num = i + 1;
					break;
				}
			}
			if (num == -1)
			{
				throw new InvalidOperationException("ProjectileDoAOEPatch: Could not find AOE target.");
			}
			for (int num3 = list.Count - 4; num3 > num; num3--)
			{
				if (CodeInstructionExtensions.IsLdloc(list[num3], (LocalBuilder)null) && !(list[num3 + 1].opcode != OpCodes.Ldc_I4_1) && !(list[num3 + 2].opcode != OpCodes.Add) && CodeInstructionExtensions.IsStloc(list[num3 + 3], (LocalBuilder)null))
				{
					num2 = num3;
					break;
				}
			}
			if (num2 == -1)
			{
				throw new InvalidOperationException("ProjectileDoAOEPatch: Could not find AOE loop continuation.");
			}
			Label label = generator.DefineLabel();
			list[num2].labels.Add(label);
			CodeInstruction val = list[num];
			CodeInstruction val2 = ((val.opcode == OpCodes.Stloc_0) ? new CodeInstruction(OpCodes.Ldloc_0, (object)null) : ((val.opcode == OpCodes.Stloc_1) ? new CodeInstruction(OpCodes.Ldloc_1, (object)null) : ((val.opcode == OpCodes.Stloc_2) ? new CodeInstruction(OpCodes.Ldloc_2, (object)null) : ((!(val.opcode == OpCodes.Stloc_3)) ? new CodeInstruction(OpCodes.Ldloc, val.operand) : new CodeInstruction(OpCodes.Ldloc_3, (object)null)))));
			list.InsertRange(num + 1, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[4]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				val2,
				new CodeInstruction(OpCodes.Call, (object)methodInfo2),
				new CodeInstruction(OpCodes.Brtrue, (object)label)
			});
			return list;
		}

		private static bool IsProtectedDvergr(Projectile projectile, GameObject target)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			if (!HexDvergrAlliesConfiguration.EnablePlayerDamageImmunity.Value)
			{
				return false;
			}
			object? value = OwnerField.GetValue(projectile);
			Character val = (Character)((value is Character) ? value : null);
			if ((Object)(object)val == (Object)null || !val.IsPlayer())
			{
				return false;
			}
			Character component = target.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				return (int)component.GetFaction() == 10;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Projectile), "IsValidTarget")]
	internal static class ProjectileIsValidTargetPatch
	{
		private static bool Prefix(IDestructible destr, Character ___m_owner, ref bool __result)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			if (!HexDvergrAlliesConfiguration.EnablePlayerDamageImmunity.Value)
			{
				return true;
			}
			if ((Object)(object)___m_owner == (Object)null || !___m_owner.IsPlayer())
			{
				return true;
			}
			Character val = (Character)(object)((destr is Character) ? destr : null);
			if ((Object)(object)val == (Object)null || (int)val.GetFaction() != 10)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(StoreGui), "BuySelectedItem")]
	internal static class StoreGuiBuySelectedItemPatch
	{
		private static bool Prefix(StoreGui __instance, Trader ___m_trader, TradeItem ___m_selectedItem)
		{
			return DvergrTradePurchaseController.OnBuySelectedItem(__instance, ___m_trader, ___m_selectedItem);
		}
	}
	[HarmonyPatch(typeof(StoreGui), "CanAfford")]
	internal static class StoreGuiCanAffordPatch
	{
		private static void Postfix(Trader ___m_trader, TradeItem __0, ref bool __result)
		{
			DvergrTradeAffordability.Apply(___m_trader, __0, ref __result);
		}
	}
	[HarmonyPatch]
	internal static class StoreGuiDvergrDisplayPatch
	{
		[HarmonyPatch(typeof(StoreGui), "FillList")]
		[HarmonyPostfix]
		private static void FillListPostfix(StoreGui __instance)
		{
			DvergrTraderDisplayManager.OnFillList(__instance);
		}

		[HarmonyPatch(typeof(StoreGui), "Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(StoreGui __instance)
		{
			DvergrTraderDisplayManager.OnUpdate(__instance);
		}
	}
	[HarmonyPatch(typeof(StoreGui), "Update")]
	internal static class StoreGuiDvergrTransactionPatch
	{
		private static void Postfix(StoreGui __instance, Trader ___m_trader)
		{
			if (__instance.m_rootPanel.activeSelf && Object.op_Implicit((Object)(object)___m_trader) && DvergrTraderManager.IsDvergrTrader(___m_trader) && DvergrTradeTransaction.IsPending)
			{
				((Selectable)__instance.m_buyButton).interactable = false;
			}
		}
	}
	[HarmonyPatch(typeof(StoreGui), "UpdateBuyButton")]
	internal static class StoreGuiForgePactBuyButtonPatch
	{
		private static void Postfix(StoreGui __instance, Trader ___m_trader, TradeItem ___m_selectedItem)
		{
			if (Object.op_Implicit((Object)(object)___m_trader) && DvergrTraderManager.IsDvergrTrader(___m_trader) && ___m_selectedItem != null && DvergrTraderManager.IsForgePact(___m_selectedItem))
			{
				Player localPlayer = Player.m_localPlayer;
				Character component = ((Component)___m_trader).GetComponent<Character>();
				bool flag = DvergrCompanionManager.HasHiredCompanion(localPlayer);
				bool flag2 = DvergrTraderManager.CanAffordForgePact(localPlayer, component);
				((Selectable)__instance.m_buyButton).interactable = flag2;
				((Component)__instance.m_buyButton).GetComponent<UITooltip>().m_text = (flag ? Localization.instance.Localize("$hex_dvergr_one_companion_only") : (flag2 ? "" : Localization.instance.Localize("$msg_missingrequirement")));
			}
		}
	}
	[HarmonyPatch(typeof(StoreGui), "Hide")]
	internal static class StoreGuiTradeSessionPatch
	{
		private static void Prefix(Trader ___m_trader)
		{
			if (Object.op_Implicit((Object)(object)___m_trader) && DvergrTraderManager.IsDvergrTrader(___m_trader))
			{
				DvergrTradeSessionManager.Close();
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "RPC_Damage")]
	internal static class WearNTearRPCDamagePatch
	{
		private static bool Prefix(WearNTear __instance, HitData hit)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!HexDvergrAlliesConfiguration.EnablePlayerDamageImmunity.Value)
			{
				return true;
			}
			Character attacker = hit.GetAttacker();
			if ((Object)(object)attacker == (Object)null || !attacker.IsPlayer())
			{
				return true;
			}
			return !PrivateArea.InsideFactionArea(((Component)__instance).transform.position, (Faction)10);
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class ZRoutedRpcRegistrationPatch
	{
		private static void Postfix()
		{
			DvergrTradeRpcManager.Initialize();
			DvergrTradeSessionManager.Register();
			DvergrCompanionPortalRelocationManager.Register();
			DvergrRpcManager.RegisterRoutedRpcs();
		}
	}
	[HarmonyPatch(typeof(PlayerController), "TakeInput")]
	internal static class PlayerControllerCompanionUIPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref bool __result)
		{
			if (DvergrCompanionUIController.IsVisible)
			{
				DvergrCompanionUIController.Update();
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	internal static class StarterRevivalLootPatch
	{
		private static bool Prefix(CharacterDrop __instance, ref List<KeyValuePair<GameObject, int>> __result)
		{
			if (!DvergrStarterRevivalManager.SuppressDeathLoot((Component)(object)__instance))
			{
				return true;
			}
			__result = new List<KeyValuePair<GameObject, int>>();
			return false;
		}
	}
	[HarmonyPatch(typeof(TombStone), "UpdateDespawn")]
	internal static class StarterTombstoneUpdatePatch
	{
		private static bool Prefix(TombStone __instance)
		{
			return DvergrStarterRevivalManager.UpdateTombstone(__instance);
		}
	}
	[HarmonyPatch(typeof(TombStone), "GetHoverText")]
	internal static class StarterTombstoneHoverPatch
	{
		private static bool Prefix(TombStone __instance, ref string __result)
		{
			if (!DvergrStarterRevivalManager.IsTombstone((Component)(object)__instance))
			{
				return true;
			}
			__result = DvergrStarterRevivalManager.HoverText(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(TombStone), "Interact")]
	internal static class StarterTombstoneInteractPatch
	{
		private static bool Prefix(TombStone __instance, Humanoid __0, bool __1, ref bool __result)
		{
			if (!DvergrStarterRevivalManager.IsTombstone((Component)(object)__instance))
			{
				return true;
			}
			DvergrStarterRevivalManager.Interact(__instance, __0, __1);
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(Container), "TakeAll")]
	internal static class StarterTombstoneTakeAllPatch
	{
		private static bool Prefix(Container __instance, ref bool __result)
		{
			return StarterTombstoneContainerPatch.Prefix(__instance, ref __result);
		}
	}
	[HarmonyPatch(typeof(Container), "Interact")]
	internal static class StarterTombstoneContainerPatch
	{
		internal static bool Prefix(Container __instance, ref bool __result)
		{
			if (!DvergrStarterRevivalManager.IsTombstone((Component)(object)__instance))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class StoreGuiStarterVendorPatch
	{
		[HarmonyPatch(typeof(StoreGui), "Show")]
		[HarmonyPrefix]
		private static void ShowPrefix(Trader __0)
		{
			DvergrStarterVendorService.OnShow(__0);
		}

		[HarmonyPatch(typeof(StoreGui), "SellItem")]
		[HarmonyPrefix]
		private static bool SellPrefix(Trader ___m_trader)
		{
			return DvergrStarterVendorService.CanSell(___m_trader);
		}

		[HarmonyPatch(typeof(StoreGui), "UpdateSellButton")]
		[HarmonyPostfix]
		private static void SellButtonPostfix(StoreGui __instance, Trader ___m_trader)
		{
			DvergrStarterVendorService.UpdateSellButton(__instance, ___m_trader);
		}
	}
	[HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")]
	internal static class TextsDialogDvergrCompendiumPatch
	{
		private static void Postfix(TextsDialog __instance)
		{
			DvergrCompendiumManager.AddEntry(__instance);
		}
	}
}
namespace HexDvergrAllies.Patches.Networking
{
	[HarmonyPatch]
	internal static class ZoneSystemStarterKeyMapPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(ZoneSystem), "GlobalKeyAdd", new Type[2]
			{
				typeof(string),
				typeof(bool)
			}, (Type[])null);
			yield return AccessTools.Method(typeof(ZoneSystem), "GlobalKeyRemove", new Type[2]
			{
				typeof(string),
				typeof(bool)
			}, (Type[])null);
		}

		private static void Prefix(string __0, out IDisposable __state)
		{
			__state = DvergrStarterMapRefreshGuard.BeginKeyUpdate(__0);
		}

		private static Exception Finalizer(Exception __exception, IDisposable __state)
		{
			__state?.Dispose();
			return __exception;
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "RPC_GlobalKeys")]
	internal static class ZoneSystemStarterKeySyncMapPatch
	{
		private static void Prefix(ZoneSystem __instance, List<string> __1, out IDisposable __state)
		{
			__state = DvergrStarterMapRefreshGuard.BeginSync(__instance.GetGlobalKeys(), __1);
		}

		private static Exception Finalizer(Exception __exception, IDisposable __state)
		{
			__state?.Dispose();
			return __exception;
		}
	}
	[HarmonyPatch(typeof(Game), "UpdateNoMap")]
	internal static class GameStarterKeyMapRefreshPatch
	{
		private static bool Prefix()
		{
			return DvergrStarterMapRefreshGuard.ShouldRefreshMap;
		}
	}
}
namespace HexDvergrAllies.Patches.Companions
{
	[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
	internal static class AttackCompanionDoubleShotPatch
	{
		private static readonly FieldRef<Attack, Humanoid> CharacterField = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");

		private static readonly FieldRef<Attack, ItemData> WeaponField = AccessTools.FieldRefAccess<Attack, ItemData>("m_weapon");

		private static void Prefix(Attack __instance, out int __state)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			__state = __instance.m_projectiles;
			Humanoid val = CharacterField.Invoke(__instance);
			ItemData val2 = WeaponField.Invoke(__instance);
			if (Object.op_Implicit((Object)(object)val) && DvergrCompanionState.IsHired((Character)(object)val) && (int)((Character)val).GetFaction() == 10 && val2 != null && !(((Object)val2.m_dropPrefab).name != "CrossbowArbalest"))
			{
				__instance.m_projectiles = 2;
			}
		}

		private static void Postfix(Attack __instance, int __state)
		{
			__instance.m_projectiles = __state;
		}
	}
	[HarmonyPatch(typeof(BaseAI), "Flee")]
	internal static class BaseAICompanionFleePatch
	{
		private static bool Prefix(BaseAI __instance)
		{
			MonsterAI val = (MonsterAI)(object)((__instance is MonsterAI) ? __instance : null);
			if (val == null)
			{
				return true;
			}
			Character component = ((Component)val).GetComponent<Character>();
			if (!Object.op_Implicit((Object)(object)component) || !DvergrCompanionState.IsHired(component))
			{
				return true;
			}
			ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component2) || !component2.IsValid() || !component2.IsOwner())
			{
				return true;
			}
			if (HexDvergrAlliesConfiguration.EnableDebugLogs.Value)
			{
				Character targetCreature = ((BaseAI)val).GetTargetCreature();
				string text = (Object.op_Implicit((Object)(object)targetCreature) ? ((Object)targetCreature).name : "None");
				HexLog.LogInfo($"[Dvergr Companion] Flee suppressed: Dvergr={((Object)component).name}, Health={component.GetHealth():F1}, MaxHealth={component.GetMaxHealth():F1}, Target={text}");
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	internal static class CharacterCompanionDamagePatch
	{
		private static bool Prefix(Character __instance, HitData hit, out DvergrCompanionDamageManager.DamageState __state)
		{
			__state = default(DvergrCompanionDamageManager.DamageState);
			if (DvergrFriendlyFireRules.ShouldBlockDamage(__instance, hit) || DvergrStarterCharacterState.IsProtected(__instance))
			{
				return false;
			}
			DvergrCompanionDamageManager.BeforeDamage(__instance, hit, out __state);
			return true;
		}

		private static void Postfix(Character __instance, DvergrCompanionDamageManager.DamageState __state)
		{
			DvergrCompanionDamageManager.AfterDamage(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	internal static class DvergrCompanionLedgeFollowPatch
	{
		private const float MinimumHeightDifference = 3f;

		private const float MinimumHorizontalDistance = 2f;

		private const float MaximumHorizontalDistance = 12f;

		[HarmonyPostfix]
		private static void Postfix(MonsterAI __instance)
		{
			//IL_0074: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (DvergrCompanionDungeonFollowManager.IsDungeonFollow(__instance))
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if (!Object.op_Implicit((Object)(object)component) || !DvergrCompanionState.IsHired(component))
			{
				return;
			}
			ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component2) || !component2.IsValid() || !component2.IsOwner())
			{
				return;
			}
			GameObject followTarget = __instance.GetFollowTarget();
			if (!Object.op_Implicit((Object)(object)followTarget) || (Object)(object)((BaseAI)__instance).GetTargetCreature() != (Object)null || (Object)(object)__instance.GetStaticTarget() != (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)component).transform.position;
			Vector3 position2 = followTarget.transform.position;
			if (!(position.y - position2.y < 3f))
			{
				Vector3 val = position2 - position;
				val.y = 0f;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (!(magnitude < 2f) && !(magnitude > 12f))
				{
					component.SetMoveDir(((Vector3)(ref val)).normalized);
					component.SetRun(true);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class DvergrCompanionPortalTeleportPatch
	{
		[HarmonyPatch(typeof(Player), "TeleportTo")]
		[HarmonyPostfix]
		private static void TeleportToPostfix(Player __instance, bool __result)
		{
			DvergrCompanionPortalRelocationManager.BeginTeleport(__instance, __result);
		}

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		[HarmonyPrefix]
		private static void UpdateTeleportPrefix(Player __instance, out bool __state)
		{
			__state = ((Character)__instance).IsTeleporting();
		}

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		[HarmonyPostfix]
		private static void UpdateTeleportPostfix(Player __instance, bool __state)
		{
			DvergrCompanionPortalRelocationManager.CompleteTeleport(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	internal static class DvergrCompanionTerrainRecoveryPatch
	{
		private sealed class RecoveryState
		{
			internal float NextCheckTime;

			internal float LastDistance;

			internal float LastProgressTime;

			internal GameObject FollowTarget;
		}

		private const float CheckInterval = 0.5f;

		private const float RecoveryDistance = 12f;

		private const float ImmediateRecoveryDistance = 30f;

		private const float StuckDuration = 3f;

		private const float MinimumProgress = 1f;

		private const float RecoveryOffset = 2f;

		private static readonly Dictionary<MonsterAI, RecoveryState> States = new Dictionary<MonsterAI, RecoveryState>();

		[HarmonyPostfix]
		private static void Postfix(MonsterAI __instance)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || !DvergrCompanionState.IsHired(component))
			{
				States.Remove(__instance);
				return;
			}
			ProcessPendingRecall(__instance, component);
			if (DvergrCompanionShipManager.IsPassenger(component))
			{
				States.Remove(__instance);
				return;
			}
			if (DvergrCompanionSentryMode.IsActive(component))
			{
				DvergrCompanionDungeonFollowManager.RemoveCharacter(component);
				States.Remove(__instance);
				return;
			}
			ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
			if ((Object)(object)component2 == (Object)null || !component2.IsValid() || !component2.IsOwner())
			{
				States.Remove(__instance);
				return;
			}
			GameObject followTarget = __instance.GetFollowTarget();
			if ((Object)(object)followTarget == (Object)null)
			{
				States.Remove(__instance);
				return;
			}
			float num = Vector3.Distance(((Component)component).transform.position, followTarget.transform.position);
			if (DvergrCompanionDungeonFollowManager.Update(__instance))
			{
				return;
			}
			RecoveryState value;
			if (num >= 30f)
			{
				Recover(component, followTarget, num, "Distance limit");
				States.Remove(__instance);
			}
			else if ((Object)(object)((BaseAI)__instance).GetTargetCreature() != (Object)null || (Object)(object)__instance.GetStaticTarget() != (Object)null)
			{
				States.Remove(__instance);
			}
			else if (num < 12f)
			{
				States.Remove(__instance);
			}
			else if (!States.TryGetValue(__instance, out value))
			{
				value = new RecoveryState
				{
					NextCheckTime = Time.time + 0.5f,
					LastDistance = num,
					LastProgressTime = Time.time,
					FollowTarget = followTarget
				};
				States.Add(__instance, value);
			}
			else if ((Object)(object)value.FollowTarget != (Object)(object)followTarget)
			{
				States.Remove(__instance);
			}
			else if (!(Time.time < value.NextCheckTime))
			{
				value.NextCheckTime = Time.time + 0.5f;
				if (value.LastDistance - num >= 1f)
				{
					value.LastProgressTime = Time.time;
				}
				value.LastDistance = num;
				if (!(Time.time - value.LastProgressTime < 3f))
				{
					Recover(component, followTarget, num, "No progress");
					States.Remove(__instance);
				}
			}
		}

		private static void Recover(Character character, GameObject followTarget, float distance, string reason)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = followTarget.transform.position + followTarget.transform.right * 2f;
			HexLog.LogInfo($"[Dvergr Terrain Recovery] Dvergr={((Object)character).name}, Reason={reason}, Distance={distance:F1}, From={((Component)character).transform.position}, To={val}");
			((Component)character).transform.position = val;
		}

		private static void ProcessPendingRecall(MonsterAI monsterAI, Character character)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)character).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO.GetBool("HexDvergr_PendingModeTeleport", false))
			{
				Vector3 vec = zDO.GetVec3("HexDvergr_RecallPosition", ((Component)character).transform.position);
				Rigidbody component2 = ((Component)character).GetComponent<Rigidbody>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					component2.linearVelocity = Vector3.zero;
					component2.angularVelocity = Vector3.zero;
					component2.position = vec;
				}
				((Component)character).transform.position = vec;
				zDO.SetPosition(vec);
				zDO.Set("HexDvergr_PendingModeTeleport", false);
				((BaseAI)monsterAI).ResetPatrolPoint();
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "CustomFixedUpdate")]
	internal static class HumanoidCompanionAttackAnimationPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Humanoid __instance)
		{
			DvergrCompanionBehaviorManager.UpdateAttackAnimation(__instance);
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	internal static class MonsterAICompanionBehaviorPatch
	{
		private static void Prefix(MonsterAI __instance)
		{
			DvergrCompanionBehaviorManager.UpdateBehavior(__instance);
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateTarget")]
	internal static class MonsterAICompanionTargetScanPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo objB = AccessTools.Field(typeof(MonsterAI), "m_updateTargetTimer");
			MethodInfo methodInfo = AccessTools.Method(typeof(DvergrCompanionBehaviorManager), "GetTargetScanInterval", (Type[])null, (Type[])null);
			int num = 0;
			for (int i = 1; i < list.Count; i++)
			{
				if (!(list[i].opcode != OpCodes.Stfld) && object.Equals(list[i].operand, objB) && !(list[i - 1].opcode != OpCodes.Ldc_R4) && (float)list[i - 1].operand == 2f)
				{
					CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					val.labels.AddRange(list[i].labels);
					list[i].labels.Clear();
					list.InsertRange(i, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
					{
						val,
						new CodeInstruction(OpCodes.Call, (object)methodInfo)
					});
					i += 2;
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException("MonsterAICompanionTargetScanPatch: Expected one normal target scan timer reset.");
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	internal static class MonsterAICompanionShipPatch
	{
		private static void Postfix(MonsterAI __instance)
		{
			Character component = ((Component)__instance).GetComponent<Character>();
			if (Object.op_Implicit((Object)(object)component) && DvergrCompanionShipManager.IsPassenger(component))
			{
				ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component2) && component2.IsValid() && component2.IsOwner())
				{
					((BaseAI)__instance).StopMoving();
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
	internal static class PlayerCompanionPinPatch
	{
		private static void Postfix(Player __instance)
		{
			DvergrCompanionPinManager dvergrCompanionPinManager = default(DvergrCompanionPinManager);
			if (!((Component)__instance).TryGetComponent<DvergrCompanionPinManager>(ref dvergrCompanionPinManager))
			{
				((Component)__instance).gameObject.AddComponent<DvergrCompanionPinManager>();
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	internal static class ShipCompanionBoardingPatch
	{
		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				DvergrCompanionShipManager.Update();
			}
		}
	}
}
namespace HexDvergrAllies.Core
{
	internal static class HexConfigurationMigration
	{
		private static readonly PropertyInfo UnboundEntriesProperty = typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly PropertyInfo BoundEntriesProperty = typeof(ConfigFile).GetProperty("Entries", BindingFlags.Instance | BindingFlags.NonPublic);

		internal static bool Complete(ConfigFile config)
		{
			Dictionary<ConfigDefinition, string> obj = (Dictionary<ConfigDefinition, string>)UnboundEntriesProperty.GetValue(config, null);
			bool result = obj.Count > 0;
			obj.Clear();
			Dictionary<ConfigDefinition, ConfigEntryBase> dictionary = (Dictionary<ConfigDefinition, ConfigEntryBase>)BoundEntriesProperty.GetValue(config, null);
			KeyValuePair<ConfigDefinition, ConfigEntryBase>[] array = dictionary.OrderBy<KeyValuePair<ConfigDefinition, ConfigEntryBase>, string>((KeyValuePair<ConfigDefinition, ConfigEntryBase> pair) => pair.Key.Section, StringComparer.Ordinal).ThenByDescending((KeyValuePair<ConfigDefinition, ConfigEntryBase> pair) => (from attributes in pair.Value.Description.Tags.OfType<ConfigurationManagerAttributes>()
				select attributes.Order.GetValueOrDefault()).FirstOrDefault()).ThenBy<KeyValuePair<ConfigDefinition, ConfigEntryBase>, string>((KeyValuePair<ConfigDefinition, ConfigEntryBase> pair) => pair.Key.Key, StringComparer.Ordinal)
				.ToArray();
			dictionary.Clear();
			KeyValuePair<ConfigDefinition, ConfigEntryBase>[] array2 = array;
			for (int num = 0; num < array2.Length; num++)
			{
				KeyValuePair<ConfigDefinition, ConfigEntryBase> keyValuePair = array2[num];
				dictionary.Add(keyValuePair.Key, keyValuePair.Value);
			}
			return result;
		}
	}
	internal static class PrefabHelper
	{
		internal const string Coins = "Coins";

		internal const string JuteBlue = "JuteBlue";

		internal const string TrophyDvergr = "TrophyDvergr";

		internal const string Softtissue = "Softtissue";

		internal const string MeadTasty = "MeadTasty";

		internal const string StaffShieldAoe = "staff_shield_aoe";

		internal const string FlametalNew = "FlametalNew";

		internal const string MoltenCore = "MoltenCore";

		internal const string DvergrNeedle = "DvergrNeedle";

		internal const string Sap = "Sap";

		internal const string AshlandsDvergrPrefix = "DvergerAshlands";

		internal const string CharredStoneSpawner = "Spawner_CharredStone";

		internal const string CrossbowArbalest = "CrossbowArbalest";

		internal static readonly HashSet<string> AllowedHomesteadPieces = new HashSet<string> { "piece_workbench", "piece_stonecutter", "portal_wood", "portal_stone" };

		internal static readonly string[] MistlandsTrophyPrefabs = new string[3] { "TrophySeeker", "TrophyGjall", "TrophySeekerBrute" };
	}
	internal static class HexLog
	{
		private static bool Enabled
		{
			get
			{
				if (HexDvergrAlliesConfiguration.EnableDebugLogs != null)
				{
					return HexDvergrAlliesConfiguration.EnableDebugLogs.Value;
				}
				return false;
			}
		}

		internal static void LogInfo(object message)
		{
			if (Enabled)
			{
				Plugin.Log.LogInfo(message);
			}
		}

		internal static void LogWarning(object message)
		{
			if (Enabled)
			{
				Plugin.Log.LogWarning(message);
			}
		}

		internal static void LogError(object message)
		{
			if (Enabled)
			{
				Plugin.Log.LogError(message);
			}
		}
	}
}
namespace HexDvergrAllies.Core.Features.Progression
{
	internal sealed class DvergrStarterEncounterManager : MonoBehaviour
	{
		internal const string RegisterRpc = "HexDvergrStarterRegister";

		internal const string DeathRpc = "HexDvergrStarterDeath";

		internal const string AcceptedRpc = "HexDvergrStarterAccepted";

		private static DvergrStarterEncounterManager _instance;

		private readonly Dictionary<long, bool> _registered = new Dictionary<long, bool>();

		private readonly Dictionary<long, DvergrStarterEncounter> _encounters = new Dictionary<long, DvergrStarterEncounter>();

		private readonly List<ZDO> _legacyDvergr = new List<ZDO>();

		private readonly HashSet<long> _legacyCompleted = new HashSet<long>();

		private readonly HashSet<long> _reconciled = new HashSet<long>();

		private readonly Dictionary<long, float> _recoverAt = new Dictionary<long, float>();

		private readonly List<long> _recoveryBuffer = new List<long>();

		private int _legacyIndex;

		private bool _legacyScanComplete;

		private ZoneSystem _world;

		private Minimap _map;

		private PinData _pin;

		private long _pinCharacter;

		private float _nextRegistration;

		private int _testAction;

		internal static bool IsStarter(Character character)
		{
			return DvergrStarterCharacterState.IsStarter(character);
		}

		internal static bool HasFreePact(Character character)
		{
			return DvergrStarterCharacterState.HasFreePact(Player.m_localPlayer, character);
		}

		internal static int PactCost(Character character)
		{
			if (!IsStarter(character))
			{
				return 2;
			}
			return 0;
		}

		internal static string PactPrice(Character character)
		{
			if (!IsStarter(character))
			{
				return DvergrPricingConfig.ForgePactCostDisplay;
			}
			return HexLocalizationManager.Localize("$hex_dvergr_starter_free");
		}

		private void Awake()
		{
			_instance = this;
		}

		private void Update()
		{
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)_world != (Object)(object)instance)
			{
				RemovePin();
				DvergrForgePactManager.ResetSessionState();
				_world = instance;
				_registered.Clear();
				_encounters.Clear();
				_legacyDvergr.Clear();
				_legacyCompleted.Clear();
				_reconciled.Clear();
				_recoverAt.Clear();
				_legacyIndex = 0;
				_legacyScanComplete = false;
				_nextRegistration = 0f;
				_testAction = 0;
			}
			if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)ZNet.instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)Game.instance) || ZDOMan.instance == null || ZRoutedRpc.instance == null || WorldGenerator.instance == null)
			{
				return;
			}
			UpdateTestControls();
			DvergrPactAuthority.Update();
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer) && localPlayer.GetPlayerID() != 0L && Time.time >= _nextRegistration)
			{
				_nextRegistration = Time.time + 5f;
				bool flag = DvergrStarterCharacterState.HasCompleted(localPlayer) || DvergrStarterCharacterState.HasAcceptedStarter(localPlayer);
				ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.IsOwner())
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(DvergrCompanionManager.GetServerPeerID(ZRoutedRpc.instance), "HexDvergrStarterRegister", new object[2]
					{
						((Character)localPlayer).GetZDOID(),
						flag
					});
					DvergrStarterProgressionService.Report(localPlayer);
				}
			}
			UpdatePin(localPlayer);
			if (!ZNet.instance.IsServer() || !instance.LocationsGenerated || _registered.Count == 0)
			{
				return;
			}
			if (!_legacyScanComplete)
			{
				for (int i = 0; i < 16; i++)
				{
					if (_legacyScanComplete)
					{
						break;
					}
					_legacyScanComplete = ZDOMan.instance.GetAllZDOsWithPrefabIterative("Dverger", _legacyDvergr, ref _legacyIndex);
				}
				if (!_legacyScanComplete)
				{
					return;
				}
				foreach (ZDO item2 in _legacyDvergr)
				{
					if (item2.GetBool("hex_starter_dvergr", false))
					{
						if (DvergrCompanionState.IsHired(item2))
						{
							_legacyCompleted.Add(DvergrCompanionState.GetOwnerPlayerId(item2));
						}
						long item = item2.GetLong("hex_starter_character", 0L);
						if (item2.GetBool("hex_starter_consumed", false))
						{
							_legacyCompleted.Add(item);
						}
					}
				}
			}
			foreach (KeyValuePair<long, bool> item3 in _registered)
			{
				string text = DvergrStarterCharacterState.DoneKey(item3.Key);
				if (item3.Value || _legacyCompleted.Contains(item3.Key))
				{
					if (!instance.GetGlobalKey(text))
					{
						instance.SetGlobalKey(text);
					}
				}
				else if (!instance.GetGlobalKey(text) && !_encounters.ContainsKey(item3.Key))
				{
					_encounters.Add(item3.Key, new DvergrStarterEncounter(item3.Key));
				}
				if (_reconciled.Add(item3.Key) && !instance.GetGlobalKey(text) && instance.GetGlobalKey(DvergrStarterCharacterState.WorldPrefix(item3.Key) + "built") && !DvergrPersistentOwnership.HasLivingStarter(item3.Key))
				{
					_recoverAt[item3.Key] = Time.time + 5f;
				}
			}
			List<long> recoveryBuffer = _recoveryBuffer;
			recoveryBuffer.Clear();
			foreach (KeyValuePair<long, float> item4 in _recoverAt)
			{
				if (Time.time >= item4.Value)
				{
					recoveryBuffer.Add(item4.Key);
				}
			}
			foreach (long item5 in recoveryBuffer)
			{
				_recoverAt.Remove(item5);
				if (!instance.GetGlobalKey(DvergrStarterCharacterState.DoneKey(item5)) && !DvergrPersistentOwnership.HasLivingStarter(item5))
				{
					string text2 = DvergrStarterCharacterState.WorldPrefix(item5);
					instance.RemoveGlobalKey(text2 + "built");
					instance.RemoveGlobalKey(text2 + "slot_dvergr");
					_encounters[item5] = new DvergrStarterEncounter(item5);
					HexLog.LogInfo($"[Starter Encounter] Recovering missing unhired starter for character {item5}; existing camp pieces are retained.");
				}
			}
			foreach (DvergrStarterEncounter value in _encounters.Values)
			{
				if (!value.IsFinished)
				{
					value.Tick();
					break;
				}
			}
		}

		internal static void RequestTestControl(bool reset)
		{
			if (Object.op_Implicit((Object)(object)_instance) && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer() && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				_instance._testAction = ((!reset) ? 1 : 2);
			}
		}

		private void UpdateTestControls()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			int testAction = _testAction;
			_testAction = 0;
			Player localPlayer = Player.m_localPlayer;
			if (testAction == 0 || !ZNet.instance.IsServer() || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || localPlayer.GetPlayerID() == 0L || DvergrForgePactManager.IsHirePending)
			{
				return;
			}
			bool flag = testAction == 2;
			long characterId = localPlayer.GetPlayerID();
			foreach (ZDO starter in DvergrPersistentOwnership.GetStarters(characterId))
			{
				GameObject val = ZNetScene.instance.FindInstance(starter.m_uid);
				Character val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Character>() : null);
				if (!flag)
				{
					if (Object.op_Implicit((Object)(object)val2))
					{
						((Component)val2).GetComponent<ZNetView>().ClaimOwnership();
						val2.SetHealth(0f);
					}
				}
				else if (Object.op_Implicit((Object)(object)val2))
				{
					((Component)val2).GetComponent<ZNetView>().ClaimOwnership();
					DvergrCompanionManager.OnCompanionDeath(val2);
					ZNetScene.instance.Destroy(val);
				}
				else
				{
					starter.SetOwner(DvergrCompanionManager.GetServerPeerID(ZRoutedRpc.instance));
					ZDOMan.instance.DestroyZDO(starter);
				}
			}
			if (!flag)
			{
				HexLog.LogInfo("[Starter Test] Kill requested for loaded starters belonging to character " + characterId);
				return;
			}
			foreach (ZDO starterTombstone in DvergrPersistentOwnership.GetStarterTombstones(characterId))
			{
				starterTombstone.SetOwner(DvergrCompanionManager.GetServerPeerID(ZRoutedRpc.instance));
				ZDOMan.instance.DestroyZDO(starterTombstone);
			}
			DvergrForgePactManager.ResetSessionState();
			string text = DvergrStarterCharacterState.WorldPrefix(characterId);
			_world.RemoveGlobalKey(DvergrStarterCharacterState.DoneKey(characterId));
			_world.RemoveGlobalKey(text + "built");
			_world.RemoveGlobalKey(text + "slot_dvergr");
			_registered[characterId] = false;
			_legacyCompleted.Remove(characterId);
			_legacyDvergr.RemoveAll((ZDO zdo) => zdo.GetLong("hex_starter_character", 0L) == characterId);
			_recoverAt.Remove(