Decompiled source of Game Settings v1.1.1

OutwardGameSettings.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Xml;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using OutwardGameSettings.BepInEx.Configs;
using OutwardGameSettings.Events;
using OutwardGameSettings.Managers;
using OutwardGameSettings.Serializable;
using OutwardGameSettings.Utility.Enemies;
using OutwardGameSettings.Utility.Enemies.AI;
using OutwardGameSettings.Utility.Enemies.AI.Conditions;
using OutwardGameSettings.Utility.Enemies.AI.Effects;
using OutwardGameSettings.Utility.Enemies.Data;
using OutwardGameSettings.Utility.Enemies.Visuals;
using OutwardGameSettings.Utility.Enemies.Waves;
using OutwardGameSettings.Utility.Enums;
using OutwardGameSettings.Utility.Helpers;
using OutwardGameSettings.Utility.Helpers.Generic;
using OutwardGameSettings.Utility.Seasons;
using OutwardGameSettings.Utility.Timer.Controllers;
using OutwardModsCommunicator.EventBus;
using OutwardModsCommunicator.Managers;
using SideLoader;
using SideLoader.Model;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OutwardGameSettings")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OutwardGameSettings")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace OutwardGameSettings
{
	[BepInPlugin("gymmed.outward_game_settings", "Outward Game Settings", "1.1.1")]
	public class OutwardGameSettings : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ResourcesPrefabManager), "Load")]
		public class ResourcesPrefabManager_Load
		{
			private static void Postfix(ResourcesPrefabManager __instance)
			{
				try
				{
					EnchantmentsHelper.FixFilterRecipe();
					EnemyEquipmentManager.Instance.Init();
					EnemyWaveManager.Instance.Init();
				}
				catch (Exception ex)
				{
					LogMessage("ResourcesPrefabManager@Load error: \"" + ex.Message + "\"");
				}
			}
		}

		public const string GUID = "gymmed.outward_game_settings";

		public const string NAME = "Outward Game Settings";

		public const string VERSION = "1.1.1";

		public static string prefix = "[GymMed-Game-Settings]";

		internal static ManualLogSource Log;

		internal void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogMessage((object)"Hello world from Outward Game Settings 1.1.1!");
			EnchantmentRecipesConfigs.Init((BaseUnityPlugin)(object)this);
			SkillsExpertiseConfigs.Init((BaseUnityPlugin)(object)this);
			EnemiesConfigs.Init((BaseUnityPlugin)(object)this);
			EnemyAmbushesConfigs.Init((BaseUnityPlugin)(object)this);
			EnemyWarsConfigs.Init((BaseUnityPlugin)(object)this);
			EnemySpawnsConfigs.Init((BaseUnityPlugin)(object)this);
			SeasonsConfigs.Init((BaseUnityPlugin)(object)this);
			SeasonsManager.Instance.Init();
			EventBusRegister.RegisterEvents();
			new Harmony("gymmed.outward_game_settings").PatchAll();
		}

		internal void Update()
		{
		}

		public static void LogMessage(string message)
		{
			Log.LogMessage((object)(prefix + " " + message));
		}
	}
}
namespace OutwardGameSettings.Utility.Timer.Controllers
{
	public class InGameEventController
	{
		private float chancePerCyclePercent = 1.3888f;

		private int checksPerCycle = 72;

		private float baseChance;

		private float accumulator;

		public float ChancePerCyclePercent
		{
			get
			{
				return chancePerCyclePercent;
			}
			set
			{
				chancePerCyclePercent = value;
			}
		}

		public int ChecksPerCycle
		{
			get
			{
				return checksPerCycle;
			}
			set
			{
				checksPerCycle = value;
			}
		}

		public float Accumulator
		{
			get
			{
				return accumulator;
			}
			set
			{
				accumulator = value;
			}
		}

		public InGameEventController(float chancePerCyclePercent = 1.3888f, int checksPerCycle = 72)
		{
			CalculateHourlyChances(chancePerCyclePercent, checksPerCycle);
		}

		public void CalculateHourlyChances(float chancePerCyclePercent = 1.3888f)
		{
			ChancePerCyclePercent = chancePerCyclePercent;
			CalculateHourlyChances();
		}

		public void CalculateHourlyChances(float chancePerCyclePercent = 1.3888f, int checksPerCycle = 72)
		{
			ChancePerCyclePercent = chancePerCyclePercent;
			ChecksPerCycle = checksPerCycle;
			CalculateHourlyChances();
		}

		public void CalculateHourlyChances()
		{
			float num = chancePerCyclePercent / 100f;
			baseChance = 1f - Mathf.Pow(1f - num, 1f / (float)checksPerCycle);
		}

		public void SimulateCheck()
		{
			Accumulator += baseChance;
			Accumulator = Mathf.Min(Accumulator, 1f);
		}

		public bool PassedHourlyCheck()
		{
			Accumulator += baseChance;
			if (Random.Range(0f, 1f) < Accumulator)
			{
				Accumulator = 0f;
				return true;
			}
			return false;
		}
	}
}
namespace OutwardGameSettings.Utility.Seasons
{
	public class BasicSeason
	{
		private Season season;

		private CustomSeasons customSeason;

		private bool isSafe;

		public Action OnHour { get; set; }

		public Season Season
		{
			get
			{
				return season;
			}
			set
			{
				season = value;
			}
		}

		public CustomSeasons CustomSeason
		{
			get
			{
				return customSeason;
			}
			set
			{
				customSeason = value;
			}
		}

		public bool IsSafe
		{
			get
			{
				return isSafe;
			}
			set
			{
				isSafe = value;
			}
		}

		public BasicSeason(Season season, CustomSeasons customSeason)
		{
			Season = season;
			CustomSeason = customSeason;
		}

		public void init()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			EnvironmentConditions.Instance.Seasons.Add(Season);
			if (EnvironmentConditions.Instance.Seasons.Count > 0)
			{
				((Component)Season).transform.SetParent(((Component)EnvironmentConditions.Instance.Seasons[0]).transform.parent);
			}
			else
			{
				GameObject val = new GameObject("Seasons");
				val.transform.SetParent(((Component)EnvironmentConditions.Instance).transform);
				((Component)Season).transform.SetParent(val.transform);
			}
			SeasonsManager.FillWeatherEffects(ref WeatherManagerNew.Instance.RainEffects);
			SeasonsManager.FillWeatherEffects(ref WeatherManagerNew.Instance.SnowEffects);
			SeasonsManager.FillWeatherEffects(ref WeatherManagerNew.Instance.SeasonEffects);
		}
	}
}
namespace OutwardGameSettings.Utility.Helpers
{
	public static class AreaFamiliesHelper
	{
		public static bool IsAreaInAreaFamily(AreaEnum area)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Area area2 = AreaManager.Instance.GetArea(area);
			if (area2 == null)
			{
				return false;
			}
			AreaFamily[] areaFamilies = AreaManager.AreaFamilies;
			for (int i = 0; i < areaFamilies.Length; i++)
			{
				string[] familyKeywords = areaFamilies[i].FamilyKeywords;
				foreach (string value in familyKeywords)
				{
					if (area2.SceneName.Contains(value))
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	public static class AreasHelper
	{
		public static AreaEnum[] Towns;

		public static AreaEnum[] OpenAreas;

		public static bool IsCurrentAreaInOpenWorld()
		{
			return IsAreaInOpenWorld(AreaManager.Instance.CurrentArea);
		}

		public static bool IsAreaInOpenWorld(Area area)
		{
			return IsAreaInEnumList(area, OpenAreas);
		}

		public static bool IsAreaInEnumList(Area area, IList<AreaEnum> list)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			AreaEnum areaEnumFromArea = GetAreaEnumFromArea(area);
			return list.Contains(areaEnumFromArea);
		}

		public static AreaEnum GetAreaEnumFromArea(Area area)
		{
			return (AreaEnum)area.ID;
		}

		static AreasHelper()
		{
			AreaEnum[] array = new AreaEnum[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Towns = (AreaEnum[])(object)array;
			AreaEnum[] array2 = new AreaEnum[6];
			RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			OpenAreas = (AreaEnum[])(object)array2;
		}
	}
	public static class CharacterHelpers
	{
		public static int GetLobbiesSilverWorth()
		{
			Character val = null;
			int num = 0;
			foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
			{
				val = item.ControlledCharacter;
				if (val == null)
				{
					continue;
				}
				CharacterInventory inventory = val.Inventory;
				if (inventory != null)
				{
					_ = inventory.TotalValue;
					if (true)
					{
						num += val.Inventory.TotalValue;
					}
				}
			}
			return num;
		}

		public static void FixCharacterAINullOnQuestEvent(CharacterAI charAI)
		{
			FieldInfo field = typeof(CharacterAI).GetField("m_aiActiveOnQuestEvent", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field != null && field.GetValue(charAI) == null)
			{
				object value = Activator.CreateInstance(field.FieldType);
				field.SetValue(charAI, value);
			}
		}
	}
	public class ConfigsHelper
	{
		public static int GetPercentageValueFromConfig(int originalValue)
		{
			if (originalValue < 0)
			{
				return 0;
			}
			if (originalValue > 100)
			{
				return 100;
			}
			return originalValue;
		}
	}
	public class EnchantmentsHelper
	{
		public static List<EnchantmentRecipeItem> GetAvailableEnchantmentRecipeItemsInInventory(Item item, CharacterInventory inventory)
		{
			List<EnchantmentRecipeItem> allItemsOfType = ItemsHelper.GetAllItemsOfType<EnchantmentRecipeItem>(ItemsHelper.GetUniqueItemsInInventory(inventory));
			List<EnchantmentRecipeItem> list = new List<EnchantmentRecipeItem>();
			foreach (EnchantmentRecipeItem item2 in allItemsOfType)
			{
				EnchantmentRecipe[] recipes = item2.Recipes;
				for (int i = 0; i < recipes.Length; i++)
				{
					if (recipes[i].GetHasMatchingEquipment(item))
					{
						list.Add(item2);
					}
				}
			}
			return list;
		}

		public static List<EnchantmentRecipe> GetAvailableEnchantmentRecipies(Item item)
		{
			List<EnchantmentRecipe> enchantmentRecipes = RecipeManager.Instance.GetEnchantmentRecipes();
			List<EnchantmentRecipe> list = new List<EnchantmentRecipe>();
			foreach (EnchantmentRecipe item2 in enchantmentRecipes)
			{
				if (item2.GetHasMatchingEquipment(item))
				{
					list.Add(item2);
				}
			}
			return list;
		}

		public static List<EnchantmentRecipe> GetMissingEnchantments(List<EnchantmentRecipe> availableEnchantments, List<EnchantmentRecipe> haveEnchantments)
		{
			List<EnchantmentRecipe> list = new List<EnchantmentRecipe>();
			bool flag = false;
			foreach (EnchantmentRecipe availableEnchantment in availableEnchantments)
			{
				foreach (EnchantmentRecipe haveEnchantment in haveEnchantments)
				{
					if (availableEnchantment.RecipeID == haveEnchantment.RecipeID)
					{
						flag = true;
					}
				}
				if (flag)
				{
					flag = false;
				}
				else
				{
					list.Add(availableEnchantment);
				}
			}
			return list;
		}

		public static bool IsEnchantmentInList(int enchantmentId, List<EnchantmentRecipeItem> enchantmentItems)
		{
			foreach (EnchantmentRecipeItem enchantmentItem in enchantmentItems)
			{
				EnchantmentRecipe[] recipes = enchantmentItem.Recipes;
				for (int i = 0; i < recipes.Length; i++)
				{
					if (recipes[i].RecipeID == enchantmentId)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static EnchantmentRecipeItem GetEnchantmentInTheList(int enchantmentId, List<EnchantmentRecipeItem> enchantmentItems)
		{
			foreach (EnchantmentRecipeItem enchantmentItem in enchantmentItems)
			{
				EnchantmentRecipe[] recipes = enchantmentItem.Recipes;
				for (int i = 0; i < recipes.Length; i++)
				{
					if (recipes[i].RecipeID == enchantmentId)
					{
						return enchantmentItem;
					}
				}
			}
			return null;
		}

		public static void FixFilterRecipe()
		{
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab("5800047");
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return;
			}
			EnchantmentRecipeItem val = (EnchantmentRecipeItem)(object)((itemPrefab is EnchantmentRecipeItem) ? itemPrefab : null);
			if (Object.op_Implicit((Object)(object)val) && val.Recipes.Count() != 3)
			{
				EnchantmentRecipe enchantmentRecipeForID = RecipeManager.Instance.GetEnchantmentRecipeForID(52);
				EnchantmentRecipe enchantmentRecipeForID2 = RecipeManager.Instance.GetEnchantmentRecipeForID(53);
				EnchantmentRecipe enchantmentRecipeForID3 = RecipeManager.Instance.GetEnchantmentRecipeForID(54);
				if (!((Object)(object)enchantmentRecipeForID == (Object)null) && !((Object)(object)enchantmentRecipeForID2 == (Object)null) && !((Object)(object)enchantmentRecipeForID3 == (Object)null))
				{
					EnchantmentRecipe[] recipes = (EnchantmentRecipe[])(object)new EnchantmentRecipe[3] { enchantmentRecipeForID, enchantmentRecipeForID2, enchantmentRecipeForID3 };
					val.Recipes = recipes;
				}
			}
		}
	}
	public class ItemsHelper
	{
		public static List<T> GetAllItemsOfType<T>(List<Item> items) where T : Item
		{
			List<T> list = new List<T>();
			foreach (Item item in items)
			{
				T val = (T)(object)((item is T) ? item : null);
				if (val != null)
				{
					list.Add(val);
				}
			}
			return list;
		}

		public static List<Item> GetUniqueItemsInInventory(CharacterInventory inventory)
		{
			ItemContainer pouch = inventory.Pouch;
			List<Item> first = ((pouch != null) ? pouch.GetContainedItems() : null);
			List<Item> second = new List<Item>();
			if (inventory.HasABag)
			{
				second = ((ItemContainer)inventory.EquippedBag.Container).GetContainedItems();
			}
			return first.Union(second).ToList();
		}
	}
}
namespace OutwardGameSettings.Utility.Helpers.Generic
{
	public static class LocationHelpers
	{
		public static Vector3 GetRandomPositionAround(Vector3 origin, float minRadius, float maxRadius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector2 normalized = ((Vector2)(ref insideUnitCircle)).normalized;
			float num = Random.Range(minRadius, maxRadius);
			Vector3 val = new Vector3(normalized.x, 0f, normalized.y) * num;
			return origin + val;
		}

		public static Vector3 GetGroundPosition(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(position + Vector3.up * 50f, Vector3.down, ref val, 100f, LayerMask.GetMask(new string[1] { "Default" })))
			{
				return ((RaycastHit)(ref val)).point;
			}
			return position;
		}

		public static Vector3 GetRandomReachablePosition(Vector3 playerPos, float minRadius, float maxRadius)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 20; i++)
			{
				Vector3 groundPosition = GetGroundPosition(GetRandomPositionAround(playerPos, minRadius, maxRadius));
				if (IsReachable(playerPos, groundPosition))
				{
					return groundPosition;
				}
			}
			return playerPos;
		}

		public static bool IsReachable(Vector3 from, Vector3 to)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			NavMeshPath val = new NavMeshPath();
			if (NavMesh.CalculatePath(from, to, -1, val))
			{
				return (int)val.status == 0;
			}
			return false;
		}

		public static bool IsReachableRaycast(Vector3 from, Vector3 to)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			return !Physics.Linecast(from + Vector3.up * 1f, to + Vector3.up * 1f);
		}

