Decompiled source of DvergrAllies v1.0.0

DvergrAllies/plugins/DvergrAllies.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DvergrAllies
{
	public class CustomDvergrDef
	{
		public string PrefabName;

		public string BasePrefab;

		public string DisplayName;

		public string[] Loadout;

		public float HealthMultiplier = 1f;

		public bool StripArmor;

		public bool AddRage;

		public bool IsMeleeAI;

		public bool IsRangedAI;

		public bool IsClericAI;
	}
	public static class AllyPrefabManager
	{
		public static List<CustomDvergrDef> CustomVariants = new List<CustomDvergrDef>
		{
			new CustomDvergrDef
			{
				PrefabName = "AllyDvergrMageElemental",
				BasePrefab = "DvergerMageFire",
				DisplayName = "Dvergr Elemental Mage",
				Loadout = new string[0],
				IsRangedAI = true
			},
			new CustomDvergrDef
			{
				PrefabName = "AllyDvergrSpellswordFire",
				BasePrefab = "DvergerMageFire",
				DisplayName = "Dvergr Fire Spellsword",
				Loadout = new string[1] { "AllyDvergr_SwordBronze" },
				IsMeleeAI = true
			},
			new CustomDvergrDef
			{
				PrefabName = "AllyDvergrSpellswordIce",
				BasePrefab = "DvergerMageIce",
				DisplayName = "Dvergr Ice Spellsword",
				Loadout = new string[1] { "AllyDvergr_SwordBronze" },
				IsMeleeAI = true
			},
			new CustomDvergrDef
			{
				PrefabName = "AllyDvergrCleric",
				BasePrefab = "DvergerMageSupport",
				DisplayName = "Dvergr Cleric",
				Loadout = new string[3] { "AllyDvergr_MaceBronze", "DvergerStaffHeal_heal", "DvergerStaffSupport_buff" },
				IsClericAI = true
			},
			new CustomDvergrDef
			{
				PrefabName = "AllyDvergrWarrior",
				BasePrefab = "Dverger",
				DisplayName = "Dvergr Warrior",
				Loadout = new string[2] { "AllyDvergr_SwordBronze", "ShieldBanded" },
				HealthMultiplier = 1.5f,
				IsMeleeAI = true
			},
			new CustomDvergrDef
			{
				PrefabName = "AllyDvergrBerserker",
				BasePrefab = "Dverger",
				DisplayName = "Dvergr Berserker",
				Loadout = new string[1] { "AllyDvergr_Battleaxe" },
				StripArmor = false,
				AddRage = true,
				IsMeleeAI = true
			}
		};

		public static void Setup()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Setup;
			Logger.LogInfo((object)"Setting up Ally Dvergr prefabs...");
			CreateAllyVariant("Dverger", "AllyDvergrRogue", "Dvergr Rogue");
			CreateAllyVariant("DvergerMage", "AllyDvergrMage", "Dvergr Mage");
			CreateAllyVariant("DvergerMageFire", "AllyDvergrMageFire", "Dvergr Fire Mage");
			CreateAllyVariant("DvergerMageIce", "AllyDvergrMageIce", "Dvergr Ice Mage");
			CreateAllyVariant("DvergerMageSupport", "AllyDvergrMageSupport", "Dvergr Support Mage");
			foreach (CustomDvergrDef customVariant in CustomVariants)
			{
				CreateCustomVariant(customVariant);
			}
			GetOrCloneWeaponWithMeleeAnim("AllyDvergr_SwordIron");
			GetOrCloneWeaponWithMeleeAnim("AllyDvergr_SwordBlackmetal");
			GetOrCloneWeaponWithMeleeAnim("AllyDvergr_MaceIron");
			GetOrCloneWeaponWithMeleeAnim("AllyDvergr_MaceBlackmetal");
			GetOrCloneWeaponWithMeleeAnim("AllyDvergr_BattleaxeBlackmetal");
			Logger.LogInfo((object)"Ally Dvergr prefabs created.");
		}

		public static void MakePrefabTamable(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			Tameable component = prefab.GetComponent<Tameable>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			DvergrTameable dvergrTameable = prefab.GetComponent<DvergrTameable>();
			if ((Object)(object)dvergrTameable == (Object)null)
			{
				dvergrTameable = prefab.AddComponent<DvergrTameable>();
			}
			((Tameable)dvergrTameable).m_tamingTime = ConfigManager.TamingTime.Value;
			((Tameable)dvergrTameable).m_fedDuration = ConfigManager.FedDuration.Value;
			((Tameable)dvergrTameable).m_commandable = true;
			Procreation component2 = prefab.GetComponent<Procreation>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component2);
			}
			if ((Object)(object)prefab.GetComponent<DvergrProcreation>() == (Object)null)
			{
				prefab.AddComponent<DvergrProcreation>();
			}
			if ((Object)(object)prefab.GetComponent<DvergrGenetics>() == (Object)null)
			{
				prefab.AddComponent<DvergrGenetics>();
			}
			MonsterAI component3 = prefab.GetComponent<MonsterAI>();
			if (!((Object)(object)component3 != (Object)null))
			{
				return;
			}
			((BaseAI)component3).m_passiveAggresive = false;
			component3.m_fleeIfNotAlerted = false;
			component3.m_fleeIfLowHealth = 0f;
			component3.m_attackPlayerObjects = false;
			((BaseAI)component3).m_avoidFire = false;
			if (component3.m_consumeItems == null)
			{
				component3.m_consumeItems = new List<ItemDrop>();
			}
			string[] array = ConfigManager.TamingItems.Value.Split(new char[1] { ',' });
			foreach (string text in array)
			{
				GameObject prefab2 = PrefabManager.Instance.GetPrefab(text.Trim());
				if ((Object)(object)prefab2 != (Object)null)
				{
					ItemDrop component4 = prefab2.GetComponent<ItemDrop>();
					if ((Object)(object)component4 != (Object)null && !component3.m_consumeItems.Contains(component4))
					{
						component3.m_consumeItems.Add(component4);
					}
				}
			}
			if (component3.m_consumeSearchRange < 10f)
			{
				component3.m_consumeSearchRange = 10f;
			}
			if (component3.m_consumeSearchInterval < 10f)
			{
				component3.m_consumeSearchInterval = 10f;
			}
			component3.m_consumeRange = ConfigManager.ConsumeRange.Value;
		}

		public static GameObject GetOrCloneWeaponWithMeleeAnim(string itemName)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			if (itemName.StartsWith("AllyDvergr_"))
			{
				string text = itemName.Replace("AllyDvergr_", "");
				GameObject prefab = PrefabManager.Instance.GetPrefab(itemName);
				if ((Object)(object)prefab != (Object)null)
				{
					return prefab;
				}
				if ((Object)(object)PrefabManager.Instance.GetPrefab(text) == (Object)null)
				{
					return null;
				}
				GameObject obj = PrefabManager.Instance.CreateClonedPrefab(itemName, text);
				CustomItem val = new CustomItem(obj, true);
				ItemDrop itemDrop = val.ItemDrop;
				if ((Object)(object)itemDrop != (Object)null && itemDrop.m_itemData != null && itemDrop.m_itemData.m_shared != null)
				{
					if (itemName.Contains("Sword") || itemName.Contains("Mace") || itemName.Contains("Battleaxe") || itemName.Contains("Shield"))
					{
						GameObject prefab2 = PrefabManager.Instance.GetPrefab("Dverger_melee");
						if ((Object)(object)prefab2 != (Object)null)
						{
							ItemDrop component = prefab2.GetComponent<ItemDrop>();
							if ((Object)(object)component != (Object)null && component.m_itemData.m_shared != null)
							{
								itemDrop.m_itemData.m_shared.m_attack = component.m_itemData.m_shared.m_attack.Clone();
							}
						}
						itemDrop.m_itemData.m_shared.m_aiAttackInterval = 1.2f;
						itemDrop.m_itemData.m_shared.m_aiAttackRange = 3.5f;
						itemDrop.m_itemData.m_shared.m_attack.m_attackRange = 3.5f;
						itemDrop.m_itemData.m_shared.m_attack.m_attackStamina = 0f;
						itemDrop.m_itemData.m_shared.m_attack.m_attackHealth = 0f;
						itemDrop.m_itemData.m_shared.m_attack.m_attackHealthPercentage = 0f;
						itemDrop.m_itemData.m_shared.m_attack.m_attackEitr = 0f;
						itemDrop.m_itemData.m_shared.m_useDurability = false;
					}
					if (itemName.Contains("Battleaxe"))
					{
						itemDrop.m_itemData.m_shared.m_damages.m_slash *= 1.5f;
					}
					float value = ConfigManager.AllyDamageMultiplier.Value;
					if (value != 1f)
					{
						itemDrop.m_itemData.m_shared.m_damages.m_damage *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_blunt *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_slash *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_pierce *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_chop *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_pickaxe *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_fire *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_frost *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_lightning *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_poison *= value;
						itemDrop.m_itemData.m_shared.m_damages.m_spirit *= value;
					}
				}
				ItemManager.Instance.AddItem(val);
				return obj;
			}
			return PrefabManager.Instance.GetPrefab(itemName);
		}

		private static string GetSuitName(string basePrefabName)
		{
			return basePrefabName switch
			{
				"Dverger" => "DvergerSuitArbalest", 
				"DvergerMageFire" => "DvergerSuitFire", 
				"DvergerMageIce" => "DvergerSuitIce", 
				"DvergerMageSupport" => "DvergerSuitSupport", 
				_ => null, 
			};
		}

		private static void CreateCustomVariant(CustomDvergrDef def)
		{
			CreateAllyVariant(def.BasePrefab, def.PrefabName, def.DisplayName, def.HealthMultiplier, def.IsMeleeAI, def.IsRangedAI, def.IsClericAI);
			GameObject prefab = PrefabManager.Instance.GetPrefab(def.PrefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			Humanoid component = prefab.GetComponent<Humanoid>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			component.m_randomSets = (ItemSet[])(object)new ItemSet[0];
			component.m_randomWeapon = (GameObject[])(object)new GameObject[0];
			component.m_randomShield = (GameObject[])(object)new GameObject[0];
			if (def.StripArmor)
			{
				component.m_randomArmor = (GameObject[])(object)new GameObject[0];
			}
			List<GameObject> list = new List<GameObject>();
			if (!def.StripArmor)
			{
				string suitName = GetSuitName(def.BasePrefab);
				if (suitName != null)
				{
					GameObject prefab2 = PrefabManager.Instance.GetPrefab(suitName);
					if ((Object)(object)prefab2 != (Object)null)
					{
						list.Add(prefab2);
						ConfigManager.LogEquipment("[CustomVariant] " + def.PrefabName + ": Added suit: " + suitName);
					}
				}
			}
			string[] loadout = def.Loadout;
			foreach (string text in loadout)
			{
				GameObject orCloneWeaponWithMeleeAnim = GetOrCloneWeaponWithMeleeAnim(text);
				if ((Object)(object)orCloneWeaponWithMeleeAnim != (Object)null)
				{
					list.Add(orCloneWeaponWithMeleeAnim);
					ConfigManager.LogEquipment("[CustomVariant] " + def.PrefabName + ": Added: " + text);
					continue;
				}
				Logger.LogWarning((object)("[CustomVariant] " + def.PrefabName + ": Could not find prefab '" + text + "'!"));
			}
			component.m_defaultItems = list.ToArray();
			component.m_unarmedWeapon = null;
			ConfigManager.LogEquipment($"[CustomVariant] {def.PrefabName}: Final m_defaultItems count: {list.Count}");
			if (def.AddRage)
			{
				prefab.AddComponent<DvergrBerserkerRage>();
			}
			DvergrCombatAI component2 = prefab.GetComponent<DvergrCombatAI>();
			if ((Object)(object)component2 != (Object)null && def.PrefabName == "AllyDvergrMageElemental")
			{
				component2.IsElementalMage = true;
			}
		}

		private static void CreateAllyVariant(string basePrefabName, string newPrefabName, string displayName, float healthMultiplier = 1f, bool isMelee = false, bool isRanged = false, bool isCleric = false)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PrefabManager.Instance.GetPrefab(basePrefabName) == (Object)null)
			{
				Logger.LogWarning((object)("Base prefab " + basePrefabName + " not found!"));
				return;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(newPrefabName, basePrefabName);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			CustomPrefab val2 = new CustomPrefab(val, true);
			Tameable component = val.GetComponent<Tameable>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			DvergrTameable dvergrTameable = val.GetComponent<DvergrTameable>();
			if ((Object)(object)dvergrTameable == (Object)null)
			{
				dvergrTameable = val.AddComponent<DvergrTameable>();
			}
			((Tameable)dvergrTameable).m_tamingTime = ConfigManager.TamingTime.Value;
			((Tameable)dvergrTameable).m_fedDuration = ConfigManager.FedDuration.Value;
			((Tameable)dvergrTameable).m_commandable = true;
			MonsterAI component2 = val.GetComponent<MonsterAI>();
			if ((Object)(object)component2 != (Object)null)
			{
				string[] array = ConfigManager.TamingItems.Value.Split(new char[1] { ',' });
				component2.m_consumeItems = new List<ItemDrop>();
				string[] array2 = array;
				foreach (string text in array2)
				{
					GameObject prefab = PrefabManager.Instance.GetPrefab(text.Trim());
					if ((Object)(object)prefab != (Object)null)
					{
						ItemDrop component3 = prefab.GetComponent<ItemDrop>();
						if ((Object)(object)component3 != (Object)null)
						{
							component2.m_consumeItems.Add(component3);
						}
						else
						{
							Logger.LogWarning((object)("Item " + text + " is missing ItemDrop component!"));
						}
					}
					else
					{
						Logger.LogWarning((object)("Could not find taming item prefab: " + text));
					}
				}
				component2.m_consumeSearchRange = 10f;
				component2.m_consumeSearchInterval = 10f;
				component2.m_consumeRange = ConfigManager.ConsumeRange.Value;
				((BaseAI)component2).m_aggravatable = false;
				((BaseAI)component2).m_passiveAggresive = false;
				component2.m_fleeIfLowHealth = 0f;
				component2.m_fleeIfNotAlerted = false;
				component2.m_circulateWhileCharging = false;
				component2.m_circulateWhileChargingFlying = false;
				((BaseAI)component2).m_avoidFire = false;
				((BaseAI)component2).m_avoidWater = false;
				component2.m_interceptTimeMax = 2f;
				component2.m_interceptTimeMin = 0f;
				component2.m_maxChaseDistance = 0f;
				component2.m_alertRange = 30f;
				component2.m_attackPlayerObjects = false;
			}
			Procreation component4 = val.GetComponent<Procreation>();
			if ((Object)(object)component4 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component4);
			}
			if ((Object)(object)val.GetComponent<DvergrProcreation>() == (Object)null)
			{
				val.AddComponent<DvergrProcreation>();
			}
			val.AddComponent<DvergrGenetics>();
			val.AddComponent<DvergrWeaponScaler>();
			DvergrCombatAI dvergrCombatAI = val.AddComponent<DvergrCombatAI>();
			dvergrCombatAI.IsMeleeClass = isMelee;
			dvergrCombatAI.IsRangedClass = isRanged;
			dvergrCombatAI.IsClericClass = isCleric;
			Character component5 = val.GetComponent<Character>();
			if ((Object)(object)component5 != (Object)null)
			{
				component5.m_health *= ConfigManager.AllyHealthMultiplier.Value * healthMultiplier;
				component5.m_faction = (Faction)0;
				component5.m_runSpeed = Mathf.Max(component5.m_runSpeed, 6.5f);
				component5.m_walkSpeed = Mathf.Max(component5.m_walkSpeed, 3f);
			}
			Humanoid component6 = val.GetComponent<Humanoid>();
			if ((Object)(object)component6 != (Object)null)
			{
				((Character)component6).m_name = displayName;
			}
			PrefabManager.Instance.AddPrefab(val2);
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	public static class Patch_ZNetScene_Awake_Dvergrs
	{
		[HarmonyPostfix]
		public static void Postfix(ZNetScene __instance)
		{
			if ((Object)(object)__instance == (Object)null || __instance.m_prefabs == null)
			{
				return;
			}
			Logger.LogInfo((object)"Scanning ZNetScene for wild Dvergr prefabs to make tamable...");
			int num = 0;
			foreach (GameObject prefab in __instance.m_prefabs)
			{
				if (!((Object)(object)prefab == (Object)null))
				{
					string text = ((Object)prefab).name.ToLower();
					if ((text.Contains("dverg") || text.Contains("dverger")) && !text.Contains("ally") && (Object)(object)prefab.GetComponent<Humanoid>() != (Object)null && (Object)(object)prefab.GetComponent<MonsterAI>() != (Object)null)
					{
						AllyPrefabManager.MakePrefabTamable(prefab);
						num++;
					}
				}
			}
			Logger.LogInfo((object)$"Successfully injected Taming/Breeding components into {num} wild Dvergr prefabs!");
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class Patch_MonsterAI_UpdateAI_Dvergrs
	{
		[HarmonyPrefix]
		public static void Prefix(MonsterAI __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).gameObject == (Object)null))
			{
				string text = ((Object)((Component)__instance).gameObject).name.ToLower();
				if ((text.Contains("dverg") || text.Contains("dverger")) && !text.Contains("ally"))
				{
					((BaseAI)__instance).m_passiveAggresive = false;
					__instance.m_attackPlayerObjects = false;
					((BaseAI)__instance).m_avoidFire = false;
					__instance.m_fleeIfNotAlerted = false;
				}
			}
		}
	}
	public class CheckMethods
	{
		public static void Dump()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(MonsterAI), "Awake", (Type[])null, (Type[])null);
			Logger.LogInfo((object)("MonsterAI Awake is " + ((methodInfo == null) ? "NULL" : methodInfo.DeclaringType.Name)));
			methodInfo = AccessTools.Method(typeof(BaseAI), "Awake", (Type[])null, (Type[])null);
			Logger.LogInfo((object)("BaseAI Awake is " + ((methodInfo == null) ? "NULL" : methodInfo.DeclaringType.Name)));
		}
	}
	public static class ConfigManager
	{
		public static ConfigEntry<float> TamingTime;

		public static ConfigEntry<string> TamingItems;

		public static ConfigEntry<float> FedDuration;

		public static ConfigEntry<float> ConsumeRange;

		public static ConfigEntry<float> PregnancyDuration;

		public static ConfigEntry<int> BreedingLimit;

		public static ConfigEntry<float> SpecialComboChance;

		public static ConfigEntry<float> PregnancyChance;

		public static ConfigEntry<float> PartnerCheckRange;

		public static ConfigEntry<float> UpdateInterval;

		public static ConfigEntry<float> LevelUpChance;

		public static ConfigEntry<int> MaxBreedingLevel;

		public static ConfigEntry<float> MaxFollowLeash;

		public static ConfigEntry<int> ContractCost;

		public static ConfigEntry<float> AllyHealthMultiplier;

		public static ConfigEntry<float> AllyDamageMultiplier;

		public static ConfigEntry<bool> EnableDebugLogs;

		public static ConfigEntry<bool> DebugFull;

		public static ConfigEntry<bool> DebugAI;

		public static ConfigEntry<bool> DebugBreeding;

		public static ConfigEntry<bool> DebugEquipment;

		public static void LogAI(string message)
		{
			if (EnableDebugLogs != null && EnableDebugLogs.Value && (DebugFull.Value || DebugAI.Value))
			{
				Logger.LogInfo((object)("[AI] " + message));
			}
		}

		public static void LogBreeding(string message)
		{
			if (EnableDebugLogs != null && EnableDebugLogs.Value && (DebugFull.Value || DebugBreeding.Value))
			{
				Logger.LogInfo((object)("[Breeding] " + message));
			}
		}

		public static void LogEquipment(string message)
		{
			if (EnableDebugLogs != null && EnableDebugLogs.Value && (DebugFull.Value || DebugEquipment.Value))
			{
				Logger.LogInfo((object)("[Equipment] " + message));
			}
		}

		public static void LogDebug(string message)
		{
			if (EnableDebugLogs != null && EnableDebugLogs.Value && DebugFull.Value)
			{
				Logger.LogInfo((object)("[General] " + message));
			}
		}

		private static ConfigDescription SyncedConfig(string description)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			return new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} });
		}

		public static void Init(ConfigFile config)
		{
			TamingTime = config.Bind<float>("1 - Taming", "Taming Time", 1800f, SyncedConfig("Time in seconds required to tame a Dvergr."));
			TamingItems = config.Bind<string>("1 - Taming", "Taming Items", "CookedMeat,Coins,Sausages,YggdrasilWood", SyncedConfig("Comma-separated list of item prefabs Dvergrs will eat to tame/breed."));
			FedDuration = config.Bind<float>("1 - Taming", "Fed Duration", 600f, SyncedConfig("Time in seconds a Dvergr stays fed (not hungry) after eating."));
			ConsumeRange = config.Bind<float>("1 - Taming", "Consume Range", 4f, SyncedConfig("Distance from which they can consume food. Increase if they get stuck pushing each other."));
			PregnancyDuration = config.Bind<float>("2 - Breeding", "Pregnancy Duration", 600f, SyncedConfig("Time in seconds before a pregnant Dvergr gives birth."));
			BreedingLimit = config.Bind<int>("2 - Breeding", "Breeding Limit", 4, SyncedConfig("Maximum number of Dvergrs in a 10m radius before they stop breeding."));
			SpecialComboChance = config.Bind<float>("2 - Breeding", "Special Combo Chance", 25f, SyncedConfig("Percentage chance (0-100) to breed a special combo variant if parents are compatible."));
			PregnancyChance = config.Bind<float>("2 - Breeding", "Pregnancy Chance", 0.33f, SyncedConfig("Chance (0.0 to 1.0) of getting pregnant when conditions are met."));
			PartnerCheckRange = config.Bind<float>("2 - Breeding", "Partner Check Range", 10f, SyncedConfig("Distance within which to look for a partner."));
			UpdateInterval = config.Bind<float>("2 - Breeding", "Update Interval", 10f, SyncedConfig("How often (in seconds) the breeding logic checks for partners/pregnancy."));
			LevelUpChance = config.Bind<float>("2 - Breeding", "Level Up Chance", 10f, SyncedConfig("Percentage chance (0-100) for offspring to gain +1 level (star) above their highest level parent."));
			MaxBreedingLevel = config.Bind<int>("2 - Breeding", "Max Breeding Level", 3, SyncedConfig("Maximum level (3 = 2 stars) a Dvergr can reach through breeding."));
			MaxFollowLeash = config.Bind<float>("2.5 - AI", "Max Follow Leash", 40f, SyncedConfig("Max distance (meters) a Dvergr can chase an enemy before dropping aggro to return to the player they are following."));
			ContractCost = config.Bind<int>("3 - Economy", "Contract Cost", 999, SyncedConfig("Cost in coins to purchase a Dvergr Contract from Haldor or Recruiter."));
			AllyHealthMultiplier = config.Bind<float>("4 - Stats", "Health Multiplier", 1f, SyncedConfig("Multiplier applied to base health of Ally Dvergrs."));
			AllyDamageMultiplier = config.Bind<float>("4 - Stats", "Damage Multiplier", 1f, SyncedConfig("Multiplier applied to base damage of Ally Dvergrs."));
			EnableDebugLogs = config.Bind<bool>("5 - Debug", "Enable Debug Logs", false, SyncedConfig("Master switch to enable debug logging."));
			DebugFull = config.Bind<bool>("5 - Debug", "Debug Full", false, SyncedConfig("If true, overrides sub-categories and logs absolutely everything."));
			DebugAI = config.Bind<bool>("5 - Debug", "Debug AI", false, SyncedConfig("Log AI behavior overrides, targeting, and behavior resets."));
			DebugBreeding = config.Bind<bool>("5 - Debug", "Debug Breeding", false, SyncedConfig("Log partner finding, pregnancy, birth, and genetic scaling."));
			DebugEquipment = config.Bind<bool>("5 - Debug", "Debug Equipment", false, SyncedConfig("Log prefab creation, loadout setup, and weapon scaling/upgrades."));
		}
	}
	public static class CustomStavesManager
	{
		public static void Setup()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Setup;
			CreateEarthStaff();
			CreateSpiritStaff();
		}

		private static void CreateEarthStaff()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			if ((Object)(object)PrefabManager.Instance.GetPrefab("DvergerStaffFire") == (Object)null)
			{
				return;
			}
			CustomItem val = new CustomItem("AllyDvergrStaffEarth", "DvergerStaffFire");
			ItemDrop itemDrop = val.ItemDrop;
			itemDrop.m_itemData.m_shared.m_name = "Earth Staff";
			if ((Object)(object)PrefabManager.Instance.GetPrefab("DvergerStaffIce_projectile") != (Object)null)
			{
				GameObject val2 = PrefabManager.Instance.CreateClonedPrefab("AllyDvergrStaffEarth_projectile", "DvergerStaffIce_projectile");
				Projectile component = val2.GetComponent<Projectile>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_damage.m_frost = 0f;
					component.m_damage.m_blunt = 20f;
					component.m_damage.m_poison = 40f;
					component.m_statusEffect = "Tar";
					GameObject prefab = PrefabManager.Instance.GetPrefab("vfx_blob_attack");
					if ((Object)(object)prefab != (Object)null)
					{
						component.m_hitEffects.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
						{
							new EffectData
							{
								m_prefab = prefab,
								m_enabled = true
							}
						};
					}
				}
				itemDrop.m_itemData.m_shared.m_attack.m_attackProjectile = val2;
			}
			ItemManager.Instance.AddItem(val);
		}

		private static void CreateSpiritStaff()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if ((Object)(object)PrefabManager.Instance.GetPrefab("DvergerStaffFire") == (Object)null)
			{
				return;
			}
			CustomItem val = new CustomItem("AllyDvergrStaffSpirit", "DvergerStaffFire");
			ItemDrop itemDrop = val.ItemDrop;
			itemDrop.m_itemData.m_shared.m_name = "Spirit Staff";
			if ((Object)(object)PrefabManager.Instance.GetPrefab("DvergerStaffIce_projectile") != (Object)null)
			{
				GameObject val2 = PrefabManager.Instance.CreateClonedPrefab("AllyDvergrStaffSpirit_projectile", "DvergerStaffIce_projectile");
				Projectile component = val2.GetComponent<Projectile>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_damage.m_frost = 0f;
					component.m_damage.m_blunt = 20f;
					component.m_damage.m_spirit = 60f;
				}
				itemDrop.m_itemData.m_shared.m_attack.m_attackProjectile = val2;
			}
			ItemManager.Instance.AddItem(val);
		}
	}
	public class DummyCheck
	{
		public void Check()
		{
		}
	}
	public class DvergrBerserkerRage : MonoBehaviour
	{
		private Character m_character;

		private void Start()
		{
			m_character = ((Component)this).GetComponent<Character>();
			((MonoBehaviour)this).InvokeRepeating("ApplyRage", 1f, 5f);
		}

		private void ApplyRage()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)m_character == (Object)null) && !m_character.IsDead())
			{
				SEMan sEMan = m_character.GetSEMan();
				if (sEMan != null && !sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("BerserkerRage")))
				{
					SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
					((Object)val).name = "BerserkerRage";
					((StatusEffect)val).m_name = "Rage";
					val.m_speedModifier = 1.15f;
					val.m_staminaRegenMultiplier = 1.3f;
					val.m_healthRegenMultiplier = 1.2f;
					val.m_raiseSkill = (SkillType)7;
					val.m_raiseSkillModifier = 15f;
					sEMan.AddStatusEffect((StatusEffect)(object)val, false, 0, 0f);
				}
			}
		}
	}
	public class DvergrCombatAI : MonoBehaviour
	{
		public bool IsMeleeClass;

		public bool IsRangedClass;

		public bool IsClericClass;

		public bool IsElementalMage;

		private MonsterAI m_monsterAI;

		private Character m_character;

		private bool m_initialized;

		private bool m_isConfigured;

		private float m_clericHealTimer = 15f;

		private float m_healScanTimer;

		private float m_elementRotateTimer;

		private List<ItemData> m_elementalStaves = new List<ItemData>();

		private int m_elementSetIndex;

		private void Awake()
		{
			m_monsterAI = ((Component)this).GetComponent<MonsterAI>();
			m_character = ((Component)this).GetComponent<Character>();
			m_isConfigured = false;
		}

		private void Start()
		{
			ForceAggressiveAI();
			((MonoBehaviour)this).Invoke("ForceAggressiveAI", 1f);
			((MonoBehaviour)this).Invoke("ForceAggressiveAI", 3f);
			((MonoBehaviour)this).Invoke("InjectMagicWeapons", 0.5f);
		}

		private void ForceAggressiveAI()
		{
			if (!((Object)(object)m_monsterAI == (Object)null))
			{
				((BaseAI)m_monsterAI).m_aggravatable = false;
				((BaseAI)m_monsterAI).m_passiveAggresive = false;
				m_monsterAI.m_fleeIfNotAlerted = false;
				((BaseAI)m_monsterAI).m_avoidFire = false;
				((BaseAI)m_monsterAI).m_avoidWater = false;
				m_monsterAI.m_fleeIfLowHealth = 0f;
				m_monsterAI.m_attackPlayerObjects = false;
				if (IsMeleeClass)
				{
					m_monsterAI.m_circulateWhileCharging = false;
					m_monsterAI.m_circulateWhileChargingFlying = false;
					((BaseAI)m_monsterAI).m_randomMoveInterval = 0f;
					((BaseAI)m_monsterAI).m_randomCircleInterval = 0f;
					m_monsterAI.m_alertRange = 30f;
				}
				else if (IsRangedClass)
				{
					m_monsterAI.m_circulateWhileCharging = false;
					m_monsterAI.m_circulateWhileChargingFlying = false;
					((BaseAI)m_monsterAI).m_randomMoveInterval = 10f;
				}
				else if (IsClericClass)
				{
					m_monsterAI.m_circulateWhileCharging = false;
					((BaseAI)m_monsterAI).m_randomMoveInterval = 5f;
					((BaseAI)m_monsterAI).m_randomCircleInterval = 5f;
					m_monsterAI.m_alertRange = 30f;
				}
				if (!m_initialized)
				{
					m_initialized = true;
					ConfigManager.LogAI($"[CombatAI] Forced aggressive AI on {((Object)((Component)this).gameObject).name} (Melee:{IsMeleeClass}, Ranged:{IsRangedClass})");
				}
			}
		}

		private void FixedUpdate()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_monsterAI == (Object)null)
			{
				return;
			}
			if (Time.frameCount % 60 == 0 && (((BaseAI)m_monsterAI).m_aggravatable || ((BaseAI)m_monsterAI).m_passiveAggresive || m_monsterAI.m_fleeIfNotAlerted))
			{
				ConfigManager.LogAI("[CombatAI] AI flags were reset on " + ((Object)((Component)this).gameObject).name + ", re-forcing!");
				ForceAggressiveAI();
			}
			if (IsMeleeClass || IsClericClass)
			{
				((BaseAI)m_monsterAI).m_randomCircleInterval = 9999f;
				m_monsterAI.m_circulateWhileCharging = false;
			}
			GameObject followTarget = m_monsterAI.GetFollowTarget();
			if ((Object)(object)followTarget != (Object)null && (Object)(object)((BaseAI)m_monsterAI).GetTargetCreature() != (Object)null)
			{
				float num = Vector3.Distance(((Component)this).transform.position, followTarget.transform.position);
				if (num > ConfigManager.MaxFollowLeash.Value)
				{
					m_monsterAI.SetTarget((Character)null);
					ConfigManager.LogAI($"[Leash] {((Object)((Component)this).gameObject).name} strayed too far ({num:F1}m > {ConfigManager.MaxFollowLeash.Value}m), dropping aggro to return to leader.");
				}
			}
			if (IsClericClass)
			{
				m_clericHealTimer += Time.fixedDeltaTime;
				m_healScanTimer += Time.fixedDeltaTime;
				if (m_healScanTimer >= 2f)
				{
					m_healScanTimer = 0f;
					UpdateClericAI();
				}
			}
			if (IsElementalMage)
			{
				UpdateElementalMageAI();
			}
		}

		private void UpdateClericAI()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)(object)((BaseAI)m_monsterAI).m_character != (Object)null && ((BaseAI)m_monsterAI).m_character.InAttack()) || m_clericHealTimer < 15f)
			{
				return;
			}
			bool flag = false;
			int level = ((BaseAI)m_monsterAI).m_character.GetLevel();
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 15f, LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" }));
			for (int i = 0; i < array.Length; i++)
			{
				Character component = ((Component)array[i]).GetComponent<Character>();
				if (!((Object)(object)component != (Object)null) || component.IsDead() || (!((Object)(object)component == (Object)(object)((BaseAI)m_monsterAI).m_character) && !component.IsPlayer() && !component.IsTamed()) || !(component.GetHealthPercentage() < 0.8f))
				{
					continue;
				}
				if (!flag)
				{
					((BaseAI)m_monsterAI).m_character.GetZAnim().SetTrigger("StaffCast");
					flag = true;
					m_clericHealTimer = 0f;
					ConfigManager.LogAI($"[Cleric] Triggered AoE HoT Pulse (Level {level})");
					if ((Object)(object)ZNetScene.instance != (Object)null)
					{
						GameObject prefab = ZNetScene.instance.GetPrefab("vfx_Potion_health_medium");
						if ((Object)(object)prefab != (Object)null)
						{
							Object.Instantiate<GameObject>(prefab, ((Component)this).transform.position, Quaternion.identity);
						}
						GameObject prefab2 = ZNetScene.instance.GetPrefab("vfx_creature_soothed");
						if ((Object)(object)prefab2 != (Object)null)
						{
							Object.Instantiate<GameObject>(prefab2, ((Component)this).transform.position + Vector3.up, Quaternion.identity);
						}
					}
				}
				DvergrHoT[] components = ((Component)component).gameObject.GetComponents<DvergrHoT>();
				for (int j = 0; j < components.Length; j++)
				{
					Object.Destroy((Object)(object)components[j]);
				}
				((Component)component).gameObject.AddComponent<DvergrHoT>().Setup(level);
			}
		}

		private ItemData CreateNativeVariant(string baseWeaponName, string newProjectileName = null)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			if ((Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			GameObject val = ObjectDB.instance.GetItemPrefab(baseWeaponName) ?? ZNetScene.instance.GetPrefab(baseWeaponName);
			if ((Object)(object)val == (Object)null)
			{
				ConfigManager.LogAI("[NativeVariant] Base weapon " + baseWeaponName + " not found!");
				return null;
			}
			ItemData val2 = val.GetComponent<ItemDrop>().m_itemData.Clone();
			val2.m_dropPrefab = val;
			SharedData shared = val2.m_shared;
			val2.m_shared = new SharedData();
			FieldInfo[] fields = typeof(SharedData).GetFields(BindingFlags.Instance | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				fieldInfo.SetValue(val2.m_shared, fieldInfo.GetValue(shared));
			}
			val2.m_shared.m_attack = shared.m_attack.Clone();
			if (shared.m_secondaryAttack != null)
			{
				val2.m_shared.m_secondaryAttack = shared.m_secondaryAttack.Clone();
			}
			val2.m_shared.m_attack.m_attackStamina = 0f;
			val2.m_shared.m_attack.m_attackHealth = 0f;
			val2.m_shared.m_attack.m_attackEitr = 0f;
			float value = ConfigManager.AllyDamageMultiplier.Value;
			if (value != 1f)
			{
				val2.m_shared.m_damages.m_damage *= value;
				val2.m_shared.m_damages.m_blunt *= value;
				val2.m_shared.m_damages.m_slash *= value;
				val2.m_shared.m_damages.m_pierce *= value;
				val2.m_shared.m_damages.m_chop *= value;
				val2.m_shared.m_damages.m_pickaxe *= value;
				val2.m_shared.m_damages.m_fire *= value;
				val2.m_shared.m_damages.m_frost *= value;
				val2.m_shared.m_damages.m_lightning *= value;
				val2.m_shared.m_damages.m_poison *= value;
				val2.m_shared.m_damages.m_spirit *= value;
			}
			if (newProjectileName != null)
			{
				GameObject val3 = ObjectDB.instance.GetItemPrefab(newProjectileName) ?? ZNetScene.instance.GetPrefab(newProjectileName);
				if ((Object)(object)val3 != (Object)null)
				{
					val2.m_shared.m_attack.m_attackProjectile = val3;
				}
			}
			return val2;
		}

		private void InjectMagicWeapons()
		{
			if ((Object)(object)m_monsterAI == (Object)null || (Object)(object)((BaseAI)m_monsterAI).m_character == (Object)null)
			{
				return;
			}
			Character character = ((BaseAI)m_monsterAI).m_character;
			Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
			if ((Object)(object)val == (Object)null || val.GetInventory() == null)
			{
				return;
			}
			ConfigManager.LogAI($"[RuntimeBuilder] {((Object)((Component)this).gameObject).name} - inventory has {val.GetInventory().GetAllItems().Count} items");
			foreach (ItemData allItem in val.GetInventory().GetAllItems())
			{
				if (allItem.IsWeapon() && (Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name.Contains("Heal"))
				{
					allItem.m_shared.m_aiAttackInterval = 30f;
					ConfigManager.LogAI("[RuntimeBuilder] NERFED heal staff: " + ((Object)allItem.m_dropPrefab).name + " -> interval=30s");
				}
			}
			if (((Object)((Component)this).gameObject).name.Contains("SpellswordFire"))
			{
				ItemData val2 = CreateNativeVariant("DvergerStaffFire_fireball");
				if (val2 != null)
				{
					val2.m_shared.m_aiAttackInterval = 15f;
					val.GetInventory().AddItem(val2);
					ConfigManager.LogAI("[SpellswordFire] Injected Native Fireball into memory inventory!");
				}
			}
			else if (((Object)((Component)this).gameObject).name.Contains("SpellswordIce"))
			{
				ItemData val3 = CreateNativeVariant("DvergerStaffIce_icebolt");
				if (val3 != null)
				{
					val3.m_shared.m_aiAttackInterval = 15f;
					val.GetInventory().AddItem(val3);
					ConfigManager.LogAI("[SpellswordIce] Injected Native Icebolt into memory inventory!");
				}
			}
			if (!IsElementalMage)
			{
				return;
			}
			m_elementalStaves.Clear();
			m_elementalStaves.Add(CreateNativeVariant("DvergerStaffFire_fireball"));
			m_elementalStaves.Add(CreateNativeVariant("DvergerStaffIce_icebolt"));
			m_elementalStaves.Add(CreateNativeVariant("DvergerStaffFire_fireball", "GoblinShaman_projectile_fireball"));
			m_elementalStaves.RemoveAll((ItemData x) => x == null);
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData allItem2 in val.GetInventory().GetAllItems())
			{
				if (allItem2.IsWeapon())
				{
					val.UnequipItem(allItem2, true);
					list.Add(allItem2);
				}
			}
			foreach (ItemData item in list)
			{
				val.GetInventory().RemoveItem(item);
			}
			if (m_elementalStaves.Count > 0)
			{
				val.GetInventory().AddItem(m_elementalStaves[0]);
				val.EquipItem(m_elementalStaves[0], true);
			}
			ConfigManager.LogAI($"[ElementalMage] Loaded {m_elementalStaves.Count} elements into memory cache.");
			m_elementRotateTimer = 0f;
		}

		private void UpdateElementalMageAI()
		{
			if ((Object)(object)((BaseAI)m_monsterAI).m_character == (Object)null)
			{
				return;
			}
			Character character = ((BaseAI)m_monsterAI).m_character;
			Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Inventory inventory = val.GetInventory();
			if (inventory == null || m_elementalStaves.Count == 0)
			{
				return;
			}
			m_elementRotateTimer += Time.fixedDeltaTime;
			if (!(m_elementRotateTimer >= 10f))
			{
				return;
			}
			m_elementRotateTimer = 0f;
			m_elementSetIndex = (m_elementSetIndex + 1) % m_elementalStaves.Count;
			ItemData val2 = m_elementalStaves[m_elementSetIndex];
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.IsWeapon())
				{
					val.UnequipItem(allItem, true);
					list.Add(allItem);
				}
			}
			foreach (ItemData item in list)
			{
				inventory.RemoveItem(item);
			}
			inventory.AddItem(val2);
			val.EquipItem(val2, true);
			ConfigManager.LogAI($"[ElementalMage] Swapped to element {m_elementSetIndex}");
		}
	}
	public class DvergrGenetics : MonoBehaviour
	{
		public enum Gender
		{
			Male,
			Female
		}

		private ZNetView m_nview;

		private Humanoid m_humanoid;

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_humanoid = ((Component)this).GetComponent<Humanoid>();
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid() && m_nview.IsOwner() && m_nview.GetZDO().GetInt("dvergr_gender", -1) == -1)
			{
				Gender gender = ((!(Random.value > 0.5f)) ? Gender.Female : Gender.Male);
				m_nview.GetZDO().Set("dvergr_gender", (int)gender);
				ConfigManager.LogBreeding($"[Genetics] {((Object)((Component)this).gameObject).name} randomly assigned gender: {gender}");
			}
		}

		private void LateUpdate()
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || !((Object)(object)Player.m_localPlayer != (Object)null) || !((Object)(object)((Humanoid)Player.m_localPlayer).GetHoverObject() != (Object)null))
			{
				return;
			}
			GameObject hoverObject = ((Humanoid)Player.m_localPlayer).GetHoverObject();
			if ((!((Object)(object)hoverObject == (Object)(object)((Component)this).gameObject) && !hoverObject.transform.IsChildOf(((Component)this).transform)) || !((Object)(object)Hud.instance != (Object)null) || !((Object)(object)Hud.instance.m_hoverName != (Object)null))
			{
				return;
			}
			int num = m_nview.GetZDO().GetInt("dvergr_gender", -1);
			if (num != -1)
			{
				Gender gender = (Gender)num;
				string text = $"\n({gender})";
				DvergrProcreation component = ((Component)this).GetComponent<DvergrProcreation>();
				if ((Object)(object)component != (Object)null && component.IsPregnant())
				{
					int pregnancyTimeLeft = component.GetPregnancyTimeLeft();
					string text2 = ((pregnancyTimeLeft > 0) ? $"{pregnancyTimeLeft}s" : "Imminent");
					text = text + "\n<color=yellow>Pregnant: " + text2 + "</color>";
				}
				DvergrTameable component2 = ((Component)this).GetComponent<DvergrTameable>();
				if ((Object)(object)component2 != (Object)null && ((Tameable)component2).IsHungry())
				{
					text += "\n<color=red>Hungry</color>";
				}
				TextMeshProUGUI hoverName = Hud.instance.m_hoverName;
				((TMP_Text)hoverName).text = ((TMP_Text)hoverName).text + text;
			}
		}

		public Gender GetGender()
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return Gender.Male;
			}
			return (Gender)m_nview.GetZDO().GetInt("dvergr_gender", 0);
		}
	}
	public class DvergrHoT : MonoBehaviour
	{
		private Character m_target;

		private int m_ticksRemaining = 5;

		private float m_healAmountPerTick = 10f;

		private float m_tickTimer;

		public void Setup(int clericLevel)
		{
			m_target = ((Component)this).GetComponent<Character>();
			m_healAmountPerTick = 5f + 5f * (float)clericLevel;
			m_ticksRemaining = 5;
			m_tickTimer = 1f;
			object[] array = new object[4];
			Character target = m_target;
			array[0] = ((target != null) ? ((Object)target).name : null);
			array[1] = clericLevel;
			array[2] = m_healAmountPerTick;
			array[3] = m_ticksRemaining;
			ConfigManager.LogAI(string.Format("[Cleric] Applied HoT to {0} (Lvl {1}): {2} HP/s for {3}s", array));
		}

		private void FixedUpdate()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_target == (Object)null || m_target.IsDead())
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			m_tickTimer += Time.fixedDeltaTime;
			if (!(m_tickTimer >= 1f))
			{
				return;
			}
			m_tickTimer = 0f;
			m_ticksRemaining--;
			m_target.Heal(m_healAmountPerTick, true);
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("vfx_Potion_health_medium");
				if ((Object)(object)prefab != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab, ((Component)m_target).transform.position, Quaternion.identity);
				}
			}
			if (m_ticksRemaining <= 0)
			{
				Object.Destroy((Object)(object)this);
			}
		}
	}
	public class DvergrProcreation : MonoBehaviour
	{
		private ZNetView m_nview;

		private Character m_character;

		private BaseAI m_baseAI;

		private DvergrGenetics m_genetics;

		private Coroutine m_birthingCoroutine;

		public EffectList m_birthEffects = new EffectList();

		public float m_spawnOffset = 1f;

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_character = ((Component)this).GetComponent<Character>();
			m_baseAI = ((Component)this).GetComponent<BaseAI>();
			m_genetics = ((Component)this).GetComponent<DvergrGenetics>();
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				((MonoBehaviour)this).InvokeRepeating("Procreate", Random.Range(0f, ConfigManager.UpdateInterval.Value), ConfigManager.UpdateInterval.Value);
			}
		}

		public bool IsPregnant()
		{
			if ((Object)(object)m_nview != (Object)null && m_nview.IsValid())
			{
				return m_nview.GetZDO().GetLong("pregnant", 0L) != 0;
			}
			return false;
		}

		public int GetPregnancyTimeLeft()
		{
			if (!IsPregnant())
			{
				return 0;
			}
			long num = m_nview.GetZDO().GetLong("pregnant", 0L);
			if (num == 0L)
			{
				return 0;
			}
			DateTime dateTime = new DateTime(num);
			double totalSeconds = (ZNet.instance.GetTime() - dateTime).TotalSeconds;
			int num2 = Mathf.CeilToInt((float)((double)ConfigManager.PregnancyDuration.Value - totalSeconds));
			return Mathf.Max(0, num2);
		}

		private void MakePregnant(string partnerPrefab, int partnerLevel)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_nview.GetZDO().Set("pregnant", ZNet.instance.GetTime().Ticks);
				m_nview.GetZDO().Set("dvergr_partner_prefab", partnerPrefab);
				m_nview.GetZDO().Set("dvergr_partner_level", partnerLevel);
			}
		}

		private void ResetPregnancy()
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_nview.GetZDO().Set("pregnant", 0L);
				m_nview.GetZDO().Set("dvergr_partner_prefab", "");
			}
		}

		private bool ReadyForProcreation()
		{
			if (IsPregnant())
			{
				return false;
			}
			if ((Object)(object)m_character == (Object)null || !m_character.IsTamed())
			{
				return false;
			}
			if ((Object)(object)m_baseAI != (Object)null && m_baseAI.IsAlerted())
			{
				return false;
			}
			DvergrTameable component = ((Component)this).GetComponent<DvergrTameable>();
			if ((Object)(object)component != (Object)null && ((Tameable)component).IsHungry())
			{
				return false;
			}
			return true;
		}

		private void Procreate()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if (!m_nview.IsValid() || !m_nview.IsOwner())
			{
				return;
			}
			if (IsPregnant())
			{
				long num = m_nview.GetZDO().GetLong("pregnant", 0L);
				if (num != 0L)
				{
					DateTime dateTime = new DateTime(num);
					if ((ZNet.instance.GetTime() - dateTime).TotalSeconds > (double)ConfigManager.PregnancyDuration.Value && m_birthingCoroutine == null)
					{
						m_birthingCoroutine = ((MonoBehaviour)this).StartCoroutine(BirthingProcess());
					}
				}
			}
			else
			{
				if (!ReadyForProcreation())
				{
					return;
				}
				string text = ((Object)((Component)this).gameObject).name.Replace("(Clone)", "").Trim();
				int num2 = 0;
				Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 10f, LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" }));
				for (int i = 0; i < array.Length; i++)
				{
					Character component = ((Component)array[i]).GetComponent<Character>();
					if ((Object)(object)component != (Object)null && component.IsTamed() && (Object)(object)((Component)component).GetComponent<DvergrGenetics>() != (Object)null)
					{
						num2++;
					}
				}
				if (num2 >= ConfigManager.BreedingLimit.Value)
				{
					ConfigManager.LogBreeding($"[Procreation] {text} halted breeding: Population limit reached ({num2}/{ConfigManager.BreedingLimit.Value}) tamed Dvergrs within 10m.");
					return;
				}
				array = Physics.OverlapSphere(((Component)this).transform.position, ConfigManager.PartnerCheckRange.Value, LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" }));
				for (int i = 0; i < array.Length; i++)
				{
					Character component2 = ((Component)array[i]).GetComponent<Character>();
					if (!((Object)(object)component2 != (Object)null) || !((Object)(object)((Component)component2).gameObject != (Object)(object)((Component)this).gameObject))
					{
						continue;
					}
					DvergrGenetics component3 = ((Component)component2).GetComponent<DvergrGenetics>();
					if (!((Object)(object)component3 != (Object)null) || !((Object)(object)m_genetics != (Object)null) || m_genetics.GetGender() == component3.GetGender())
					{
						continue;
					}
					DvergrProcreation component4 = ((Component)component2).GetComponent<DvergrProcreation>();
					if (!((Object)(object)component4 != (Object)null) || !component4.ReadyForProcreation())
					{
						continue;
					}
					ConfigManager.LogBreeding($"[Procreation] {text} ({m_genetics.GetGender()}) found compatible partner {((Object)((Component)component2).gameObject).name} ({component3.GetGender()})");
					if (Random.value <= ConfigManager.PregnancyChance.Value)
					{
						string text2 = ((Object)((Component)component2).gameObject).name.Replace("(Clone)", "").Trim();
						int level = component2.GetLevel();
						if (m_genetics.GetGender() == DvergrGenetics.Gender.Female)
						{
							MakePregnant(text2, level);
							component4.ResetPregnancy();
							ConfigManager.LogBreeding("[Procreation] " + text + " is now PREGNANT!");
						}
						else
						{
							string partnerPrefab = ((Object)((Component)this).gameObject).name.Replace("(Clone)", "").Trim();
							int level2 = m_character.GetLevel();
							component4.MakePregnant(partnerPrefab, level2);
							ResetPregnancy();
							ConfigManager.LogBreeding("[Procreation] Partner " + text2 + " is now PREGNANT!");
						}
					}
					else
					{
						ConfigManager.LogBreeding("[Procreation] " + text + " failed pregnancy chance roll.");
					}
					break;
				}
			}
		}

		private IEnumerator BirthingProcess()
		{
			string text = m_nview.GetZDO().GetString("dvergr_partner_prefab", "");
			int num = m_nview.GetZDO().GetInt("dvergr_partner_level", 1);
			ResetPregnancy();
			string text2 = ((Object)((Component)this).gameObject).name.Replace("(Clone)", "").Trim();
			string text3 = DetermineOffspring(text2, text);
			ConfigManager.LogBreeding($"[Procreation] BIRTHING PROCESS START: ParentA={text2}(Lvl {m_character.GetLevel()}), ParentB={text}(Lvl {num}) -> Outcome={text3}");
			GameObject prefab = PrefabManager.Instance.GetPrefab(text3);
			if ((Object)(object)prefab != (Object)null)
			{
				Vector3 val = ((Component)this).transform.position + ((Component)this).transform.forward * m_spawnOffset;
				Character component = Object.Instantiate<GameObject>(prefab, val, Quaternion.LookRotation(((Component)this).transform.forward)).GetComponent<Character>();
				if ((Object)(object)component != (Object)null && (Object)(object)m_character != (Object)null)
				{
					component.SetTamed(m_character.IsTamed());
					int num2 = Mathf.Max(m_character.GetLevel(), num);
					if ((float)Random.Range(0, 100) < ConfigManager.LevelUpChance.Value)
					{
						num2++;
						ConfigManager.LogBreeding("[Procreation] " + text3 + " offspring triggered LEVEL UP CHANCE! Level increased.");
					}
					num2 = Mathf.Clamp(num2, 1, ConfigManager.MaxBreedingLevel.Value);
					component.SetLevel(num2);
					ConfigManager.LogBreeding($"[Procreation] Birthed {text3} at Level {num2} (Max {ConfigManager.MaxBreedingLevel.Value})");
				}
				if (m_birthEffects != null && m_birthEffects.HasEffects())
				{
					m_birthEffects.Create(((Component)this).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
				}
			}
			m_birthingCoroutine = null;
			yield break;
		}

		private string DetermineOffspring(string parentA, string parentB)
		{
			bool flag = parentA.Contains("Fire") || parentB.Contains("Fire");
			bool flag2 = parentA.Contains("Ice") || parentB.Contains("Ice");
			bool flag3 = parentA.Contains("Support") || parentB.Contains("Support");
			bool flag4 = parentA.Contains("Rogue") || parentB.Contains("Rogue");
			bool flag5 = parentA.Contains("Warrior") || parentB.Contains("Warrior");
			bool flag6 = parentA.Contains("Cleric") || parentB.Contains("Cleric");
			if ((float)Random.Range(0, 100) < ConfigManager.SpecialComboChance.Value)
			{
				if (flag4 && !flag && !flag2 && !flag3 && !flag5 && !flag6)
				{
					return "AllyDvergrWarrior";
				}
				if (flag3 && !flag4 && !flag && !flag2 && !flag5 && !flag6)
				{
					return "AllyDvergrCleric";
				}
				if (flag && flag2)
				{
					return "AllyDvergrMageElemental";
				}
				if (flag4 && flag && !flag2)
				{
					return "AllyDvergrSpellswordFire";
				}
				if (flag4 && flag2 && !flag)
				{
					return "AllyDvergrSpellswordIce";
				}
				if (flag5 && flag5)
				{
					return "AllyDvergrBerserker";
				}
			}
			if (!(Random.value > 0.5f))
			{
				return parentB;
			}
			return parentA;
		}
	}
	public class DvergrTameable : Tameable, Hoverable
	{
		public string GetHoverText()
		{
			string text = ((Tameable)this).GetHoverText();
			DvergrProcreation component = ((Component)this).GetComponent<DvergrProcreation>();
			if ((Object)(object)component != (Object)null && component.IsPregnant())
			{
				int pregnancyTimeLeft = component.GetPregnancyTimeLeft();
				string text2 = ((pregnancyTimeLeft > 0) ? $"{pregnancyTimeLeft}s" : "Imminent");
				text = text + "\n<color=yellow>Pregnant: " + text2 + "</color>";
			}
			if (((Tameable)this).IsHungry())
			{
				text += "\n<color=red>Hungry</color>";
			}
			return text;
		}

		public string GetHoverName()
		{
			return ((Tameable)this).GetHoverName();
		}
	}
	public class DvergrWeaponScaler : MonoBehaviour
	{
		private Humanoid m_humanoid;

		private Character m_character;

		private ZNetView m_nview;

		private bool m_scaled;

		private void Start()
		{
			m_humanoid = ((Component)this).GetComponent<Humanoid>();
			m_character = ((Component)this).GetComponent<Character>();
			m_nview = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)m_nview != (Object)null && m_nview.IsValid() && m_nview.IsOwner())
			{
				((MonoBehaviour)this).Invoke("DoScaleWeapons", 1f);
			}
		}

		private void DoScaleWeapons()
		{
			if (m_scaled || (Object)(object)m_humanoid == (Object)null || (Object)(object)m_character == (Object)null)
			{
				return;
			}
			m_scaled = true;
			int level = m_character.GetLevel();
			if (level <= 1)
			{
				return;
			}
			string prefabName = Utils.GetPrefabName(((Component)this).gameObject);
			ConfigManager.LogEquipment($"[WeaponScaler] Scaling {prefabName} (level {level})");
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			if (level == 2)
			{
				dictionary["AllyDvergr_SwordBronze"] = "AllyDvergr_SwordIron";
				dictionary["AllyDvergr_MaceBronze"] = "AllyDvergr_MaceIron";
				dictionary["ShieldBanded"] = "ShieldSilver";
				dictionary["AllyDvergr_Battleaxe"] = "AllyDvergr_BattleaxeBlackmetal";
			}
			else
			{
				dictionary["AllyDvergr_SwordBronze"] = "AllyDvergr_SwordBlackmetal";
				dictionary["AllyDvergr_MaceBronze"] = "AllyDvergr_MaceBlackmetal";
				dictionary["ShieldBanded"] = "ShieldBlackmetal";
				dictionary["AllyDvergr_Battleaxe"] = "AllyDvergr_BattleaxeBlackmetal";
			}
			ItemData rightItem = m_humanoid.GetRightItem();
			if (rightItem != null)
			{
				m_humanoid.UnequipItem(rightItem, true);
			}
			ItemData leftItem = m_humanoid.GetLeftItem();
			if (leftItem != null)
			{
				m_humanoid.UnequipItem(leftItem, true);
			}
			List<ItemData> allItems = m_humanoid.GetInventory().GetAllItems();
			List<int> list = new List<int>();
			List<string> list2 = new List<string>();
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val = allItems[i];
				string text = (((Object)(object)val.m_dropPrefab != (Object)null) ? ((Object)val.m_dropPrefab).name : "");
				if (!string.IsNullOrEmpty(text) && dictionary.ContainsKey(text))
				{
					list.Add(i);
					list2.Add(dictionary[text]);
					ConfigManager.LogEquipment("[WeaponScaler] Upgrading " + text + " -> " + dictionary[text]);
				}
			}
			for (int num = list.Count - 1; num >= 0; num--)
			{
				m_humanoid.GetInventory().RemoveItem(list[num]);
			}
			List<GameObject> list3 = new List<GameObject>();
			foreach (string item in list2)
			{
				GameObject orCloneWeaponWithMeleeAnim = AllyPrefabManager.GetOrCloneWeaponWithMeleeAnim(item);
				if ((Object)(object)orCloneWeaponWithMeleeAnim != (Object)null)
				{
					list3.Add(orCloneWeaponWithMeleeAnim);
					bool flag = m_humanoid.GetInventory().AddItem(orCloneWeaponWithMeleeAnim, 1);
					ConfigManager.LogEquipment($"[WeaponScaler] Added {item} to inventory: {flag}");
					if (!flag)
					{
						continue;
					}
					foreach (ItemData allItem in m_humanoid.GetInventory().GetAllItems())
					{
						if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == item)
						{
							m_humanoid.EquipItem(allItem, true);
							ConfigManager.LogEquipment("[WeaponScaler] Equipped " + item + " successfully!");
							break;
						}
					}
				}
				else
				{
					Logger.LogWarning((object)("[WeaponScaler] Could not find replacement prefab: " + item));
				}
			}
			if (list3.Count <= 0)
			{
				return;
			}
			List<GameObject> list4 = new List<GameObject>(m_humanoid.m_defaultItems);
			foreach (GameObject item2 in list3)
			{
				if (!list4.Contains(item2))
				{
					list4.Add(item2);
				}
			}
			m_humanoid.m_defaultItems = list4.ToArray();
		}
	}
	[BepInPlugin("wubarrk.dvergrallies", "DvergrAllies", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "wubarrk.dvergrallies";

		public const string PluginName = "DvergrAllies";

		public const string PluginVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("wubarrk.dvergrallies");

		private void Awake()
		{
			ConfigManager.Init(((BaseUnityPlugin)this).Config);
			PrefabManager.OnVanillaPrefabsAvailable += CustomStavesManager.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += AllyPrefabManager.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += RecruiterManager.Setup;
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DvergrAllies v1.0.0 has loaded!");
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
		}
	}
	public static class RecruiterManager
	{
		public static void Setup()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Setup;
			CreateContractItem();
		}

		private static void CreateContractItem()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0064: 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_00a1: Expected O, but got Unknown
			if (!((Object)(object)PrefabManager.Instance.GetPrefab("Amber") == (Object)null))
			{
				CustomItem val = new CustomItem("DvergrContract", "Amber");
				ItemDrop itemDrop = val.ItemDrop;
				itemDrop.m_itemData.m_shared.m_name = "Dvergr Contract";
				itemDrop.m_itemData.m_shared.m_description = "A binding contract. Consume to summon a loyal Dvergr Rogue.";
				itemDrop.m_itemData.m_shared.m_itemType = (ItemType)2;
				SummonDvergrStatusEffect summonDvergrStatusEffect = ScriptableObject.CreateInstance<SummonDvergrStatusEffect>();
				((Object)summonDvergrStatusEffect).name = "SE_SummonDvergr";
				((StatusEffect)summonDvergrStatusEffect).m_name = "Summoning";
				((StatusEffect)summonDvergrStatusEffect).m_ttl = 0.1f;
				ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)summonDvergrStatusEffect, false));
				itemDrop.m_itemData.m_shared.m_consumeStatusEffect = (StatusEffect)(object)summonDvergrStatusEffect;
				itemDrop.m_itemData.m_shared.m_food = 0f;
				itemDrop.m_itemData.m_shared.m_foodStamina = 0f;
				itemDrop.m_itemData.m_shared.m_foodRegen = 0f;
				itemDrop.m_itemData.m_shared.m_value = 0;
				itemDrop.m_itemData.m_dropPrefab = val.ItemPrefab;
				ItemManager.Instance.AddItem(val);
			}
		}
	}
	public class SummonDvergrStatusEffect : StatusEffect
	{
		private readonly string[] baseTypes = new string[5] { "AllyDvergrRogue", "AllyDvergrMage", "AllyDvergrMageFire", "AllyDvergrMageIce", "AllyDvergrMageSupport" };

		public override void Setup(Character character)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			((StatusEffect)this).Setup(character);
			if (!((Object)(object)character != (Object)null) || !character.IsPlayer())
			{
				return;
			}
			List<string> list = new List<string>(baseTypes);
			if (AllyPrefabManager.CustomVariants != null)
			{
				foreach (CustomDvergrDef customVariant in AllyPrefabManager.CustomVariants)
				{
					list.Add(customVariant.PrefabName);
				}
			}
			string text = list[Random.Range(0, list.Count)];
			GameObject prefab = PrefabManager.Instance.GetPrefab(text);
			if ((Object)(object)prefab != (Object)null)
			{
				Vector3 val = ((Component)character).transform.position + ((Component)character).transform.forward * 2f;
				Tameable component = Object.Instantiate<GameObject>(prefab, val, ((Component)character).transform.rotation).GetComponent<Tameable>();
				if ((Object)(object)component != (Object)null)
				{
					component.Tame();
				}
				string text2 = text.Replace("AllyDvergr", "");
				if (text2 == "Rogue")
				{
					text2 = "Rogue";
				}
				character.Message((MessageType)2, "Summoned an Ally Dvergr " + text2 + "!", 0, (Sprite)null);
			}
		}
	}
	[HarmonyPatch(typeof(Trader))]
	public static class Patches_Trader
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void TraderStartPostfix(Trader __instance)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			if (!((Object)((Component)__instance).gameObject).name.Contains("Haldor"))
			{
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("DvergrContract");
			if (!((Object)(object)prefab != (Object)null))
			{
				return;
			}
			foreach (TradeItem item in __instance.m_items)
			{
				if ((Object)(object)item.m_prefab != (Object)null && ((Object)((Component)item.m_prefab).gameObject).name == "DvergrContract")
				{
					return;
				}
			}
			TradeItem val = new TradeItem
			{
				m_prefab = prefab.GetComponent<ItemDrop>(),
				m_price = ConfigManager.ContractCost.Value,
				m_stack = 1,
				m_requiredGlobalKey = ""
			};
			FieldInfo[] fields = typeof(TradeItem).GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType == typeof(string) && fieldInfo.GetValue(val) == null)
				{
					fieldInfo.SetValue(val, "");
				}
			}
			__instance.m_items.Add(val);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "DvergrAllies";

		public const string PLUGIN_NAME = "DvergrAllies";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}