		public static Vector3 GetRandomNavMeshPosition(Vector3 origin, float minRadius, float maxRadius, int attempts = 30)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				NavMeshHit val = default(NavMeshHit);
				for (int i = 0; i < attempts; i++)
				{
					Vector2 insideUnitCircle = Random.insideUnitCircle;
					Vector2 normalized = ((Vector2)(ref insideUnitCircle)).normalized;
					float num = Random.Range(minRadius, maxRadius);
					if (NavMesh.SamplePosition(origin + new Vector3(normalized.x * num, 0f, normalized.y * num), ref val, 1.5f, -1))
					{
						float num2 = Vector3.Distance(origin, ((NavMeshHit)(ref val)).position);
						if (!(num2 < minRadius) && !(num2 > maxRadius) && IsReachable(origin, ((NavMeshHit)(ref val)).position) && IsWithinMapBounds(origin, ((NavMeshHit)(ref val)).position))
						{
							OutwardGameSettings.LogMessage($"[Spawn] Valid point at {((NavMeshHit)(ref val)).position}, distance {num2:0.0}");
							return ((NavMeshHit)(ref val)).position;
						}
					}
				}
				OutwardGameSettings.LogMessage("[Spawn] No valid NavMesh point found — returning origin.");
				return origin;
			}
			catch (Exception ex)
			{
				OutwardGameSettings.LogMessage("[Spawn] Error: " + ex.Message);
				return origin;
			}
		}

		public static bool HitIsMapBound(RaycastHit hit)
		{
			Transform val = ((Component)((RaycastHit)(ref hit)).collider).transform;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name.Equals("MapBounds", StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		public static bool IsWithinMapBounds(Vector3 origin, Vector3 target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0016: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = target - origin;
			float magnitude = ((Vector3)(ref val)).magnitude;
			RaycastHit hit = default(RaycastHit);
			if (Physics.Raycast(origin + Vector3.up, ((Vector3)(ref val)).normalized, ref hit, magnitude) && HitIsMapBound(hit))
			{
				OutwardGameSettings.LogMessage("[Spawn] Blocked by MapBounds: " + ((Object)((RaycastHit)(ref hit)).collider).name);
				return false;
			}
			return true;
		}
	}
}
namespace OutwardGameSettings.Utility.Enums
{
	public enum AIClassTypes
	{
		Warrior,
		Archer,
		Gunner,
		PassiveMage
	}
	public static class AIClassTypesHelper
	{
		public static readonly Dictionary<AIClassTypes, string> Data = new Dictionary<AIClassTypes, string>();
	}
	public enum CustomSeasons
	{
		Winter,
		FoggySpirits,
		GreatWar
	}
	public static class CustomSeasonsHelper
	{
		private static Dictionary<CustomSeasons, BasicSeason> _seasons;

		public static readonly Dictionary<CustomSeasons, string> SeasonsNames = new Dictionary<CustomSeasons, string>
		{
			{
				CustomSeasons.Winter,
				"GameSettings_Winter_Season"
			},
			{
				CustomSeasons.FoggySpirits,
				"GameSettings_Foggy_Spirits_Season"
			},
			{
				CustomSeasons.GreatWar,
				"GameSettings_Great_War_Season"
			}
		};

		public static Dictionary<CustomSeasons, BasicSeason> Seasons
		{
			get
			{
				if (_seasons == null || AreSeasonsInvalid())
				{
					RebuildSeasons();
				}
				return _seasons;
			}
		}

		private static void RebuildSeasons()
		{
			if (_seasons != null)
			{
				foreach (KeyValuePair<CustomSeasons, BasicSeason> season in _seasons)
				{
					if ((Object)(object)season.Value?.Season != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)season.Value.Season).gameObject);
					}
				}
			}
			_seasons = new Dictionary<CustomSeasons, BasicSeason>
			{
				{
					CustomSeasons.Winter,
					GetWinterSeason()
				},
				{
					CustomSeasons.FoggySpirits,
					GetFoggySpiritsSeason()
				},
				{
					CustomSeasons.GreatWar,
					GetGreatWarSeason()
				}
			};
		}

		public static Season GetSafeSeason(CustomSeasons season)
		{
			Season val = null;
			return MakeSeasonSafe((Season)(season switch
			{
				CustomSeasons.Winter => GetWinterSeason().Season, 
				CustomSeasons.GreatWar => GetGreatWarSeason().Season, 
				_ => GetFoggySpiritsSeason().Season, 
			}));
		}

		public static Season MakeSeasonSafe(Season originalSeason)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			originalSeason.MaxNightTemperature = (TemperatureSteps)4;
			originalSeason.MinNightTemperature = (TemperatureSteps)4;
			originalSeason.MaxDayTemperature = (TemperatureSteps)4;
			originalSeason.MinDayTemperature = (TemperatureSteps)4;
			return originalSeason;
		}

		public static BasicSeason GetWinterSeason()
		{
			//IL_0012: 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_0052: Expected O, but got Unknown
			//IL_0054: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (!SeasonsNames.TryGetValue(CustomSeasons.Winter, out var value))
			{
				return null;
			}
			Season obj = new GameObject(value).AddComponent<Season>();
			((Object)obj).name = value;
			obj.WinterLerp = MakeAnimationCurve();
			obj.AutumnLerp = MakeAnimationCurve();
			obj.SnowEnabled = true;
			obj.SnowingEnabled = true;
			obj.DayTemperatureTransition = new AnimationCurve();
			obj.MaxNightTemperature = (TemperatureSteps)0;
			obj.MinNightTemperature = (TemperatureSteps)0;
			obj.MaxDayTemperature = (TemperatureSteps)1;
			obj.MinDayTemperature = (TemperatureSteps)1;
			obj.WeatherProgressClamp = default(Vector2);
			obj.StartMonth = 1;
			obj.EndMonth = 3;
			obj.NextSeason = new Vector2(360f, 480f);
			obj.FogDensity = 0.02f;
			obj.EventThreshold = 1f;
			BasicSeason result = new BasicSeason(obj, CustomSeasons.Winter)
			{
				IsSafe = false
			};
			EnvironmentConditions.Instance.MinMaxSnowQuantity = new Vector2(2.5f, 5f);
			return result;
		}

		public static AnimationCurve MakeAnimationCurve()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			AnimationCurve val = new AnimationCurve();
			val.keys = (Keyframe[])(object)new Keyframe[2];
			for (int i = 0; i < val.keys.Length; i++)
			{
				((Keyframe)(ref val.keys[i])).inWeight = 0.3333f;
				((Keyframe)(ref val.keys[i])).outWeight = 0.3333f;
				((Keyframe)(ref val.keys[i])).value = 1f;
			}
			val.postWrapMode = (WrapMode)8;
			val.preWrapMode = (WrapMode)8;
			return val;
		}

		public static BasicSeason GetFoggySpiritsSeason()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (!SeasonsNames.TryGetValue(CustomSeasons.FoggySpirits, out var value))
			{
				return null;
			}
			GameObject val = new GameObject(value);
			Season foggySpirits = val.AddComponent<Season>();
			((Object)foggySpirits).name = value;
			foggySpirits.WinterLerp = MakeAnimationCurve();
			foggySpirits.AutumnLerp = MakeAnimationCurve();
			foggySpirits.SnowEnabled = true;
			foggySpirits.SnowingEnabled = true;
			foggySpirits.DayTemperatureTransition = new AnimationCurve();
			foggySpirits.MaxNightTemperature = (TemperatureSteps)1;
			foggySpirits.MinNightTemperature = (TemperatureSteps)2;
			foggySpirits.MaxDayTemperature = (TemperatureSteps)7;
			foggySpirits.MinDayTemperature = (TemperatureSteps)5;
			foggySpirits.WeatherProgressClamp = default(Vector2);
			foggySpirits.StartMonth = 1;
			foggySpirits.EndMonth = 3;
			foggySpirits.NextSeason = new Vector2(360f, 480f);
			foggySpirits.FogDensity = 0.1f;
			foggySpirits.EventThreshold = 0.5f;
			BasicSeason obj = new BasicSeason(foggySpirits, CustomSeasons.Winter)
			{
				IsSafe = false
			};
			obj.OnHour = (Action)Delegate.Combine(obj.OnHour, (Action)delegate
			{
				float num = Mathf.Clamp(foggySpirits.FogDensity - 0.05f, 0f, 0.2f);
				float num2 = Mathf.Clamp(foggySpirits.FogDensity + 0.05f, 0f, 0.2f);
				int num3 = Random.Range(0, 1);
				float num4 = 0f;
				float num5 = 0.015f;
				num4 = ((num3 != 1) ? Random.Range(num, foggySpirits.FogDensity + num5) : Random.Range(foggySpirits.FogDensity + num5, num2));
				OutwardGameSettings.LogMessage("Setting fog by Foggy Spirits season.");
				((MonoBehaviour)EnemyWaveManager.Instance).StartCoroutine(ShiftFogTo(num4));
			});
			return obj;
		}

		public static IEnumerator ShiftFogTo(float nextFogDensity, float stepSize = 0.002f)
		{
			if (EnvironmentConditions.Instance.CurrentSeason.FogDensity < nextFogDensity)
			{
				while (EnvironmentConditions.Instance.CurrentSeason.FogDensity < nextFogDensity)
				{
					Season currentSeason = EnvironmentConditions.Instance.CurrentSeason;
					currentSeason.FogDensity += stepSize;
					yield return (object)new WaitForSeconds(0.3f);
				}
			}
			else
			{
				while (EnvironmentConditions.Instance.CurrentSeason.FogDensity > nextFogDensity)
				{
					Season currentSeason2 = EnvironmentConditions.Instance.CurrentSeason;
					currentSeason2.FogDensity -= stepSize;
					yield return (object)new WaitForSeconds(0.3f);
				}
			}
		}

		public static BasicSeason GetGreatWarSeason()
		{
			//IL_0012: 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_0052: Expected O, but got Unknown
			//IL_0054: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (!SeasonsNames.TryGetValue(CustomSeasons.GreatWar, out var value))
			{
				return null;
			}
			Season obj = new GameObject(value).AddComponent<Season>();
			((Object)obj).name = value;
			obj.WinterLerp = MakeAnimationCurve();
			obj.AutumnLerp = MakeAnimationCurve();
			obj.SnowEnabled = true;
			obj.SnowingEnabled = true;
			obj.DayTemperatureTransition = new AnimationCurve();
			obj.MaxNightTemperature = (TemperatureSteps)2;
			obj.MinNightTemperature = (TemperatureSteps)4;
			obj.MaxDayTemperature = (TemperatureSteps)5;
			obj.MinDayTemperature = (TemperatureSteps)3;
			obj.WeatherProgressClamp = default(Vector2);
			obj.StartMonth = 1;
			obj.EndMonth = 3;
			obj.NextSeason = new Vector2(360f, 480f);
			obj.FogDensity = 0.008f;
			obj.EventThreshold = 1f;
			BasicSeason obj2 = new BasicSeason(obj, CustomSeasons.Winter)
			{
				IsSafe = false
			};
			obj2.OnHour = (Action)Delegate.Combine(obj2.OnHour, (Action)delegate
			{
				int num = Random.Range(0, 4);
				OutwardGameSettings.LogMessage("Setting enemies by Great War season.");
				switch (num)
				{
				case 0:
					EnemyWaveManager.Instance.StartWarOfRandomSize();
					break;
				case 1:
					EnemyWaveManager.Instance.SpawnRandomWave(notifyOnAmbush: false);
					break;
				case 2:
					EnemyWaveManager.Instance.SpawnRandomWanderer();
					break;
				case 3:
					break;
				}
			});
			return obj2;
		}

		public static void RemovePreviousSeasonEffects()
		{
			TOD_Time tODTime = TOD_Sky.Instance.TODTime;
			if ((Object)(object)tODTime == (Object)null)
			{
				OutwardGameSettings.LogMessage("Patch_EnvironmentConditions_StartSeasonTime@Prefix TODTime is missing! Cannot set season effects.");
				return;
			}
			foreach (KeyValuePair<CustomSeasons, BasicSeason> season in Seasons)
			{
				tODTime.OnHour -= season.Value.OnHour;
			}
		}

		public static bool AreSeasonsInvalid()
		{
			if (_seasons == null)
			{
				return true;
			}
			foreach (KeyValuePair<CustomSeasons, BasicSeason> season in _seasons)
			{
				if (season.Value == null)
				{
					return true;
				}
				if ((Object)(object)season.Value.Season == (Object)null)
				{
					return true;
				}
			}
			return false;
		}
	}
	public enum EnemiesWaveTypes
	{
		Bandits,
		Troglodytes,
		Skeletons,
		Ghosts
	}
	public static class EnemiesWaveTypesHelper
	{
		public static readonly Dictionary<EnemiesWaveTypes, EnemiesWave> EnemiesWaves = new Dictionary<EnemiesWaveTypes, EnemiesWave>
		{
			{
				EnemiesWaveTypes.Bandits,
				new BanditsWave()
			},
			{
				EnemiesWaveTypes.Troglodytes,
				new TroglodytesWave()
			},
			{
				EnemiesWaveTypes.Skeletons,
				new SkeletonsWave()
			},
			{
				EnemiesWaveTypes.Ghosts,
				new GhostsWave()
			}
		};

		public static EnemiesWave CreateSpecializedWave(EnemiesWaveTypes waveType, WeaponType weaponType)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			AnyWeaponWave anyWeaponWave = null;
			switch (waveType)
			{
			case EnemiesWaveTypes.Bandits:
				anyWeaponWave = new BanditsWave();
				break;
			case EnemiesWaveTypes.Skeletons:
				anyWeaponWave = new SkeletonsWave();
				break;
			default:
				return new DummiesWave();
			}
			anyWeaponWave.WeaponTypes.Add(weaponType);
			return anyWeaponWave;
		}
	}
	public enum EnemyHourlyEvents
	{
		War,
		Ambush,
		Wanderer
	}
	public static class EnemyHourlyEventsHelper
	{
		public static Dictionary<EnemyHourlyEvents, InGameEventController> Events = new Dictionary<EnemyHourlyEvents, InGameEventController>
		{
			{
				EnemyHourlyEvents.War,
				new InGameEventController(EnemyWarsConfigs.ChanceToGetIntoWarZone.Value, 168)
			},
			{
				EnemyHourlyEvents.Ambush,
				new InGameEventController(EnemyAmbushesConfigs.ChanceToGetAmbushed.Value)
			},
			{
				EnemyHourlyEvents.Wanderer,
				new InGameEventController(EnemySpawnsConfigs.ChanceToMeetWanderer.Value, 48)
			}
		};

		public static EventSaveData CreateCurrentCharacterSaveData()
		{
			return CreateSaveData(EnemyWaveManager.Instance.LastDay, EnemyWaveManager.Instance.LastHour, Events.Values.ToArray());
		}

		public static EventSaveData CreateSaveData(int lastDay, int lastHour, InGameEventController[] controllers)
		{
			EventSaveData eventSaveData = new EventSaveData
			{
				LastDay = lastDay,
				LastHour = lastHour
			};
			foreach (InGameEventController inGameEventController in controllers)
			{
				eventSaveData.Accumulators.Add(inGameEventController.Accumulator);
			}
			return eventSaveData;
		}

		public static void ApplySaveData(EventSaveData data)
		{
			if (data != null)
			{
				EnemyWaveManager.Instance.LastDay = data.LastDay;
				EnemyWaveManager.Instance.LastHour = data.LastHour;
				int length = Enum.GetValues(typeof(EnemyHourlyEvents)).Length;
				int num = ((data.Accumulators.Count > length) ? length : data.Accumulators.Count);
				for (int i = 0; i < num; i++)
				{
					Events[(EnemyHourlyEvents)i].Accumulator = data.Accumulators[i];
				}
			}
		}
	}
	public enum Races
	{
		Auraian,
		Tramon,
		Kazite
	}
	public static class RacesHelper
	{
		public static readonly Dictionary<Races, RaceData> races = new Dictionary<Races, RaceData>
		{
			{
				Races.Auraian,
				new RaceData(new GenderData(15, 11, 8), new GenderData(15, 11, 6))
			},
			{
				Races.Tramon,
				new RaceData(new GenderData(15, 11, 6), new GenderData(15, 11, 6))
			},
			{
				Races.Kazite,
				new RaceData(new GenderData(15, 11, 7), new GenderData(15, 11, 6))
			}
		};
	}
	public enum SkeletonTypes
	{
		Simple,
		AncientBlue
	}
	public static class SkeletonTypesHelper
	{
		public static readonly Dictionary<SkeletonTypes, SkeletonTypeData> types = new Dictionary<SkeletonTypes, SkeletonTypeData>
		{
			{
				SkeletonTypes.Simple,
				new SkeletonTypeData(175)
			},
			{
				SkeletonTypes.AncientBlue,
				new SkeletonTypeData(300, 3300301, 3300300, 3300302)
			}
		};
	}
	public enum TroglodyteTypes
	{
		Simple,
		Mana,
		Armored,
		Knight,
		Grenadier,
		Annoying,
		Archmage
	}
	public static class TroglodyteTypesHelper
	{
		public static readonly Dictionary<TroglodyteTypes, TroglodyteTypeData> types = new Dictionary<TroglodyteTypes, TroglodyteTypeData>
		{
			{
				TroglodyteTypes.Simple,
				new TroglodyteTypeData(90, 2130080)
			},
			{
				TroglodyteTypes.Mana,
				new TroglodyteTypeData(200, 2150040, 3900000)
			},
			{
				TroglodyteTypes.Armored,
				new TroglodyteTypeData(225, 2140050, 3900001)
			},
			{
				TroglodyteTypes.Knight,
				new TroglodyteTypeData(275, 2130081, 3900002)
			},
			{
				TroglodyteTypes.Grenadier,
				new TroglodyteTypeData(120, 2140050, 3900003)
			},
			{
				TroglodyteTypes.Annoying,
				new TroglodyteTypeData(125, 2140051, 3900004)
			},
			{
				TroglodyteTypes.Archmage,
				new TroglodyteTypeData(300, 2150041, 3900005)
			}
		};
	}
	public enum WeaponHoldingTypes
	{
		MainHanded,
		OffHanded,
		TwoHanded
	}
	public static class WeaponHoldingTypesHelpers
	{
		public static readonly HashSet<WeaponType> MainHanded = new HashSet<WeaponType>
		{
			(WeaponType)0,
			(WeaponType)1,
			(WeaponType)2
		};

		public static readonly HashSet<WeaponType> OffHanded = new HashSet<WeaponType>
		{
			(WeaponType)30,
			(WeaponType)40,
			(WeaponType)45,
			(WeaponType)100
		};

		public static readonly HashSet<WeaponType> TwoHanded = new HashSet<WeaponType>
		{
			(WeaponType)50,
			(WeaponType)51,
			(WeaponType)52,
			(WeaponType)53,
			(WeaponType)54,
			(WeaponType)55,
			(WeaponType)150,
			(WeaponType)200
		};

		public static readonly Dictionary<WeaponHoldingTypes, HashSet<WeaponType>> Types = new Dictionary<WeaponHoldingTypes, HashSet<WeaponType>>
		{
			{
				WeaponHoldingTypes.MainHanded,
				MainHanded
			},
			{
				WeaponHoldingTypes.OffHanded,
				OffHanded
			},
			{
				WeaponHoldingTypes.TwoHanded,
				TwoHanded
			}
		};

		public static WeaponHoldingTypes GetHoldingType(WeaponType type)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<WeaponHoldingTypes, HashSet<WeaponType>> type2 in Types)
			{
				if (type2.Value.Contains(type))
				{
					return type2.Key;
				}
			}
			return WeaponHoldingTypes.TwoHanded;
		}
	}
}
namespace OutwardGameSettings.Utility.Enemies
{
	public class AnyWeaponEnemyTemplate : EnemyTemplate
	{
		public List<WeaponType> weaponTypes = new List<WeaponType>();

		public bool TryToAssignWeaponTypesWithRandomWeapons(List<WeaponType> types, out int unusedMoney, int forPrice = 0)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			unusedMoney = 0;
			if (HasFoundWeaponsAndAssignedTypes())
			{
				OutwardGameSettings.LogMessage("AnyWeaponEnemyTemplate@TryToAssignWeaponTypesWithRandomWeapons using provided Weapon_ID/Shield_ID instead of Weapon.WeaponTypes");
				return false;
			}
			if (types == null || types.Count == 0 || types.Count > 2)
			{
				OutwardGameSettings.LogMessage("AnyWeaponEnemyTemplate@TryToAssignWeaponTypesWithRandomWeapons tried to insert incorrect number of Weapon.WeaponTypes");
				return false;
			}
			forPrice = EnemyEquipmentManager.Instance.SetWeaponOfTypeForPrice(this, types[0], forPrice);
			unusedMoney = forPrice;
			weaponTypes.Add(types[0]);
			if (types.Count > 1)
			{
				WeaponHoldingTypes holdingType = WeaponHoldingTypesHelpers.GetHoldingType(types[0]);
				WeaponHoldingTypes holdingType2 = WeaponHoldingTypesHelpers.GetHoldingType(types[1]);
				if (holdingType == WeaponHoldingTypes.TwoHanded || holdingType2 == WeaponHoldingTypes.TwoHanded || holdingType == holdingType2)
				{
					OutwardGameSettings.LogMessage($"AnyWeaponEnemyTemplate@TryToAssignWeaponTypesWithRandomWeapons assigned one hand: {types[0]} but other type didn't fit the requirements: {types[1]}");
					return false;
				}
				forPrice = EnemyEquipmentManager.Instance.SetWeaponOfTypeForPrice(this, types[1], forPrice);
				unusedMoney = forPrice;
				weaponTypes.Add(types[1]);
			}
			return true;
		}

		public bool TryToAssignWeaponTypesWithRandomWeapons(List<WeaponType> types)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (HasFoundWeaponsAndAssignedTypes())
			{
				OutwardGameSettings.LogMessage("AnyWeaponEnemyTemplate@TryToAssignWeaponTypesWithRandomWeapons using provided Weapon_ID/Shield_ID instead of Weapon.WeaponTypes");
				return false;
			}
			if (types == null || types.Count == 0 || types.Count > 2)
			{
				OutwardGameSettings.LogMessage("AnyWeaponEnemyTemplate@TryToAssignWeaponTypesWithRandomWeapons tried to insert incorrect number of Weapon.WeaponTypes");
				return false;
			}
			EnemyEquipmentManager.Instance.SetWeaponOfType(this, types[0]);
			weaponTypes.Add(types[0]);
			if (types.Count > 1)
			{
				WeaponHoldingTypes holdingType = WeaponHoldingTypesHelpers.GetHoldingType(types[0]);
				WeaponHoldingTypes holdingType2 = WeaponHoldingTypesHelpers.GetHoldingType(types[1]);
				if (holdingType == WeaponHoldingTypes.TwoHanded || holdingType2 == WeaponHoldingTypes.TwoHanded || holdingType == holdingType2)
				{
					OutwardGameSettings.LogMessage($"AnyWeaponEnemyTemplate@TryToAssignWeaponTypesWithRandomWeapons assigned one hand: {types[0]} but other type didn't fit the requirements: {types[1]}");
					return false;
				}
				EnemyEquipmentManager.Instance.SetWeaponOfType(this, types[1]);
				weaponTypes.Add(types[1]);
			}
			return true;
		}

		public bool HasFoundWeaponsAndAssignedTypes()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_0056: 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_0069: 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)
			if (base.Template == null)
			{
				OutwardGameSettings.LogMessage("AnyWeaponEnemyTemplate@HasFoundWeaponsAndAssignedTypes SL_Character Template is null!");
				return false;
			}
			if (base.Template.Weapon_ID.HasValue)
			{
				Weapon val = (Weapon)ResourcesPrefabManager.Instance.GetItemPrefab(base.Template.Weapon_ID.Value);
				if ((Object)(object)val != (Object)null && !weaponTypes.Contains(val.Type))
				{
					weaponTypes.Add(val.Type);
				}
			}
			if (base.Template.Shield_ID.HasValue)
			{
				Weapon val2 = (Weapon)ResourcesPrefabManager.Instance.GetItemPrefab(base.Template.Shield_ID.Value);
				if ((Object)(object)val2 != (Object)null && !weaponTypes.Contains(val2.Type))
				{
					weaponTypes.Add(val2.Type);
				}
			}
			if (weaponTypes.Count < 1)
			{
				return false;
			}
			return true;
		}

		public bool HasNotFoundWeaponsAndAssignedRandom()
		{
			return TryAssignRandomWeapons((AnyWeaponEnemyTemplate anyWeaponEnemyTemplate) => EnemyEquipmentManager.Instance.SetRandomWeapons(anyWeaponEnemyTemplate));
		}

		public bool HasNotFoundWeaponsAndAssignedRandomForPrice(out int unusedMoney, int forPrice = 0)
		{
			int moneyAmountLeft = 0;
			bool result = TryAssignRandomWeapons((AnyWeaponEnemyTemplate anyWeaponEnemyTemplate) => EnemyEquipmentManager.Instance.SetRandomWeaponsForPrice(anyWeaponEnemyTemplate, out moneyAmountLeft, forPrice));
			unusedMoney = moneyAmountLeft;
			return result;
		}

		private bool TryAssignRandomWeapons(Func<AnyWeaponEnemyTemplate, List<WeaponType>> assignWeaponsFunc)
		{
			if (!base.Template.Weapon_ID.HasValue && !base.Template.Shield_ID.HasValue)
			{
				weaponTypes = assignWeaponsFunc(this);
				return true;
			}
			if (!HasFoundWeaponsAndAssignedTypes())
			{
				weaponTypes = assignWeaponsFunc(this);
				return true;
			}
			return false;
		}
	}
	public class BanditTemplate : AnyWeaponEnemyTemplate
	{
		public int backPackChance = 20;

		public void SpawnBandit(List<WeaponType> types, bool hasSkills = true)
		{
			TryToAssignWeaponTypesWithRandomWeapons(types);
			SpawnWithRandomEquipmentAndSkills(hasSkills);
		}

		public int SpawnBandit(List<WeaponType> types, bool hasSkills = true, int forPrice = 0)
		{
			TryToAssignWeaponTypesWithRandomWeapons(types, out var unusedMoney, forPrice);
			return SpawnWithRandomEquipmentAndSkillsForPrice(hasSkills, unusedMoney);
		}

		public void SpawnBandit(bool hasSkills = true)
		{
			HasNotFoundWeaponsAndAssignedRandom();
			SpawnWithRandomEquipmentAndSkills(hasSkills);
		}

		public int SpawnBandit(bool hasSkills = true, int forPrice = 0)
		{
			HasNotFoundWeaponsAndAssignedRandomForPrice(out var unusedMoney, forPrice);
			return SpawnWithRandomEquipmentAndSkillsForPrice(hasSkills, unusedMoney);
		}

		public int SpawnWithRandomEquipmentAndSkillsForPrice(bool hasSkills = true, int forPrice = 0)
		{
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				int result = EnemyEquipmentManager.Instance.SetRandomEquipmentForPrice(this, forPrice);
				if (hasSkills)
				{
					foreach (WeaponType weaponType in weaponTypes)
					{
						if (EnemySkillsManager.Instance.GetRandomSkills(weaponType, out var addSkillsIds))
						{
							base.SkillsIds.UnionWith(addSkillsIds);
						}
					}
				}
				SpawnOrReset();
				return result;
			}
			catch (Exception ex)
			{
				OutwardGameSettings.LogMessage("BanditTemplate@SpawnBandit: " + ex.Message);
				return forPrice;
			}
		}

		public void SpawnWithRandomEquipmentAndSkills(bool hasSkills = true)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				EnemyEquipmentManager.Instance.SetRandomEquipment(this);
				if (hasSkills)
				{
					foreach (WeaponType weaponType in weaponTypes)
					{
						if (EnemySkillsManager.Instance.GetRandomSkills(weaponType, out var addSkillsIds))
						{
							base.SkillsIds.UnionWith(addSkillsIds);
						}
					}
				}
				SpawnOrReset();
			}
			catch (Exception ex)
			{
				OutwardGameSettings.LogMessage("BanditTemplate@SpawnBandit: " + ex.Message);
			}
		}

		public override void ApplyStats()
		{
			if (!Health.HasValue)
			{
				int num = Random.Range(100, 600);
				base.Template.Health = num;
				Health = num;
			}
			base.ApplyStats();
		}

		public override void ApplyCharacterVisuals()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (VisualData != null)
			{
				base.Template.CharacterVisualsData = VisualData;
				return;
			}
			VisualData = new VisualData();
			int num = Random.Range(0, RacesHelper.races.Count);
			VisualData.SkinIndex = num;
			int num2 = Random.Range(0, 2);
			RacesHelper.races.TryGetValue((Races)num, out var value);
			VisualData.Gender = (Gender)num2;
			GenderData gender = value.GetGender((Gender)num2);
			int hairStyleIndex = Random.Range(0, gender.TotalHairStyles);
			VisualData.HairStyleIndex = hairStyleIndex;
			int hairColorIndex = Random.Range(0, gender.TotalHairColors);
			VisualData.HairColorIndex = hairColorIndex;
			int headVariationIndex = Random.Range(0, gender.TotalHeadVariations);
			VisualData.HeadVariationIndex = headVariationIndex;
			base.Template.CharacterVisualsData = VisualData;
		}

		public override void ApplyEquipment(int forPriceAmount = 0)
		{
			if (!base.Template.Helmet_ID.HasValue && !base.Template.Chest_ID.HasValue && !base.Template.Boots_ID.HasValue)
			{
				EnemyEquipmentManager.Instance.SetRandomEquipmentForPrice(this, forPriceAmount);
			}
			if (!base.Template.Backpack_ID.HasValue && Random.Range(0, 101) < backPackChance)
			{
				EnemyEquipmentManager.Instance.SetRandomBag(this);
			}
		}
	}
	public class EnemyTemplate
	{
		public Character Character;

		public VisualData VisualData;

		public SL_CharacterAI AI;

		public bool AddCombatAI;

		public bool CanDodge;

		public bool CanBlock;

		public int? Health;

		public Vector3 SpawnPosition;

		public AIClassTypes AIType;

		public string Name { get; set; }

		public SL_Character Template { get; set; }

		public bool CharacterExists => (Object)(object)Character != (Object)null;

		public HashSet<int> SkillsIds { get; set; } = new HashSet<int>();


		public void DestroyCharacter()
		{
			CustomCharacters.DestroyCharacterRPC(Character);
		}

		public void SpawnOrReset()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			if (Template == null)
			{
				OutwardGameSettings.LogMessage("EnemyTemplate@SpawnOrReset null template!");
				return;
			}
			Template.Unregister();
			Template.SaveType = (CharSaveType)1;
			if (AddCombatAI)
			{
				switch (AIType)
				{
				case AIClassTypes.Gunner:
					Template.AI = (SL_CharacterAI)(object)new SL_CharacterAIGunnerRanged();
					break;
				case AIClassTypes.Archer:
					Template.AI = (SL_CharacterAI)(object)new SL_CharacterAIBowRanged();
					break;
				default:
					Template.AI = (SL_CharacterAI)(object)new SL_CharacterAIMeleeFixed();
					break;
				}
				Template.AI.CanBlock = CanBlock;
				Template.AI.CanDodge = CanDodge;
			}
			ApplyCharacterVisuals();
			ApplyRandomCharacterScale();
			ApplyEquipment();
			ApplyStats();
			Template.LootableOnDeath = true;
			Template.DropPouchContents = true;
			Template.OnSpawn += delegate
			{
				AddTypeNeeds();
				((MonoBehaviour)EnemyWaveManager.Instance).StartCoroutine(AddSkills());
			};
			if (CharacterExists)
			{
				CustomCharacters.DestroyCharacterRPC(Character);
				Template.Unregister();
			}
			SL.Log("EnemyTamplate@SpawnOrReset Spawning clone, AI: " + (((object)Template.AI)?.ToString() ?? "null"));
			try
			{
				((ContentTemplate)Template).ApplyTemplate();
				Character = Template.Spawn(SpawnPosition, UID.op_Implicit(UID.Generate()), (string)null);
			}
			catch (Exception ex)
			{
				SL.Log("EnemyTamplate@SpawnOrReset encountered an error: \"" + ex.Message + "\"");
			}
		}

		public virtual IEnumerator AddSkills()
		{
			foreach (int skillsId in SkillsIds)
			{
				EnemySkillsManager.Instance.SetSkill(this, skillsId);
				yield return (object)new WaitForSeconds(0.1f);
			}
		}

		public virtual void AddTypeNeeds()
		{
			switch (AIType)
			{
			case AIClassTypes.Archer:
			{
				if (!EnemyEquipmentManager.Instance.GetRandomWeaponOfType((WeaponType)150, out var weapon))
				{
					OutwardGameSettings.LogMessage("EnemyTemplate@AddTypeNeeds failed to retrieve Arrow!");
					break;
				}
				Item val2 = ResourcesPrefabManager.Instance.GenerateItem(weapon.ItemId.ToString());
				if (!((Object)(object)val2 == (Object)null))
				{
					Character.Inventory.GenerateItem(val2, 5, true);
				}
				break;
			}
			case AIClassTypes.Gunner:
			{
				Item val = ResourcesPrefabManager.Instance.GenerateItem(4400080.ToString());
				if (!((Object)(object)val == (Object)null))
				{
					Character.Inventory.GenerateItem(val, 5, true);
					int item = 8200600;
					SkillsIds.Add(item);
				}
				break;
			}
			}
		}

		public virtual void ApplyStats()
		{
			if (Health.HasValue)
			{
				Template.Health = Health;
			}
			else
			{
				Template.Health = 100f;
			}
			Template.HealthRegen = 5f;
		}

		public virtual void ApplyCharacterVisuals()
		{
			if (VisualData != null)
			{
				Template.CharacterVisualsData = VisualData;
			}
		}

		public virtual void ApplyRandomCharacterScale()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.Range(0.6f, 1.4f);
			Template.Scale = new Vector3(num, num, num);
		}

		public virtual void ApplyEquipment(int forPriceAmount = 0)
		{
		}

		[Obsolete]
		public void Reset(Vector3 pos, bool newspawn)
		{
			SpawnOrReset();
		}
	}
	public class GhostTemplate : EnemyTemplate
	{
		public void SpawGhost()
		{
			int item = 8200702;
			base.SkillsIds.Add(item);
			SpawnOrReset();
		}

		public override void ApplyStats()
		{
			base.Template.Health = 175f;
			base.Template.HealthRegen = 5f;
		}

		public override void ApplyEquipment(int forPriceAmount = 0)
		{
			if (!base.Template.Weapon_ID.HasValue)
			{
				if (Random.Range(0, 2) == 0)
				{
					base.Template.Weapon_ID = 2000042;
				}
				else
				{
					base.Template.Weapon_ID = 2010002;
				}
			}
			if (!base.Template.Helmet_ID.HasValue)
			{
				base.Template.Helmet_ID = 3200041;
			}
			if (!base.Template.Chest_ID.HasValue)
			{
				base.Template.Chest_ID = 3200040;
			}
			if (!base.Template.Boots_ID.HasValue)
			{
				base.Template.Boots_ID = 3200042;
			}
		}
	}
	public class SkeletonTemplate : AnyWeaponEnemyTemplate
	{
		public int backPackChance = 20;

		public void SpawnRandomSkeleton()
		{
			int type = Random.Range(0, Enum.GetValues(typeof(SkeletonTypes)).Length);
			SpawnSkeletonOfType((SkeletonTypes)type);
		}

		public int SpawnRandomSkeletonForPrice(int equipmentPrice = 0)
		{
			int type = Random.Range(0, Enum.GetValues(typeof(SkeletonTypes)).Length);
			return SpawnSkeletonOfType((SkeletonTypes)type, equipmentPrice);
		}

		public void SpawnRandomSkeleton(List<WeaponType> types)
		{
			int type = Random.Range(0, Enum.GetValues(typeof(SkeletonTypes)).Length);
			SpawnSkeletonOfTypeWithWeaponTypes((SkeletonTypes)type, types);
		}

		public int SpawnRandomSkeletonForPrice(List<WeaponType> types, int equipmentPrice = 0)
		{
			int type = Random.Range(0, Enum.GetValues(typeof(SkeletonTypes)).Length);
			return SpawnSkeletonOfTypeWithWeaponTypesForPrice((SkeletonTypes)type, types, equipmentPrice);
		}

		public void SpawnSkeletonOfTypeWithWeaponTypes(SkeletonTypes type, List<WeaponType> types)
		{
			TryToAssignWeaponTypesWithRandomWeapons(types);
			SpawnSkeletonOfTypeWeaponless(type);
		}

		public int SpawnSkeletonOfTypeWithWeaponTypesForPrice(SkeletonTypes type, List<WeaponType> types, int withMoney = 0)
		{
			TryToAssignWeaponTypesWithRandomWeapons(types, out var unusedMoney, withMoney);
			SpawnSkeletonOfTypeWeaponless(type);
			return unusedMoney;
		}

		public void SpawnSkeletonOfTypeWeaponless(SkeletonTypes type, bool hasSkills = true)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SkeletonTypesHelper.types.TryGetValue(type, out var value);
				base.Template.Health = value.Health;
				base.Template.Helmet_ID = value.HelmetId;
				base.Template.Chest_ID = value.ChestId;
				base.Template.Boots_ID = value.BootsId;
				if (hasSkills)
				{
					foreach (WeaponType weaponType in weaponTypes)
					{
						int randomSkillLearnCount = Random.Range(1, 3);
						if (EnemySkillsManager.Instance.GetRandomSkillsOfWeaponType(weaponType, out var addSkillsIds, randomSkillLearnCount))
						{
							base.SkillsIds.UnionWith(addSkillsIds);
						}
					}
				}
				SpawnOrReset();
			}
			catch (Exception ex)
			{
				OutwardGameSettings.LogMessage("SkeletonTemplate@SpawnSkeletonOfType: " + ex.Message);
			}
		}

		public int SpawnSkeletonOfType(SkeletonTypes type, int equipmentPrice = 0)
		{
			HasNotFoundWeaponsAndAssignedRandomForPrice(out var unusedMoney, equipmentPrice);
			SpawnSkeletonOfTypeWeaponless(type);
			return unusedMoney;
		}

		public void SpawnSkeletonOfType(SkeletonTypes type)
		{
			HasNotFoundWeaponsAndAssignedRandom();
			SpawnSkeletonOfTypeWeaponless(type);
		}

		public override void ApplyStats()
		{
			base.Template.HealthRegen = 5f;
		}

		public override void ApplyEquipment(int forPriceAmount = 0)
		{
			if (!base.Template.Helmet_ID.HasValue)
			{
				base.Template.Helmet_ID = 3200031;
			}
			if (!base.Template.Chest_ID.HasValue)
			{
				base.Template.Chest_ID = 3200030;
			}
			if (!base.Template.Boots_ID.HasValue)
			{
				base.Template.Boots_ID = 3200032;
			}
			if (!base.Template.Backpack_ID.HasValue && Random.Range(0, 101) < backPackChance)
			{
				EnemyEquipmentManager.Instance.SetRandomBagForPrice(this, forPriceAmount);
			}
		}
	}
	public class TroglodyteTemplate : EnemyTemplate
	{
		public int chanceForRandomWeapon = 20;

		public void SpawnRandomTrog()
		{
			int type = Random.Range(0, Enum.GetValues(typeof(TroglodyteTypes)).Length);
			SpawnTrogOfType((TroglodyteTypes)type);
		}

		public int SpawnRandomTrogForPrice(int forPrice = 0)
		{
			int type = Random.Range(0, Enum.GetValues(typeof(TroglodyteTypes)).Length);
			return SpawnTrogOfType((TroglodyteTypes)type, forPrice);
		}

		public void GiveTrogRandomWeapon(TroglodyteTypeData typeData)
		{
			if (Random.Range(0, 100) < 100 - chanceForRandomWeapon)
			{
				base.Template.Weapon_ID = typeData.WeaponId;
			}
			else if (Random.Range(0, 2) == 0)
			{
				EnemyEquipmentManager.Instance.GetRandomWeaponOfType((WeaponType)50, out var weapon);
				base.Template.Weapon_ID = weapon.ItemId;
			}
			else
			{
				EnemyEquipmentManager.Instance.GetRandomWeaponOfType((WeaponType)54, out var weapon2);
				base.Template.Weapon_ID = weapon2.ItemId;
			}
		}

		public int GiveTrogRandomWeaponForPrice(TroglodyteTypeData typeData, int forPrice = 0)
		{
			try
			{
				int num = Random.Range(0, 100);
				if (typeData.WeaponId.HasValue && num < 100 - chanceForRandomWeapon)
				{
					base.Template.Weapon_ID = typeData.WeaponId;
					Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(typeData.WeaponId.Value);
					if ((Object)(object)itemPrefab == (Object)null)
					{
						return forPrice;
					}
					return itemPrefab.RawCurrentValue;
				}
				WeaponData weapon3;
				if (Random.Range(0, 2) == 0)
				{
					if (!EnemyEquipmentManager.Instance.GetRandomWeaponOfTypeForPrice((WeaponType)50, out var weapon, forPrice))
					{
						EnemyEquipmentManager.Instance.GetCheapestRandomWeaponOfType((WeaponType)50, out var weapon2);
						base.Template.Weapon_ID = weapon2.ItemId;
					}
					else
					{
						base.Template.Weapon_ID = weapon.ItemId;
					}
				}
				else if (!EnemyEquipmentManager.Instance.GetRandomWeaponOfTypeForPrice((WeaponType)54, out weapon3, forPrice))
				{
					EnemyEquipmentManager.Instance.GetCheapestRandomWeaponOfType((WeaponType)54, out var weapon4);
					base.Template.Weapon_ID = weapon4.ItemId;
				}
				else
				{
					base.Template.Weapon_ID = weapon3.ItemId;
				}
				if (!base.Template.Weapon_ID.HasValue)
				{
					return forPrice;
				}
				return ResourcesPrefabManager.Instance.GetItemPrefab(base.Template.Weapon_ID.Value).RawCurrentValue;
			}
			catch (Exception ex)
			{
				OutwardGameSettings.LogMessage("TroglodyteTemplate@GiveTrogRandomWeaponForPrice: " + ex.Message);
				return forPrice;
			}
		}

		public int SpawnTrogOfType(TroglodyteTypes type, int forPrice = 0)
		{
			int result = forPrice;
			try
			{
				if (!TroglodyteTypesHelper.types.TryGetValue(type, out var value))
				{
					OutwardGameSettings.LogMessage("TroglodyteTemplate@SpawnTrogOfType [price] provided incorrect trog type.");
				}
				base.Template.Health = value.Health;
				base.Template.Chest_ID = value.ArmorId;
				if (!base.Template.Weapon_ID.HasValue)
				{
					result = GiveTrogRandomWeaponForPrice(value, forPrice);
				}
				if (type == TroglodyteTypes.Grenadier)
				{
					AddGrenadierAI();
				}
				AssignSkills(type);
				SpawnOrReset();
			}
			catch (Exception ex)
			{
				OutwardGameSettings.LogMessage("TroglodyteTemplate@SpawnTrogOfType: " + ex.Message + " \n" + ex.StackTrace);
			}
			return result;
		}

		public void SpawnTrogOfType(TroglodyteTypes type)
		{
			try
			{
				if (!TroglodyteTypesHelper.types.TryGetValue(type, out var value))
				{
					OutwardGameSettings.LogMessage("TroglodyteTemplate@SpawnTrogOfType provided incorrect trog type.");
				}
				base.Template.Health = value.Health;
				base.Template.Chest_ID = value.ArmorId;
				if (!base.Template.Weapon_ID.HasValue)
				{
					GiveTrogRandomWeapon(value);
				}
				if (type == TroglodyteTypes.Grenadier)
				{
					AddGrenadierAI();
				}
				AssignSkills(type);
				SpawnOrReset();
			}
			catch (Exception ex)
			{
				OutwardGameSettings.LogMessage("TroglodyteTemplate@SpawnTrogOfType: " + ex.Message);
			}
		}

		public void AddGrenadierAI()
		{
			if (AddCombatAI)
			{
				SL_CharacterAIMelee_RegenaratingInventoryItems sL_CharacterAIMelee_RegenaratingInventoryItems = new SL_CharacterAIMelee_RegenaratingInventoryItems();
				sL_CharacterAIMelee_RegenaratingInventoryItems.RegenerationQuantity = 2;
				sL_CharacterAIMelee_RegenaratingInventoryItems.ItemIdToRegenerate = 6600070;
				base.Template.AI = (SL_CharacterAI)(object)sL_CharacterAIMelee_RegenaratingInventoryItems;
				base.Template.AI.CanBlock = CanBlock;
				base.Template.AI.CanDodge = CanDodge;
			}
			AddCombatAI = false;
		}

		public void AssignSkills(TroglodyteTypes type)
		{
			switch (type)
			{
			case TroglodyteTypes.Mana:
			case TroglodyteTypes.Archmage:
			{
				int item2 = 8200702;
				int item3 = 8200701;
				base.SkillsIds.Add(item2);
				base.SkillsIds.Add(item3);
				base.SkillsIds.Add(8300064);
				base.SkillsIds.Add(8300063);
				base.SkillsIds.Add(8300062);
				base.SkillsIds.Add(8300061);
				break;
			}
			case TroglodyteTypes.Grenadier:
			{
				int item = 8200700;
				base.SkillsIds.Add(item);
				base.SkillsIds.Add(8300068);
				base.SkillsIds.Add(8300060);
				break;
			}
			}
		}

		public override void ApplyStats()
		{
			base.Template.HealthRegen = 5f;
		}

		public override void ApplyCharacterVisuals()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if (VisualData != null)
			{
				base.Template.CharacterVisualsData = VisualData;
				return;
			}
			VisualData = new VisualData();
			VisualData.SkinIndex = -999;
			base.Template.CharacterVisualsData = VisualData;
		}
	}
}
namespace OutwardGameSettings.Utility.Enemies.Waves
{
	public class AnyWeaponWave : EnemiesWave
	{
		public List<WeaponType> WeaponTypes = new List<WeaponType>();
	}
	public class BanditsWave : AnyWeaponWave
	{
		public BanditsWave()
		{
			base.AmbushSounds = GetAmbushSoundsList();
			base.NotificationMessage = "Bandits are ambushing!";
			base.EnemyNamePrefix = "Ambush Bandit";
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (WeaponTypes != null && WeaponTypes.Count > 0)
			{
				return AddEnemy(name, location, WeaponTypes);
			}
			BanditTemplate banditTemplate = GetBanditTemplate(name, location);
			banditTemplate.SpawnBandit(hasSkills: true);
			return banditTemplate;
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 position, out int unusedMoney, int equipmentPrice = 0)
		{
			//IL_002e: 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)
			unusedMoney = equipmentPrice;
			if (WeaponTypes != null && WeaponTypes.Count > 0)
			{
				return AddEnemy(name, position, WeaponTypes, out unusedMoney, equipmentPrice);
			}
			BanditTemplate banditTemplate = GetBanditTemplate(name, position);
			unusedMoney = banditTemplate.SpawnBandit(hasSkills: true, equipmentPrice);
			return banditTemplate;
		}

		public BanditTemplate AddEnemy(string name, Vector3 location, List<WeaponType> weaponTypes, out int unusedMoney, int equipmentPrice = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			BanditTemplate banditTemplate = GetBanditTemplate(name, location);
			unusedMoney = banditTemplate.SpawnBandit(weaponTypes, hasSkills: true, equipmentPrice);
			return banditTemplate;
		}

		public BanditTemplate AddEnemy(string name, Vector3 location, List<WeaponType> weaponTypes)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			BanditTemplate banditTemplate = GetBanditTemplate(name, location);
			banditTemplate.SpawnBandit(weaponTypes, hasSkills: true);
			return banditTemplate;
		}

		public BanditTemplate GetBanditTemplate(string name, Vector3 location)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			BanditTemplate obj = new BanditTemplate
			{
				Name = name,
				AddCombatAI = true,
				CanDodge = true,
				CanBlock = true,
				SpawnPosition = location
			};
			SL_Character val = new SL_Character
			{
				Name = name
			};
			UID val2 = UID.Generate();
			val.UID = ((UID)(ref val2)).Value;
			val.Faction = (Factions)2;
			obj.Template = val;
			return obj;
		}

		public List<Sounds> GetAmbushSoundsList()
		{
			return new List<Sounds>
			{
				(Sounds)50428,
				(Sounds)50429,
				(Sounds)50430,
				(Sounds)50431,
				(Sounds)50432,
				(Sounds)50433,
				(Sounds)50434
			};
		}
	}
	internal class DummiesWave : EnemiesWave
	{
		public DummiesWave()
		{
			base.AmbushSounds = GetAmbushSoundsList();
			base.NotificationMessage = "Dummies are ambushing!";
			base.EnemyNamePrefix = "Ambush Dummy";
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location, out int unusedMoney, int equipmentPrice = 0)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			unusedMoney = equipmentPrice;
			return AddEnemy(name, location);
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			EnemyTemplate dummyTemplate = GetDummyTemplate(name, location);
			dummyTemplate.SpawnOrReset();
			return dummyTemplate;
		}

		public EnemyTemplate GetDummyTemplate(string name, Vector3 location)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			EnemyTemplate obj = new EnemyTemplate
			{
				Name = name,
				AddCombatAI = true,
				SpawnPosition = location
			};
			SL_Character val = new SL_Character
			{
				Name = name
			};
			UID val2 = UID.Generate();
			val.UID = ((UID)(ref val2)).Value;
			val.Faction = (Factions)2;
			val.Weapon_ID = 2000010;
			obj.Template = val;
			return obj;
		}

		public List<Sounds> GetAmbushSoundsList()
		{
			return new List<Sounds>
			{
				(Sounds)50428,
				(Sounds)50429,
				(Sounds)50430,
				(Sounds)50431,
				(Sounds)50432,
				(Sounds)50433,
				(Sounds)50434
			};
		}
	}
	public class EnemiesWave
	{
		private List<EnemyTemplate> enemies = new List<EnemyTemplate>();

		private int minEnemies = 1;

		private int maxEnemies = 5;

		private int minRadiusSpawn = 20;

		private int maxRadiusSpawn = 40;

		private string notificationMessage = "Enemies are ambushing!";

		private string enemyNamePrefix = "Ambush Enemy";

		private List<Sounds> ambushSounds = new List<Sounds>();

		private List<Vector3> cachedPositions = new List<Vector3>();

		public int MinEnemies
		{
			get
			{
				return minEnemies;
			}
			set
			{
				minEnemies = value;
			}
		}

		public int MaxEnemies
		{
			get
			{
				return maxEnemies;
			}
			set
			{
				maxEnemies = value;
			}
		}

		public int MinRadiusSpawn
		{
			get
			{
				return minRadiusSpawn;
			}
			set
			{
				minRadiusSpawn = value;
			}
		}

		public int MaxRadiusSpawn
		{
			get
			{
				return maxRadiusSpawn;
			}
			set
			{
				maxRadiusSpawn = value;
			}
		}

		public string NotificationMessage
		{
			get
			{
				return notificationMessage;
			}
			set
			{
				notificationMessage = value;
			}
		}

		public string EnemyNamePrefix
		{
			get
			{
				return enemyNamePrefix;
			}
			set
			{
				enemyNamePrefix = value;
			}
		}

		public List<EnemyTemplate> Enemies
		{
			get
			{
				return enemies;
			}
			set
			{
				enemies = value;
			}
		}

		public List<Sounds> AmbushSounds
		{
			get
			{
				return ambushSounds;
			}
			set
			{
				ambushSounds = value;
			}
		}

		public EnemiesWave()
		{
		}

		public EnemiesWave(List<Sounds> ambushPossibleSounds, string notificationMessage = "Enemies are ambushing!", string enemyNamePrefix = "Ambush Enemy", int minEnemies = 1, int maxEnemies = 5, int minRadius = 20, int maxRadius = 40)
		{
			AmbushSounds = ambushPossibleSounds;
			EnemyNamePrefix = enemyNamePrefix;
			NotificationMessage = notificationMessage;
			MinEnemies = minEnemies;
			MaxEnemies = maxEnemies;
			MinRadiusSpawn = minRadius;
			MaxRadiusSpawn = maxRadius;
		}

		public virtual IEnumerator StartWave(bool shouldNotify = true, bool isWar = false)
		{
			Character masterCharacter = CharacterManager.Instance.GetFirstLocalCharacter();
			if (!((Object)(object)masterCharacter == (Object)null))
			{
				int totalPositions = Random.Range(MinEnemies, MaxEnemies);
				yield return ((MonoBehaviour)EnemyWaveManager.Instance).StartCoroutine(PrepareSpawnPositions(totalPositions));
				if (EnemiesConfigs.ScaleScenarioEnemiesPower.Value)
				{
					yield return ((MonoBehaviour)EnemyWaveManager.Instance).StartCoroutine(SpawnEnemies(EnemyNamePrefix, CharacterHelpers.GetLobbiesSilverWorth()));
				}
				else
				{
					yield return ((MonoBehaviour)EnemyWaveManager.Instance).StartCoroutine(SpawnEnemies(EnemyNamePrefix));
				}
				if (shouldNotify)
				{
					NotificationsManager.Instance.BroadcastGlobalTopNotification(NotificationMessage);
				}
				int index = Random.Range(0, AmbushSounds.Count);
				Global.AudioManager.PlaySoundAtPosition(AmbushSounds[index], ((Component)masterCharacter).transform.position, 0f, 1f, 1f, 1f, 1f);
				if (!isWar)
				{
					EventBusPublisher.SendEnemyWaveStarted();
				}
			}
		}

		private IEnumerator PrepareSpawnPositions(int totalPositions)
		{
			cachedPositions.Clear();
			Character masterCharacter = CharacterManager.Instance.GetFirstLocalCharacter();
			if ((Object)(object)masterCharacter == (Object)null)
			{
				yield break;
			}
			for (int i = 0; i < totalPositions; i++)
			{
				Vector3 randomNavMeshPosition = LocationHelpers.GetRandomNavMeshPosition(((Component)masterCharacter).transform.position, MinRadiusSpawn, MaxRadiusSpawn, 60);
				if (randomNavMeshPosition != Vector3.zero)
				{
					cachedPositions.Add(randomNavMeshPosition);
				}
				if (i % 3 == 0)
				{
					yield return null;
				}
			}
		}

		private IEnumerator SpawnEnemies(string enemyName)
		{
			foreach (Vector3 cachedPosition in cachedPositions)
			{
				AddEnemy(enemyName, cachedPosition);
				yield return (object)new WaitForSeconds(0.1f);
			}
		}

		private IEnumerator SpawnEnemies(string enemyName, int equipmentPrice = 0)
		{
			int totalMoney = equipmentPrice;
			foreach (Vector3 item in cachedPositions.ToList())
			{
				AddEnemy(enemyName, item, out var unusedMoney, totalMoney);
				totalMoney -= Mathf.Clamp(unusedMoney, 0, totalMoney);
				yield return (object)new WaitForSeconds(0.1f);
			}
		}

		public EnemyTemplate AddEnemyAroundMaster(string name)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Character firstLocalCharacter = CharacterManager.Instance.GetFirstLocalCharacter();
			if ((Object)(object)firstLocalCharacter == (Object)null)
			{
				return new EnemyTemplate();
			}
			Vector3 val = LocationHelpers.GetRandomNavMeshPosition(((Component)firstLocalCharacter).transform.position, MinRadiusSpawn, MaxRadiusSpawn);
			if (val == Vector3.zero)
			{
				val = ((Component)firstLocalCharacter).transform.position;
			}
			return AddEnemy(name, val);
		}

		public virtual EnemyTemplate AddEnemy(string name, Vector3 position, out int unusedMoney, int equipmentPrice = 0)
		{
			unusedMoney = 0;
			return new EnemyTemplate();
		}

		public virtual EnemyTemplate AddEnemy(string name, Vector3 position)
		{
			return new EnemyTemplate();
		}

		public void CleanDeadBodies()
		{
			int num = 0;
			int num2 = 0;
			foreach (EnemyTemplate enemy in enemies)
			{
				if (enemy.Character.Alive)
				{
					num++;
					continue;
				}
				DestroyEnemy(enemy);
				num2++;
			}
			OutwardGameSettings.LogMessage($"EnemiesWave@CleanDeadBodies Total Alive Enemies: {num} Total Dead Enemies: {num2}");
		}

		public void DestroyEnemy(EnemyTemplate dummy)
		{
			if (Enemies.Contains(dummy))
			{
				Enemies.Remove(dummy);
			}
			if (dummy.CharacterExists)
			{
				dummy.DestroyCharacter();
			}
		}
	}
	public class GhostsWave : EnemiesWave
	{
		public GhostsWave()
		{
			base.AmbushSounds = GetAmbushSoundsList();
			base.NotificationMessage = "Ghosts are ambushing!";
			base.EnemyNamePrefix = "Ambush Ghost";
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location, out int unusedMoney, int equipmentPrice = 0)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			unusedMoney = equipmentPrice;
			return AddEnemy(name, location);
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			GhostTemplate ghostTemplate = GetGhostTemplate(name, location);
			ghostTemplate.SpawGhost();
			return ghostTemplate;
		}

		public GhostTemplate GetGhostTemplate(string name, Vector3 location)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			GhostTemplate obj = new GhostTemplate
			{
				Name = name,
				AddCombatAI = true,
				CanDodge = true,
				CanBlock = true,
				SpawnPosition = location
			};
			SL_Character val = new SL_Character
			{
				Name = name
			};
			UID val2 = UID.Generate();
			val.UID = ((UID)(ref val2)).Value;
			val.Faction = (Factions)9;
			obj.Template = val;
			return obj;
		}

		public List<Sounds> GetAmbushSoundsList()
		{
			return new List<Sounds>
			{
				(Sounds)50045,
				(Sounds)50046,
				(Sounds)50040
			};
		}
	}
	public class SkeletonsWave : AnyWeaponWave
	{
		public SkeletonsWave()
		{
			base.AmbushSounds = GetAmbushSoundsList();
			base.NotificationMessage = "Skeletons are ambushing!";
			base.EnemyNamePrefix = "Ambush Skeleton";
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (WeaponTypes != null && WeaponTypes.Count > 0)
			{
				return AddEnemy(name, location, WeaponTypes);
			}
			SkeletonTemplate skeletonTemplate = GetSkeletonTemplate(name, location);
			skeletonTemplate.SpawnRandomSkeleton();
			return skeletonTemplate;
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 position, out int unusedMoney, int equipmentPrice = 0)
		{
			//IL_002e: 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)
			unusedMoney = equipmentPrice;
			if (WeaponTypes != null && WeaponTypes.Count > 0)
			{
				return AddEnemy(name, position, WeaponTypes, out unusedMoney, equipmentPrice);
			}
			SkeletonTemplate skeletonTemplate = GetSkeletonTemplate(name, position);
			unusedMoney = skeletonTemplate.SpawnRandomSkeletonForPrice(equipmentPrice);
			return skeletonTemplate;
		}

		public SkeletonTemplate AddEnemy(string name, Vector3 location, List<WeaponType> weaponTypes, out int unusedMoney, int equipmentPrice = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			SkeletonTemplate skeletonTemplate = GetSkeletonTemplate(name, location);
			unusedMoney = skeletonTemplate.SpawnRandomSkeletonForPrice(weaponTypes, equipmentPrice);
			return skeletonTemplate;
		}

		public EnemyTemplate AddEnemy(string name, Vector3 location, List<WeaponType> weaponTypes)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			SkeletonTemplate skeletonTemplate = GetSkeletonTemplate(name, location);
			skeletonTemplate.SpawnRandomSkeleton(weaponTypes);
			return skeletonTemplate;
		}

		public SkeletonTemplate GetSkeletonTemplate(string name, Vector3 location)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			SkeletonTemplate obj = new SkeletonTemplate
			{
				Name = name,
				AddCombatAI = true,
				CanDodge = true,
				CanBlock = true,
				SpawnPosition = location
			};
			SL_Character val = new SL_Character
			{
				Name = name
			};
			UID val2 = UID.Generate();
			val.UID = ((UID)(ref val2)).Value;
			val.Faction = (Factions)3;
			obj.Template = val;
			return obj;
		}

		public List<Sounds> GetAmbushSoundsList()
		{
			return new List<Sounds>
			{
				(Sounds)51898,
				(Sounds)51899,
				(Sounds)51900,
				(Sounds)51901
			};
		}
	}
	public class TroglodytesWave : EnemiesWave
	{
		public TroglodytesWave()
		{
			base.AmbushSounds = GetAmbushSoundsList();
			base.NotificationMessage = "Troglodyte are ambushing!";
			base.EnemyNamePrefix = "Ambush Troglodyte";
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location, out int unusedMoney, int equipmentPrice = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			TroglodyteTemplate troglodyteTemplate = GetTroglodyteTemplate(name, location);
			unusedMoney = troglodyteTemplate.SpawnRandomTrogForPrice(equipmentPrice);
			return troglodyteTemplate;
		}

		public override EnemyTemplate AddEnemy(string name, Vector3 location)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			TroglodyteTemplate troglodyteTemplate = GetTroglodyteTemplate(name, location);
			troglodyteTemplate.SpawnRandomTrog();
			return troglodyteTemplate;
		}

		public TroglodyteTemplate GetTroglodyteTemplate(string name, Vector3 location)
		{
			//IL_001b: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			TroglodyteTemplate obj = new TroglodyteTemplate
			{
				Name = name,
				AddCombatAI = true,
				CanBlock = true,
				SpawnPosition = location
			};
			SL_Character val = new SL_Character
			{
				Name = name
			};
			UID val2 = UID.Generate();
			val.UID = ((UID)(ref val2)).Value;
			val.Faction = (Factions)4;
			obj.Template = val;
			return obj;
		}

		public List<Sounds> GetAmbushSoundsList()
		{
			return new List<Sounds>
			{
				(Sounds)51118,
				(Sounds)51119,
				(Sounds)51120,
				(Sounds)51121
			};
		}
	}
}
namespace OutwardGameSettings.Utility.Enemies.Visuals
{
	public struct GenderData
	{
		public int TotalHairStyles;

		public int TotalHairColors;

		public int TotalHeadVariations;

		public GenderData(int totalHairStyles = 0, int totalHairColors = 0, int totalHeadVariations = 0)
		{
			TotalHairStyles = totalHairStyles;
			TotalHairColors = totalHairColors;
			TotalHeadVariations = totalHeadVariations;
		}
	}
	public struct RaceData
	{
		public GenderData Male;

		public GenderData Female;

		public RaceData(GenderData male, GenderData female)
		{
			Male = male;
			Female = female;
		}

		public GenderData GetGender(Gender gender)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)gender == 0)
			{
				return Male;
			}
			return Female;
		}
	}
}
namespace OutwardGameSettings.Utility.Enemies.Data
{
	public struct ArmorData
	{
		public int ItemId;

		public int GoldValue;

		public EquipmentSlotIDs EquipmentSlotId;

		public ArmorClass ArmorClass;

		public ArmorData(int itemId, int goldValue, EquipmentSlotIDs equipmentSlotId, ArmorClass armorClass = 1)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			ItemId = itemId;
			GoldValue = goldValue;
			EquipmentSlotId = equipmentSlotId;
			ArmorClass = armorClass;
		}
	}
	public struct EquipmentGroupData
	{
		public int ItemId;

		public int GoldValue;

		public EquipmentSlotIDs EquipmentSlotId;

		public EquipmentGroupData(int itemId, int goldValue, EquipmentSlotIDs equipmentSlotId)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			ItemId = itemId;
			GoldValue = goldValue;
			EquipmentSlotId = equipmentSlotId;
		}
	}
	public struct SkeletonTypeData
	{
		public int Health;

		public int HelmetId;

		public int ChestId;

		public int BootsId;

		public SkeletonTypeData(int health = 100, int helmetId = 3200031, int chestId = 3200030, int bootsId = 3200032)
		{
			Health = health;
			HelmetId = helmetId;
			ChestId = chestId;
			BootsId = bootsId;
		}
	}
	public struct TroglodyteTypeData
	{
		public int Health;

		public int? WeaponId;

		public int? ArmorId;

		public TroglodyteTypeData(int health = 100, int? weaponId = null, int? armorId = null)
		{
			Health = health;
			WeaponId = weaponId;
			ArmorId = armorId;
		}
	}
	public struct WeaponData
	{
		public int ItemId;

		public int GoldValue;

		public EquipmentSlotIDs EquipmentSlotId;

		public WeaponType WeaponType;

		public WeaponData(int itemId = 2130080, int goldValue = 6, EquipmentSlotIDs equipmentSlotId = 4, WeaponType weaponType = 54)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			ItemId = itemId;
			GoldValue = goldValue;
			EquipmentSlotId = equipmentSlotId;
			WeaponType = weaponType;
		}
	}
}
namespace OutwardGameSettings.Utility.Enemies.AI
{
	public class SL_CharacterAIBowRanged : SL_CharacterAI
	{
		[NonSerialized]
		[XmlIgnore]
		public AISCombatRanged AISCombatRanged;

		[NonSerialized]
		[XmlIgnore]
		public CharacterAI CharacterAI;

		public float AIContagionRange = 20f;

		public Vector2 Range = new Vector2(8f, 30f);

		public float Wander_Speed = 1.1f;

		public bool Wander_FollowPlayer;

		public WanderType Wander_Type;

		public SL_Waypoint[] Wander_PatrolWaypoints;

		public float Suspicious_Speed = 1.75f;

		public float Suspicious_Duration = 5f;

		public float Suspicious_Range = 30f;

		public float Suspicious_TurnModif = 0.9f;

		public Vector2 Combat_ChargeTime = new Vector2(0.4f, 1.2f);

		public float Combat_TargetVulnerableChargeModifier = 0.5f;

		public float Combat_ChargeAttackRangeMulti = 1f;

		public float Combat_ChargeTimeToAttack = 0.4f;

		public Vector2 Combat_ChargeStartRangeMult = new Vector2(0.8f, 3f);

		public float[] Combat_SpeedModifiers = new float[3] { 1.1f, 1.3f, 1.8f };

		public float Combat_ChanceToAttack = 75f;

		public bool Combat_KnowsUnblockable = true;

		public float Combat_DodgeCooldown = 3f;

		public AttackPattern[] Combat_AttackPatterns;

		protected override void ApplyToCharacter(Character character)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Invalid comparison between Unknown and I4
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			AIRoot val = new GameObject("BasicRanged_AIRoot").AddComponent<AIRoot>();
			((Component)val).gameObject.SetActive(false);
			((Component)val).transform.parent = ((Component)character).transform;
			AISWander val2 = new GameObject("1_Wander").AddComponent<AISWander>();
			((Component)val2).transform.parent = ((Component)val).transform;
			AISSuspicious val3 = new GameObject("2_Suspicious").AddComponent<AISSuspicious>();
			((Component)val3).transform.parent = ((Component)val).transform;
			AISSuspicious val4 = new GameObject("3_Alert").AddComponent<AISSuspicious>();
			((Component)val4).transform.parent = ((Component)val).transform;
			AISCombatRanged = new GameObject("4_CombatRanged").AddComponent<AISCombatRanged>();
			((Component)AISCombatRanged).transform.parent = ((Component)val).transform;
			((AIState)val2).ContagionRange = AIContagionRange;
			((AIState)val2).ForceNotCombat = base.ForceNonCombat;
			val2.SpeedModif = Wander_Speed;
			val2.WanderFar = base.CanWanderFar;
			val2.AutoFollowPlayer = Wander_FollowPlayer;
			if (Wander_PatrolWaypoints != null && (int)Wander_Type == 1)
			{
				GameObject val5 = new GameObject($"Waypoints_{character.UID}");
				val2.WaypointsParent = val5.transform;
				for (int i = 0; i < Wander_PatrolWaypoints.Length; i++)
				{
					GameObject val6 = new GameObject("Waypoint " + i + 1);
					Waypoint val7 = val6.AddComponent<Waypoint>();
					val6.transform.parent = val5.transform;
					val6.transform.position = Wander_PatrolWaypoints[i].WorldPosition;
					val7.RandomRadius = Wander_PatrolWaypoints[i].RandomRadius;
					val7.WaitTime = Wander_PatrolWaypoints[i].WaitTime;
				}
			}
			AICEnemyDetection val8 = new GameObject("Detection").AddComponent<AICEnemyDetection>();
			((Component)val8).transform.parent = ((Component)val2).transform;
			AIESwitchState val9 = new GameObject("DetectEffects").AddComponent<AIESwitchState>();
			val9.ToState = (AIState)(object)val3;
			((Component)val9).transform.parent = ((Component)val8).transform;
			val8.DetectEffectsTrans = ((Component)val9).transform;
			((AISWander)val3).SpeedModif = Suspicious_Speed;
			val3.SuspiciousDuration = Suspicious_Duration;
			((AISWander)val3).Range = Suspicious_Range;
			((AISWander)val3).WanderFar = base.CanWanderFar;
			((AISWander)val3).TurnModif = Suspicious_TurnModif;
			AIESwitchState val10 = new GameObject("EndSuspiciousEffects").AddComponent<AIESwitchState>();
			val10.ToState = (AIState)(object)val2;
			((Component)val10).gameObject.AddComponent<AIESheathe>().Sheathed = true;
			((Component)val10).transform.parent = ((Component)val3).transform;
			val3.EndSuspiciousEffectsTrans = ((Component)val10).transform;
			AICEnemyDetection val11 = new GameObject("Detection").AddComponent<AICEnemyDetection>();
			((Component)val11).transform.parent = ((Component)val3).transform;
			AIESwitchState val12 = new GameObject("DetectEffects").AddComponent<AIESwitchState>();
			val12.ToState = (AIState)(object)AISCombatRanged;
			((Component)val12).transform.parent = ((Component)val11).transform;
			val11.DetectEffectsTrans = ((Component)val12).transform;
			AIESwitchState val13 = new GameObject("SuspiciousEffects").AddComponent<AIESwitchState>();
			val13.ToState = (AIState)(object)val4;
			((Component)val13).transform.parent = ((Component)val11).transform;
			val11.SuspiciousEffectsTrans = ((Component)val13).transform;
			((AISWander)val4).SpeedModif = Suspicious_Speed;
			val4.SuspiciousDuration = Suspicious_Duration;
			((AISWander)val4).Range = Suspicious_Range;
			((AISWander)val4).WanderFar = base.CanWanderFar;
			((AISWander)val4).TurnModif = Suspicious_TurnModif;
			AIESwitchState val14 = new GameObject("EndSuspiciousEffects").AddComponent<AIESwitchState>();
			val14.ToState = (AIState)(object)val3;
			((Component)val14).gameObject.AddComponent<AIESheathe>().Sheathed = true;
			((Component)val14).transform.parent = ((Component)val4).transform;
			val4.EndSuspiciousEffectsTrans = ((Component)val14).transform;
			AICEnemyDetection val15 = new GameObject("Detection").AddComponent<AICEnemyDetection>();
			((Component)val15).transform.parent = ((Component)val4).transform;
			AIESwitchState val16 = new GameObject("DetectEffects").AddComponent<AIESwitchState>();
			val16.ToState = (AIState)(object)AISCombatRanged;
			((Component)val16).transform.parent = ((Component)val15).transform;
			val15.DetectEffectsTrans = ((Component)val16).transform;
			AISCombatRanged.ChargeTime = Combat_ChargeTime;
			AISCombatRanged.SpeedModifs = Combat_SpeedModifiers;
			((AISCombat)AISCombatRanged).ChanceToAttack = Combat_ChanceToAttack;
			((AISCombat)AISCombatRanged).KnowsUnblockable = Combat_KnowsUnblockable;
			((AISCombat)AISCombatRanged).DodgeCooldown = Combat_DodgeCooldown;
			((AISCombat)AISCombatRanged).CanBlock = base.CanBlock;
			((AISCombat)AISCombatRanged).CanDodge = base.CanDodge;
			AISCombatRanged.ShootChargeWeapon = true;
			((Component)new GameObject("Detection").AddComponent<AICEnemyDetection>()).transform.parent = ((Component)AISCombatRanged).transform;
			AIESwitchState obj = new GameObject("EndCombatEffects").AddComponent<AIESwitchState>();
			obj.ToState = (AIState)(object)val2;
			((Component)obj).transform.parent = ((Component)AISCombatRanged).transform;
			((Component)character).gameObject.AddComponent<NavMeshAgent>();
			((Component)character).gameObject.AddComponent<AISquadMember>();
			((Component)character).gameObject.AddComponent<EditorCharacterAILoadAI>();
			NavMeshObstacle component = ((Component)character).GetComponent<NavMeshObstacle>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			CharacterAI = ((Component)character).gameObject.AddComponent<CharacterAI>();
			((CharacterControl)CharacterAI).m_character = character;
			CharacterAI.AIStatesPrefab = val;
			CharacterHelpers.FixCharacterAINullOnQuestEvent(CharacterAI);
			AddQuiverRenewal((AISCombat)(object)AISCombatRanged, CharacterAI);
			CharacterAI.GetAIStates();
		}

		public void AddQuiverRenewal(AISCombat combatState, CharacterAI characterAI)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			AICQuiverEmpty val = new GameObject("Condition_Quiver_Empty").AddComponent<AICQuiverEmpty>();
			val.DetectionUpdateTime = 1f;
			((Component)val).transform.SetParent(((Component)combatState).transform);
			((AICondition)val).SubCondition = false;
			((Component)new GameObject("ValidEffects").AddComponent<AIESpawnRandomQuiver>()).transform.SetParent(((Component)val).transform);
			((AICondition)val).GroupValidEffectTrans = ((Component)val).transform;
		}

		public SL_CharacterAIBowRanged()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)