Decompiled source of ValheimCreatureSpawner v0.2.3

BepInEx/plugins/ValheimCreatureSpawner/ValheimCreatureSpawner.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ValheimCreatureSpawner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ValheimCreatureSpawner")]
[assembly: AssemblyTitle("ValheimCreatureSpawner")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SuperNova.ValheimCreatureSpawner
{
	internal enum CreatureCategory
	{
		Regular,
		Boss
	}
	internal sealed class CreatureMetadata
	{
		public string English;

		public string Russian;

		public CreatureCategory Category;

		public string[] Biomes;

		public CreatureMetadata(string english, string russian, CreatureCategory category, string biomeList)
		{
			English = english;
			Russian = russian;
			Category = category;
			Biomes = (string.IsNullOrWhiteSpace(biomeList) ? new string[0] : biomeList.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries));
		}
	}
	internal static class CreatureCatalog
	{
		private const string CatalogData = "\nEikthyr|Eikthyr|Эйктюр|Boss|Meadows\ngd_king|The Elder|Древний|Boss|Black Forest\nBonemass|Bonemass|Масса костей|Boss|Swamp\nDragon|Moder|Модер|Boss|Mountains\nGoblinKing|Yagluth|Яглут|Boss|Plains\nSeekerQueen|The Queen|Королева|Boss|Mistlands\nFader|Fader|Прародитель|Boss|Ashlands\nFrozenKing|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nFrozenKing_p2|Kall Fimbulbringer (phase 2)|Калль Фимбульбрингер (фаза 2)|Boss|Deep North\nFrozenKing_p3|Kall Fimbulbringer (phase 3)|Калль Фимбульбрингер (фаза 3)|Boss|Deep North\nKallFimbulbringer|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nBrenna|Brenna|Бренна|Boss|Black Forest\nGeirrhafa|Geirrhafa|Гейрафа|Boss|Mountains\nZil|Zil|Зил|Boss|Mistlands\nThungr|Thungr|Тангр|Boss|Mistlands\nCharred_Melee_Dyrnwyn|Lord Reto|Владыка Рето|Boss|Ashlands\nBoar|Boar|Кабан|Regular|Meadows;Black Forest\nBoar_piggy|Boar piglet|Поросёнок кабана|Regular|Meadows;Black Forest\nDeer|Deer|Олень|Regular|Meadows;Black Forest\nDeer_White|White deer|Белый олень|Regular|Deep North\nNeck|Neck|Никс|Regular|Meadows\nGreyling|Greyling|Грейлинг|Regular|Meadows\nGreydwarf|Greydwarf|Грейдворф|Regular|Black Forest\nGreydwarf_Elite|Greydwarf Brute|Грейдворф-берсерк|Regular|Black Forest\nGreydwarf_Shaman|Greydwarf Shaman|Грейдворф-шаман|Regular|Black Forest\nGreydwarf_Spawn|Greydwarf nest spawn|Порождение грейдворфов|Regular|Black Forest\nGreydwarf_Frozen|Frozen greydwarf|Ледяной грейдворф|Regular|Deep North\nGreydwarf_Shaman_Frozen|Frozen greydwarf shaman|Ледяной грейдворф-шаман|Regular|Deep North\nTroll|Troll|Тролль|Regular|Black Forest\nTrollFrost|Gammeltroll|Гаммельтролль|Regular|Deep North\nTroll_sleeping|Sleeping troll|Спящий тролль|Regular|Deep North\nSkeleton|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_NoArcher|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_Poison|Poison skeleton|Ядовитый скелет|Regular|Swamp\nSkeleton_Meadows|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Meadows_noarcher|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Mountains|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Mountains_noarcher|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Swamps|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_Swamps_noarcher|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_aspect|Skeleton aspect|Аспект скелета|Regular|Deep North\nDraugr|Draugr|Драугр|Regular|Swamp\nDraugr_Elite|Draugr Elite|Драугр-элита|Regular|Swamp\nDraugr_Ranged|Draugr Archer|Драугр-лучник|Regular|Swamp\nDraugr_Ranged_down|Draugr Archer (down)|Драугр-лучник (лежит)|Regular|Swamp\nDraugr_Elite_sleeping|Sleeping draugr elite|Спящий драугр-элита|Regular|Deep North\nDraugr_Ranged_sleeping|Sleeping draugr archer|Спящий драугр-лучник|Regular|Deep North\nDraugr_sleeping|Sleeping draugr|Спящий драугр|Regular|Deep North\nBlob|Blob|Сгустень|Regular|Swamp\nBlobElite|Blob elite|Большой сгустень|Regular|Swamp\nBlobTar|Tar blob|Дегтевой сгустень|Regular|Plains\nBlobMork|Shapeless Pulp|Бесформенная слизь|Regular|Deep North\nBlobMorkMini|Tiny Pulp|Крошечная слизь|Regular|Deep North\nBlobAspect|Blob aspect|Аспект сгустня|Regular|Deep North\nLeech|Leech|Пиявка|Regular|Swamp\nWraith|Wraith|Призрак|Regular|Swamp\nGhost|Ghost|Призрак|Regular|Black Forest\nGhost_old|Old ghost|Старый призрак|Regular|Deep North\nGhost_sleeping|Sleeping ghost|Спящий призрак|Regular|Deep North\nGhost_Void|Void ghost|Пустотный призрак|Regular|Deep North\nAbomination|Abomination|Мерзость|Regular|Swamp\nSurtling|Surtling|Суртлинг|Regular|Swamp;Ashlands\nWolf|Wolf|Волк|Regular|Mountains\nWolf_cub|Wolf cub|Волчонок|Regular|Mountains\nWolf_spiritcaller|Spirit-caller wolf|Волк призывателя духов|Regular|Deep North\nFenring|Fenring|Фенринг|Regular|Mountains\nFenring_Cultist|Fenring Cultist|Фенринг-культист|Regular|Mountains\nHatchling|Drake|Дракончик|Regular|Mountains\nStoneGolem|Stone Golem|Каменный голем|Regular|Mountains\nUlv|Ulv|Ульв|Regular|Mountains\nBat|Bat|Летучая мышь|Regular|Mountains\nBear|Bear|Медведь|Regular|Deep North\nCultist|Cultist|Культист|Regular|Mountains\nSerpent|Serpent|Морской змей|Regular|Ocean\nDeathsquito|Deathsquito|Смертожал|Regular|Plains\nLox|Lox|Локс|Regular|Plains\nGoblin|Fuling|Фулинг|Regular|Plains\nGoblinArcher|Fuling Archer|Фулинг-лучник|Regular|Plains\nGoblinShaman|Fuling Shaman|Фулинг-шаман|Regular|Plains\nGoblinBrute|Fuling Berserker|Фулинг-берсерк|Regular|Plains\nAsksvin|Asksvin|Асксвин|Regular|Ashlands\nAsksvin_cub|Asksvin calf|Детёныш асксвина|Regular|Ashlands\nMorgen|Morgen|Морген|Regular|Ashlands\nMorgen_Naked|Morgen (unarmored)|Морген без брони|Regular|Ashlands\nFallenValkyrie|Charred Valkyrie|Обугленная валькирия|Regular|Ashlands\nCharred_Twitcher|Charred Twitcher|Обугленный прыгун|Regular|Ashlands\nCharred_Melee|Charred Warrior|Обугленный воин|Regular|Ashlands\nCharred_Archer|Charred Marksman|Обугленный стрелок|Regular|Ashlands\nCharred_Mage|Charred Mage|Обугленный маг|Regular|Ashlands\nVolture|Volture|Вольтур|Regular|Ashlands\nTick|Tick|Клещ|Regular|Mistlands\nSeeker|Seeker|Искатель|Regular|Mistlands\nSeekerBrood|Seeker Brood|Выводок искателя|Regular|Mistlands\nSeekerBrute|Seeker Soldier|Искатель-солдат|Regular|Mistlands\nGjall|Gjall|Гьялль|Regular|Mistlands\nHare|Hare|Заяц|Regular|Mistlands\nDverger|Dvergr|Дверг|Regular|Mistlands\nDvergerMage|Dvergr Mage|Дверг-маг|Regular|Mistlands\nDvergerMageFire|Dvergr Fire Mage|Дверг-маг огня|Regular|Mistlands\nDvergerMageIce|Dvergr Frost Mage|Дверг-маг льда|Regular|Mistlands\nDvergerMageSupport|Dvergr Support Mage|Дверг-маг поддержки|Regular|Mistlands\nDvergerRogue|Dvergr Rogue|Дверг-разведчик|Regular|Mistlands\nChicken|Chicken|Курица|Regular|Any Biome\nHen|Hen|Курица-несушка|Regular|Any Biome\nFish1|Fish|Рыба|Regular|Rivers;Ocean\nFish2|Fish|Рыба|Regular|Rivers;Ocean\nFish3|Fish|Рыба|Regular|Ocean\nFish4_cave|Cave fish|Пещерная рыба|Regular|Mountain Caves\nCrow|Crow|Ворон|Regular|Any Biome\nAshCrow|Ash crow|Пепельный ворон|Regular|Ashlands\nGull|Gull|Чайка|Regular|Ocean;Meadows;Black Forest;Plains\nLeviathan|Leviathan|Левиафан|Regular|Ocean\nHugin|Hugin|Хугин|Regular|Any Biome\nMunin|Munin|Мунин|Regular|Mistlands;Ashlands\nOdin|Odin|Один|Regular|Any Biome\nValkyrie|Valkyrie|Валькирия|Regular|Any Biome\nHaldor|Haldor|Хальдор|Regular|Black Forest\nHildir|Hildir|Хильдир|Regular|Meadows\nBogWitch|The Bog Witch|Болотная ведьма|Regular|Swamp\nHalstein|Halstein|Хальштейн|Regular|Meadows\nBlub|Blåbær|Блубэр|Regular|Meadows\nHallon|Hallon|Халлон|Regular|Meadows\nBoar_spiritcaller|Spirit-caller boar|Кабан призывателя духов|Regular|Deep North\nMoose|Moose|Лось|Regular|Deep North\nMoose_calf|Moose calf|Лосёнок|Regular|Deep North\nMoose_spiritcaller|Spirit-caller moose|Лось призывателя духов|Regular|Deep North\nSeal|Seal|Тюлень|Regular|Deep North\nSeal_Pup|Seal pup|Детёныш тюленя|Regular|Deep North\nFrysling|Frysling|Фризлинг|Regular|Deep North\nFrostWisp|Frost Wisp|Ледяной дух|Regular|Deep North\nBat_Swamp|Swamp bat|Болотная летучая мышь|Regular|Swamp\nBarka|Barka|Барка|Regular|Deep North\nElaking|Elaking|Элакинг|Regular|Deep North\nElakingLantern|Elaking Lantern|Элакинг с фонарём|Regular|Deep North\nElakingMole|Eyeless One|Безглазый|Regular|Deep North\nFallenWarrior|Fallen Warrior|Павший воин|Regular|Deep North\nJotunWarrior|Krigen|Криген|Regular|Deep North\nJotunWarriorDualWield|Krigen (dual wield)|Криген с двумя оружиями|Regular|Deep North\nJotunWitch|Hexen|Хексен|Regular|Deep North\nShadowPerson|Shadow|Тень|Regular|Deep North\nTendril|Tendril|Усик|Regular|Deep North\nTendril_back|Back tendril|Задний усик|Regular|Deep North\nTentaRoot_wild|Wild tentaroot|Дикая тентакорень|Regular|Deep North\nWrithan|Writhan|Ритхан|Regular|Deep North\nGoblinDeepNorth|Deep North goblin|Гоблин Дальнего севера|Regular|Deep North\nDvergerDeepNorth|Imprisoned Dvergr|Пленённый дверг|Regular|Deep North\nBjorn_sleeping|Sleeping Bjorn|Спящий Бьёрн|Regular|Deep North\nBjorn_spiritcaller|Spirit-caller Bjorn|Бьёрн призывателя духов|Regular|Deep North\nAspect_Eikthyr|Aspect of the Lightning Stag|Аспект Эйктюра|Boss|Any Biome\nAspect_Elder|Aspect of the Living Forest|Аспект Древнего|Boss|Any Biome\nAspect_Bonemass|Aspect of the Twisted Soul|Аспект Массы костей|Boss|Any Biome\nAspect_Moder|Aspect of the Dragon Mother|Аспект Модер|Boss|Any Biome\nAspect_Yagluth|Aspect of the Writhing Dead|Аспект Яглута|Boss|Any Biome\nAspect_SeekerQueen|Aspect of the Crawling Matriarch|Аспект Королевы|Boss|Any Biome\nAspect_Fader|Aspect of the Emerald Flame|Аспект Прародителя|Boss|Any Biome\nAspect_TentaRoot|Aspect of the Tentaroot|Аспект тентакорня|Boss|Any Biome\n";

		private static readonly Dictionary<string, CreatureMetadata> Metadata = Build();

		private static Dictionary<string, CreatureMetadata> Build()
		{
			Dictionary<string, CreatureMetadata> dictionary = new Dictionary<string, CreatureMetadata>(StringComparer.OrdinalIgnoreCase);
			string[] array = "\nEikthyr|Eikthyr|Эйктюр|Boss|Meadows\ngd_king|The Elder|Древний|Boss|Black Forest\nBonemass|Bonemass|Масса костей|Boss|Swamp\nDragon|Moder|Модер|Boss|Mountains\nGoblinKing|Yagluth|Яглут|Boss|Plains\nSeekerQueen|The Queen|Королева|Boss|Mistlands\nFader|Fader|Прародитель|Boss|Ashlands\nFrozenKing|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nFrozenKing_p2|Kall Fimbulbringer (phase 2)|Калль Фимбульбрингер (фаза 2)|Boss|Deep North\nFrozenKing_p3|Kall Fimbulbringer (phase 3)|Калль Фимбульбрингер (фаза 3)|Boss|Deep North\nKallFimbulbringer|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nBrenna|Brenna|Бренна|Boss|Black Forest\nGeirrhafa|Geirrhafa|Гейрафа|Boss|Mountains\nZil|Zil|Зил|Boss|Mistlands\nThungr|Thungr|Тангр|Boss|Mistlands\nCharred_Melee_Dyrnwyn|Lord Reto|Владыка Рето|Boss|Ashlands\nBoar|Boar|Кабан|Regular|Meadows;Black Forest\nBoar_piggy|Boar piglet|Поросёнок кабана|Regular|Meadows;Black Forest\nDeer|Deer|Олень|Regular|Meadows;Black Forest\nDeer_White|White deer|Белый олень|Regular|Deep North\nNeck|Neck|Никс|Regular|Meadows\nGreyling|Greyling|Грейлинг|Regular|Meadows\nGreydwarf|Greydwarf|Грейдворф|Regular|Black Forest\nGreydwarf_Elite|Greydwarf Brute|Грейдворф-берсерк|Regular|Black Forest\nGreydwarf_Shaman|Greydwarf Shaman|Грейдворф-шаман|Regular|Black Forest\nGreydwarf_Spawn|Greydwarf nest spawn|Порождение грейдворфов|Regular|Black Forest\nGreydwarf_Frozen|Frozen greydwarf|Ледяной грейдворф|Regular|Deep North\nGreydwarf_Shaman_Frozen|Frozen greydwarf shaman|Ледяной грейдворф-шаман|Regular|Deep North\nTroll|Troll|Тролль|Regular|Black Forest\nTrollFrost|Gammeltroll|Гаммельтролль|Regular|Deep North\nTroll_sleeping|Sleeping troll|Спящий тролль|Regular|Deep North\nSkeleton|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_NoArcher|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_Poison|Poison skeleton|Ядовитый скелет|Regular|Swamp\nSkeleton_Meadows|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Meadows_noarcher|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Mountains|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Mountains_noarcher|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Swamps|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_Swamps_noarcher|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_aspect|Skeleton aspect|Аспект скелета|Regular|Deep North\nDraugr|Draugr|Драугр|Regular|Swamp\nDraugr_Elite|Draugr Elite|Драугр-элита|Regular|Swamp\nDraugr_Ranged|Draugr Archer|Драугр-лучник|Regular|Swamp\nDraugr_Ranged_down|Draugr Archer (down)|Драугр-лучник (лежит)|Regular|Swamp\nDraugr_Elite_sleeping|Sleeping draugr elite|Спящий драугр-элита|Regular|Deep North\nDraugr_Ranged_sleeping|Sleeping draugr archer|Спящий драугр-лучник|Regular|Deep North\nDraugr_sleeping|Sleeping draugr|Спящий драугр|Regular|Deep North\nBlob|Blob|Сгустень|Regular|Swamp\nBlobElite|Blob elite|Большой сгустень|Regular|Swamp\nBlobTar|Tar blob|Дегтевой сгустень|Regular|Plains\nBlobMork|Shapeless Pulp|Бесформенная слизь|Regular|Deep North\nBlobMorkMini|Tiny Pulp|Крошечная слизь|Regular|Deep North\nBlobAspect|Blob aspect|Аспект сгустня|Regular|Deep North\nLeech|Leech|Пиявка|Regular|Swamp\nWraith|Wraith|Призрак|Regular|Swamp\nGhost|Ghost|Призрак|Regular|Black Forest\nGhost_old|Old ghost|Старый призрак|Regular|Deep North\nGhost_sleeping|Sleeping ghost|Спящий призрак|Regular|Deep North\nGhost_Void|Void ghost|Пустотный призрак|Regular|Deep North\nAbomination|Abomination|Мерзость|Regular|Swamp\nSurtling|Surtling|Суртлинг|Regular|Swamp;Ashlands\nWolf|Wolf|Волк|Regular|Mountains\nWolf_cub|Wolf cub|Волчонок|Regular|Mountains\nWolf_spiritcaller|Spirit-caller wolf|Волк призывателя духов|Regular|Deep North\nFenring|Fenring|Фенринг|Regular|Mountains\nFenring_Cultist|Fenring Cultist|Фенринг-культист|Regular|Mountains\nHatchling|Drake|Дракончик|Regular|Mountains\nStoneGolem|Stone Golem|Каменный голем|Regular|Mountains\nUlv|Ulv|Ульв|Regular|Mountains\nBat|Bat|Летучая мышь|Regular|Mountains\nBear|Bear|Медведь|Regular|Deep North\nCultist|Cultist|Культист|Regular|Mountains\nSerpent|Serpent|Морской змей|Regular|Ocean\nDeathsquito|Deathsquito|Смертожал|Regular|Plains\nLox|Lox|Локс|Regular|Plains\nGoblin|Fuling|Фулинг|Regular|Plains\nGoblinArcher|Fuling Archer|Фулинг-лучник|Regular|Plains\nGoblinShaman|Fuling Shaman|Фулинг-шаман|Regular|Plains\nGoblinBrute|Fuling Berserker|Фулинг-берсерк|Regular|Plains\nAsksvin|Asksvin|Асксвин|Regular|Ashlands\nAsksvin_cub|Asksvin calf|Детёныш асксвина|Regular|Ashlands\nMorgen|Morgen|Морген|Regular|Ashlands\nMorgen_Naked|Morgen (unarmored)|Морген без брони|Regular|Ashlands\nFallenValkyrie|Charred Valkyrie|Обугленная валькирия|Regular|Ashlands\nCharred_Twitcher|Charred Twitcher|Обугленный прыгун|Regular|Ashlands\nCharred_Melee|Charred Warrior|Обугленный воин|Regular|Ashlands\nCharred_Archer|Charred Marksman|Обугленный стрелок|Regular|Ashlands\nCharred_Mage|Charred Mage|Обугленный маг|Regular|Ashlands\nVolture|Volture|Вольтур|Regular|Ashlands\nTick|Tick|Клещ|Regular|Mistlands\nSeeker|Seeker|Искатель|Regular|Mistlands\nSeekerBrood|Seeker Brood|Выводок искателя|Regular|Mistlands\nSeekerBrute|Seeker Soldier|Искатель-солдат|Regular|Mistlands\nGjall|Gjall|Гьялль|Regular|Mistlands\nHare|Hare|Заяц|Regular|Mistlands\nDverger|Dvergr|Дверг|Regular|Mistlands\nDvergerMage|Dvergr Mage|Дверг-маг|Regular|Mistlands\nDvergerMageFire|Dvergr Fire Mage|Дверг-маг огня|Regular|Mistlands\nDvergerMageIce|Dvergr Frost Mage|Дверг-маг льда|Regular|Mistlands\nDvergerMageSupport|Dvergr Support Mage|Дверг-маг поддержки|Regular|Mistlands\nDvergerRogue|Dvergr Rogue|Дверг-разведчик|Regular|Mistlands\nChicken|Chicken|Курица|Regular|Any Biome\nHen|Hen|Курица-несушка|Regular|Any Biome\nFish1|Fish|Рыба|Regular|Rivers;Ocean\nFish2|Fish|Рыба|Regular|Rivers;Ocean\nFish3|Fish|Рыба|Regular|Ocean\nFish4_cave|Cave fish|Пещерная рыба|Regular|Mountain Caves\nCrow|Crow|Ворон|Regular|Any Biome\nAshCrow|Ash crow|Пепельный ворон|Regular|Ashlands\nGull|Gull|Чайка|Regular|Ocean;Meadows;Black Forest;Plains\nLeviathan|Leviathan|Левиафан|Regular|Ocean\nHugin|Hugin|Хугин|Regular|Any Biome\nMunin|Munin|Мунин|Regular|Mistlands;Ashlands\nOdin|Odin|Один|Regular|Any Biome\nValkyrie|Valkyrie|Валькирия|Regular|Any Biome\nHaldor|Haldor|Хальдор|Regular|Black Forest\nHildir|Hildir|Хильдир|Regular|Meadows\nBogWitch|The Bog Witch|Болотная ведьма|Regular|Swamp\nHalstein|Halstein|Хальштейн|Regular|Meadows\nBlub|Blåbær|Блубэр|Regular|Meadows\nHallon|Hallon|Халлон|Regular|Meadows\nBoar_spiritcaller|Spirit-caller boar|Кабан призывателя духов|Regular|Deep North\nMoose|Moose|Лось|Regular|Deep North\nMoose_calf|Moose calf|Лосёнок|Regular|Deep North\nMoose_spiritcaller|Spirit-caller moose|Лось призывателя духов|Regular|Deep North\nSeal|Seal|Тюлень|Regular|Deep North\nSeal_Pup|Seal pup|Детёныш тюленя|Regular|Deep North\nFrysling|Frysling|Фризлинг|Regular|Deep North\nFrostWisp|Frost Wisp|Ледяной дух|Regular|Deep North\nBat_Swamp|Swamp bat|Болотная летучая мышь|Regular|Swamp\nBarka|Barka|Барка|Regular|Deep North\nElaking|Elaking|Элакинг|Regular|Deep North\nElakingLantern|Elaking Lantern|Элакинг с фонарём|Regular|Deep North\nElakingMole|Eyeless One|Безглазый|Regular|Deep North\nFallenWarrior|Fallen Warrior|Павший воин|Regular|Deep North\nJotunWarrior|Krigen|Криген|Regular|Deep North\nJotunWarriorDualWield|Krigen (dual wield)|Криген с двумя оружиями|Regular|Deep North\nJotunWitch|Hexen|Хексен|Regular|Deep North\nShadowPerson|Shadow|Тень|Regular|Deep North\nTendril|Tendril|Усик|Regular|Deep North\nTendril_back|Back tendril|Задний усик|Regular|Deep North\nTentaRoot_wild|Wild tentaroot|Дикая тентакорень|Regular|Deep North\nWrithan|Writhan|Ритхан|Regular|Deep North\nGoblinDeepNorth|Deep North goblin|Гоблин Дальнего севера|Regular|Deep North\nDvergerDeepNorth|Imprisoned Dvergr|Пленённый дверг|Regular|Deep North\nBjorn_sleeping|Sleeping Bjorn|Спящий Бьёрн|Regular|Deep North\nBjorn_spiritcaller|Spirit-caller Bjorn|Бьёрн призывателя духов|Regular|Deep North\nAspect_Eikthyr|Aspect of the Lightning Stag|Аспект Эйктюра|Boss|Any Biome\nAspect_Elder|Aspect of the Living Forest|Аспект Древнего|Boss|Any Biome\nAspect_Bonemass|Aspect of the Twisted Soul|Аспект Массы костей|Boss|Any Biome\nAspect_Moder|Aspect of the Dragon Mother|Аспект Модер|Boss|Any Biome\nAspect_Yagluth|Aspect of the Writhing Dead|Аспект Яглута|Boss|Any Biome\nAspect_SeekerQueen|Aspect of the Crawling Matriarch|Аспект Королевы|Boss|Any Biome\nAspect_Fader|Aspect of the Emerald Flame|Аспект Прародителя|Boss|Any Biome\nAspect_TentaRoot|Aspect of the Tentaroot|Аспект тентакорня|Boss|Any Biome\n".Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0 || text.StartsWith("#", StringComparison.Ordinal))
				{
					continue;
				}
				string[] array2 = text.Split('|');
				if (array2.Length >= 5)
				{
					CreatureCategory category = CreatureCategory.Regular;
					if (array2[3].Equals("Boss", StringComparison.OrdinalIgnoreCase))
					{
						category = CreatureCategory.Boss;
					}
					dictionary[array2[0].Trim()] = new CreatureMetadata(array2[1].Trim(), array2[2].Trim(), category, array2[4].Trim());
				}
			}
			return dictionary;
		}

		public static bool TryGet(string prefabName, out CreatureMetadata metadata)
		{
			return Metadata.TryGetValue(prefabName ?? string.Empty, out metadata);
		}
	}
	[BepInPlugin("com.supernova.valheimcreaturespawner", "Valheim Creature Spawner", "0.2.2")]
	public sealed class CreatureSpawnerPlugin : BaseUnityPlugin
	{
		private sealed class CreatureEntry
		{
			public readonly GameObject Prefab;

			public readonly string PrefabName;

			public readonly string EnglishName;

			public readonly string RussianName;

			public readonly string LocalizedName;

			public readonly CreatureCategory Category;

			public readonly string[] Biomes;

			public string CategoryLabel
			{
				get
				{
					if (Category != CreatureCategory.Boss)
					{
						return "Regular";
					}
					return "Boss";
				}
			}

			public string BiomeLabel
			{
				get
				{
					if (Biomes != null && Biomes.Length != 0)
					{
						return string.Join(", ", Biomes);
					}
					return "Unknown";
				}
			}

			public CreatureEntry(GameObject prefab, string prefabName, string englishName, string russianName, string localizedName, CreatureCategory category, string[] biomes)
			{
				Prefab = prefab;
				PrefabName = prefabName ?? string.Empty;
				EnglishName = (string.IsNullOrWhiteSpace(englishName) ? PrefabName : englishName);
				RussianName = (string.IsNullOrWhiteSpace(russianName) ? PrefabName : russianName);
				LocalizedName = localizedName ?? string.Empty;
				Category = category;
				Biomes = biomes ?? new string[1] { "Unknown" };
			}
		}

		public const string PluginGuid = "com.supernova.valheimcreaturespawner";

		public const string PluginName = "Valheim Creature Spawner";

		public const string PluginVersion = "0.2.2";

		private ConfigEntry<KeyCode> _toggleKey;

		private ConfigEntry<KeyCode> _spawnFrontKey;

		private ConfigEntry<KeyCode> _spawnAimKey;

		private ConfigEntry<int> _defaultCount;

		private ConfigEntry<int> _defaultLevel;

		private Harmony _harmony;

		private static CreatureSpawnerPlugin _activeInstance;

		private float _suppressInputUntil;

		private readonly List<CreatureEntry> _entries = new List<CreatureEntry>();

		private readonly List<CreatureEntry> _filtered = new List<CreatureEntry>();

		private readonly string[] _biomeOptions = new string[14]
		{
			"All Biomes", "Meadows", "Black Forest", "Swamp", "Mountains", "Plains", "Ocean", "Rivers", "Mistlands", "Ashlands",
			"Deep North", "Mountain Caves", "Any Biome", "Unknown"
		};

		private Rect _windowRect = new Rect(30f, 35f, 840f, 720f);

		private Vector2 _listScroll;

		private bool _isOpen;

		private bool _searchHasFocus;

		private bool _nameHasFocus;

		private bool _confirmKillAll;

		private float _confirmKillAllUntil;

		private bool _cursorStateStored;

		private bool _oldCursorVisible;

		private CursorLockMode _oldCursorLockState;

		private bool _catalogReady;

		private float _nextRefresh;

		private string _search = string.Empty;

		private string _customName = string.Empty;

		private string _status = "Enter a world to load the creature catalogue.";

		private int _categoryFilter;

		private int _biomeFilter;

		private int _count = 1;

		private int _level = 1;

		private CreatureEntry _selected;

		private Type _characterType;

		private Type _zNetSceneType;

		private Type _zNetType;

		private Type _playerType;

		private Type _zNetViewType;

		private Component _playerComponent;

		private object _zNetSceneInstance;

		private object _lastCatalogScene;

		private object _zNetInstance;

		private void Awake()
		{
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "ToggleHUD", (KeyCode)287, "Open or close the creature spawner HUD.");
			_spawnFrontKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "SpawnInFront", (KeyCode)288, "Spawn the selected creature in front of the player.");
			_spawnAimKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "SpawnAtCrosshair", (KeyCode)289, "Spawn the selected creature at the crosshair target.");
			_defaultCount = ((BaseUnityPlugin)this).Config.Bind<int>("Spawner", "DefaultCount", 1, "Number of creatures to spawn (1–50).");
			_defaultLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Spawner", "DefaultLevel", 1, "Level: 1 = 0 stars, 2 = 1 star, 3 = 2 stars.");
			_count = Mathf.Clamp(_defaultCount.Value, 1, 50);
			_level = Mathf.Clamp(_defaultLevel.Value, 1, 3);
			_characterType = FindType("Character");
			_zNetSceneType = FindType("ZNetScene");
			_zNetType = FindType("ZNet");
			_playerType = FindType("Player");
			_zNetViewType = FindType("ZNetView");
			_activeInstance = this;
			InstallInputGuards();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Valheim Creature Spawner loaded. Press " + ((object)_toggleKey.Value/*cast due to .constrained prefix*/).ToString() + " to open HUD."));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"The catalogue is discovered from the active ZNetScene; known creatures use English display names, Russian search aliases, and curated biome/category metadata.");
		}

		private void Update()
		{
			//IL_000e: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (_toggleKey != null && (int)_toggleKey.Value != 0 && Input.GetKeyDown(_toggleKey.Value))
			{
				SetOpen(!_isOpen);
			}
			if (_confirmKillAll && Time.unscaledTime > _confirmKillAllUntil)
			{
				_confirmKillAll = false;
			}
			if (_isOpen)
			{
				if (Input.GetKeyDown((KeyCode)27))
				{
					SetOpen(open: false);
					return;
				}
				if (!_searchHasFocus && !_nameHasFocus && (int)_spawnFrontKey.Value != 0 && Input.GetKeyDown(_spawnFrontKey.Value))
				{
					SpawnSelected(atCrosshair: false);
				}
				if (!_searchHasFocus && !_nameHasFocus && (int)_spawnAimKey.Value != 0 && Input.GetKeyDown(_spawnAimKey.Value))
				{
					SpawnSelected(atCrosshair: true);
				}
			}
			if (Time.unscaledTime >= _nextRefresh)
			{
				_nextRefresh = Time.unscaledTime + 4f;
				RefreshGameReferences();
				if (!_catalogReady && _zNetSceneInstance != null)
				{
					RefreshCatalogue();
				}
			}
		}

		private void LateUpdate()
		{
			if (_isOpen)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
		}

		private void OnGUI()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			if (_isOpen)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				float num = Mathf.Max(620f, (float)Screen.width - 20f);
				float num2 = Mathf.Max(480f, (float)Screen.height - 20f);
				((Rect)(ref _windowRect)).width = Mathf.Min(((Rect)(ref _windowRect)).width, num);
				((Rect)(ref _windowRect)).height = Mathf.Min(((Rect)(ref _windowRect)).height, num2);
				((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _windowRect)).width));
				((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _windowRect)).height));
				_windowRect = GUI.Window(731906, _windowRect, new WindowFunction(DrawWindow), "CREATURE SPAWNER  ·  SuperNova");
			}
		}

		private void DrawWindow(int windowId)
		{
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_068c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0691: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07df: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search by English name, Russian name, or prefab ID.", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(62f) });
			GUI.SetNextControlName("CreatureSpawner.Search");
			_search = GUILayout.TextField(_search, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.MinWidth(220f),
				GUILayout.ExpandWidth(true)
			});
			_searchHasFocus = GUI.GetNameOfFocusedControl() == "CreatureSpawner.Search";
			if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
			{
				_search = string.Empty;
				GUI.FocusControl("CreatureSpawner.Search");
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawCategoryButton("All", 0);
			DrawCategoryButton("Regular", 1);
			DrawCategoryButton("Bosses", 2);
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Biome:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) });
			if (GUILayout.Button("◀", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
			{
				_biomeFilter = (_biomeFilter - 1 + _biomeOptions.Length) % _biomeOptions.Length;
			}
			GUILayout.Label(_biomeOptions[_biomeFilter], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) });
			if (GUILayout.Button("▶", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
			{
				_biomeFilter = (_biomeFilter + 1) % _biomeOptions.Length;
			}
			GUILayout.Label("Found: " + BuildFilteredList(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.EndHorizontal();
			GUILayout.Space(5f);
			_listScroll = GUILayout.BeginScrollView(_listScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			_filtered.Clear();
			for (int i = 0; i < _entries.Count; i++)
			{
				CreatureEntry creatureEntry = _entries[i];
				if (MatchesFilters(creatureEntry))
				{
					_filtered.Add(creatureEntry);
					GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
					if (GUILayout.Button(creatureEntry.EnglishName + "  ·  " + creatureEntry.PrefabName, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.MinWidth(280f),
						GUILayout.ExpandWidth(true)
					}))
					{
						_selected = creatureEntry;
					}
					GUILayout.Label(creatureEntry.CategoryLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
					GUILayout.Label(creatureEntry.BiomeLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
					GUILayout.EndHorizontal();
					if (_selected == creatureEntry)
					{
						GUILayout.Label("Prefab: " + creatureEntry.PrefabName, Array.Empty<GUILayoutOption>());
					}
				}
			}
			GUILayout.EndScrollView();
			GUILayout.Space(5f);
			GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
			if (_selected == null)
			{
				GUILayout.Label("Select a creature from the list above.", Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Selected: " + _selected.EnglishName, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Prefab ID: " + _selected.PrefabName, Array.Empty<GUILayoutOption>());
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Custom name (optional):", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(205f) });
			GUI.SetNextControlName("CreatureSpawner.CustomName");
			_customName = GUILayout.TextField(_customName, 48, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.MinWidth(220f),
				GUILayout.ExpandWidth(true)
			});
			_nameHasFocus = GUI.GetNameOfFocusedControl() == "CreatureSpawner.CustomName";
			if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
			{
				_customName = string.Empty;
				GUI.FocusControl("CreatureSpawner.CustomName");
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Count:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(98f) });
			if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
			{
				_count = Mathf.Max(1, _count - 1);
			}
			GUILayout.Label(_count.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
			if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
			{
				_count = Mathf.Min(50, _count + 1);
			}
			GUILayout.Space(18f);
			GUILayout.Label("Level / stars:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) });
			if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
			{
				_level = Mathf.Max(1, _level - 1);
			}
			GUILayout.Label(_level + "  (" + (_level - 1) + "★)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
			if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
			{
				_level = Mathf.Min(3, _level + 1);
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.enabled = _selected != null;
			if (GUILayout.Button("Spawn in front  [" + ((object)_spawnFrontKey.Value/*cast due to .constrained prefix*/).ToString() + "]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
			{
				SpawnSelected(atCrosshair: false);
			}
			if (GUILayout.Button("Spawn at crosshair  [" + ((object)_spawnAimKey.Value/*cast due to .constrained prefix*/).ToString() + "]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
			{
				SpawnSelected(atCrosshair: true);
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			if (!_confirmKillAll)
			{
				Color backgroundColor = GUI.backgroundColor;
				GUI.backgroundColor = new Color(0.62f, 0.24f, 0.2f, 1f);
				if (GUILayout.Button("Kill all nearby creatures  [killall]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }))
				{
					_confirmKillAll = true;
					_confirmKillAllUntil = Time.unscaledTime + 8f;
				}
				GUI.backgroundColor = backgroundColor;
			}
			else
			{
				GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
				GUILayout.Label("Kill all nearby creatures, including tamed ones? Players are not affected.", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				if (GUILayout.Button("Confirm", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(100f),
					GUILayout.Height(30f)
				}))
				{
					_confirmKillAll = false;
					KillNearbyCreatures();
				}
				if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(75f),
					GUILayout.Height(30f)
				}))
				{
					_confirmKillAll = false;
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.EndVertical();
			GUILayout.Label(_status, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.Label("F6: close HUD  ·  F7: spawn in front  ·  F8: spawn at crosshair. Player controls are disabled while the HUD is open.", Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 24f));
		}

		private void DrawCategoryButton(string title, int value)
		{
			if (GUILayout.Button((_categoryFilter == value) ? ("[ " + title + " ]") : title, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				_categoryFilter = value;
			}
		}

		private bool MatchesFilters(CreatureEntry entry)
		{
			if (_categoryFilter == 1 && entry.Category != CreatureCategory.Regular)
			{
				return false;
			}
			if (_categoryFilter == 2 && entry.Category != CreatureCategory.Boss)
			{
				return false;
			}
			string text = _biomeOptions[_biomeFilter];
			if (text != "All Biomes")
			{
				bool flag = false;
				for (int i = 0; i < entry.Biomes.Length; i++)
				{
					if (entry.Biomes[i].Equals(text, StringComparison.OrdinalIgnoreCase))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					return false;
				}
			}
			if (string.IsNullOrWhiteSpace(_search))
			{
				return true;
			}
			string needle = _search.Trim();
			if (!ContainsIgnoreCase(entry.PrefabName, needle) && !ContainsIgnoreCase(entry.EnglishName, needle) && !ContainsIgnoreCase(entry.RussianName, needle))
			{
				return ContainsIgnoreCase(entry.LocalizedName, needle);
			}
			return true;
		}

		private static bool ContainsIgnoreCase(string haystack, string needle)
		{
			if (!string.IsNullOrEmpty(haystack))
			{
				return haystack.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private int BuildFilteredList()
		{
			int num = 0;
			for (int i = 0; i < _entries.Count; i++)
			{
				if (MatchesFiltersWithoutCount(_entries[i]))
				{
					num++;
				}
			}
			return num;
		}

		private bool MatchesFiltersWithoutCount(CreatureEntry entry)
		{
			if (_categoryFilter == 1 && entry.Category != CreatureCategory.Regular)
			{
				return false;
			}
			if (_categoryFilter == 2 && entry.Category != CreatureCategory.Boss)
			{
				return false;
			}
			string text = _biomeOptions[_biomeFilter];
			if (text != "All Biomes")
			{
				bool flag = false;
				for (int i = 0; i < entry.Biomes.Length; i++)
				{
					if (string.Equals(entry.Biomes[i], text, StringComparison.OrdinalIgnoreCase))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					return false;
				}
			}
			if (string.IsNullOrWhiteSpace(_search))
			{
				return true;
			}
			if (!ContainsIgnoreCase(entry.PrefabName, _search) && !ContainsIgnoreCase(entry.EnglishName, _search) && !ContainsIgnoreCase(entry.RussianName, _search))
			{
				return ContainsIgnoreCase(entry.LocalizedName, _search);
			}
			return true;
		}

		private void SetOpen(bool open)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			if (_isOpen == open)
			{
				return;
			}
			_isOpen = open;
			_nameHasFocus = false;
			_searchHasFocus = false;
			if (open)
			{
				_cursorStateStored = true;
				_oldCursorVisible = Cursor.visible;
				_oldCursorLockState = Cursor.lockState;
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _windowRect)).width));
				((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _windowRect)).height));
				RefreshGameReferences();
				if (_zNetSceneInstance != null && !_catalogReady)
				{
					RefreshCatalogue();
				}
			}
			else
			{
				_searchHasFocus = false;
				_confirmKillAll = false;
				_suppressInputUntil = Time.unscaledTime + 0.15f;
				if (_cursorStateStored)
				{
					Cursor.visible = _oldCursorVisible;
					Cursor.lockState = _oldCursorLockState;
					_cursorStateStored = false;
				}
			}
		}

		private void RefreshGameReferences()
		{
			if (_characterType == null)
			{
				_characterType = FindType("Character");
			}
			if (_zNetSceneType == null)
			{
				_zNetSceneType = FindType("ZNetScene");
			}
			if (_zNetType == null)
			{
				_zNetType = FindType("ZNet");
			}
			if (_playerType == null)
			{
				_playerType = FindType("Player");
			}
			if (_zNetViewType == null)
			{
				_zNetViewType = FindType("ZNetView");
			}
			_zNetSceneInstance = GetSingleton(_zNetSceneType, "instance");
			if (_zNetSceneInstance != _lastCatalogScene)
			{
				_lastCatalogScene = _zNetSceneInstance;
				_catalogReady = false;
				_entries.Clear();
				_selected = null;
			}
			_zNetInstance = GetSingleton(_zNetType, "instance");
			object singleton = GetSingleton(_playerType, "m_localPlayer");
			_playerComponent = (Component)((singleton is Component) ? singleton : null);
		}

		private void RefreshCatalogue()
		{
			if (_zNetSceneInstance == null || _characterType == null)
			{
				return;
			}
			try
			{
				List<GameObject> list = ReadPrefabList(_zNetSceneInstance);
				if (list.Count == 0)
				{
					return;
				}
				string value = ((_selected == null) ? null : _selected.PrefabName);
				Dictionary<string, CreatureEntry> dictionary = new Dictionary<string, CreatureEntry>(StringComparer.OrdinalIgnoreCase);
				for (int i = 0; i < list.Count; i++)
				{
					GameObject val = list[i];
					if (!((Object)(object)val == (Object)null))
					{
						Component val2 = null;
						try
						{
							val2 = val.GetComponent(_characterType);
						}
						catch
						{
						}
						CreatureMetadata metadata;
						bool flag = CreatureCatalog.TryGet(((Object)val).name, out metadata);
						if (!((Object)(object)val2 == (Object)null) || flag)
						{
							string text = (((Object)(object)val2 == (Object)null) ? ((Object)val).name : ReadLocalizedCharacterName(val2, ((Object)val).name));
							string englishName = (flag ? metadata.English : ((Object)val).name);
							string russianName = (flag ? metadata.Russian : text);
							CreatureCategory category = (flag ? metadata.Category : InferCategory(((Object)val).name));
							string[] biomes = (flag ? metadata.Biomes : InferBiomes(((Object)val).name));
							CreatureEntry value2 = new CreatureEntry(val, ((Object)val).name, englishName, russianName, text, category, biomes);
							dictionary[((Object)val).name] = value2;
						}
					}
				}
				_entries.Clear();
				_entries.AddRange(dictionary.Values);
				_entries.Sort(delegate(CreatureEntry a, CreatureEntry b)
				{
					int num2 = a.Category.CompareTo(b.Category);
					return (num2 != 0) ? num2 : string.Compare(a.EnglishName, b.EnglishName, StringComparison.CurrentCultureIgnoreCase);
				});
				_selected = null;
				if (!string.IsNullOrEmpty(value))
				{
					for (int num = 0; num < _entries.Count; num++)
					{
						if (_entries[num].PrefabName.Equals(value, StringComparison.OrdinalIgnoreCase))
						{
							_selected = _entries[num];
							break;
						}
					}
				}
				if (_selected == null)
				{
					_selected = ((_entries.Count > 0) ? _entries[0] : null);
				}
				_catalogReady = _entries.Count > 0;
				_status = (_catalogReady ? ("Catalogue loaded: " + _entries.Count + " creatures. Spawning is available to the host/server only.") : "No creatures were found in the game prefabs. Check BepInEx/LogOutput.log.");
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Creature catalogue refreshed: " + _entries.Count + " character prefabs available."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not read the creature catalogue: " + ex));
				_status = "Failed to load the catalogue. See BepInEx/LogOutput.log for details.";
			}
		}

		private static List<GameObject> ReadPrefabList(object sceneInstance)
		{
			List<GameObject> list = new List<GameObject>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			if (sceneInstance == null)
			{
				return list;
			}
			Type type = sceneInstance.GetType();
			while (type != null)
			{
				FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				for (int i = 0; i < fields.Length; i++)
				{
					if (fields[i].Name != "m_prefabs" && fields[i].Name != "m_namedPrefabs")
					{
						continue;
					}
					object value;
					try
					{
						value = fields[i].GetValue(sceneInstance);
					}
					catch
					{
						continue;
					}
					if (!(value is IEnumerable enumerable))
					{
						continue;
					}
					foreach (object item in enumerable)
					{
						GameObject val = (GameObject)((item is GameObject) ? item : null);
						if ((Object)(object)val == (Object)null && item != null)
						{
							PropertyInfo property = item.GetType().GetProperty("Value");
							if (property != null)
							{
								try
								{
									object? value2 = property.GetValue(item, null);
									val = (GameObject)((value2 is GameObject) ? value2 : null);
								}
								catch
								{
								}
							}
						}
						if ((Object)(object)val != (Object)null && hashSet.Add(((Object)val).name))
						{
							list.Add(val);
						}
					}
				}
				type = type.BaseType;
			}
			return list;
		}

		private static Type FindType(string typeName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				try
				{
					Type type = assemblies[i].GetType(typeName, throwOnError: false);
					if (type != null)
					{
						return type;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static object GetSingleton(Type type, string memberName)
		{
			if (type == null)
			{
				return null;
			}
			Type type2 = type;
			while (type2 != null)
			{
				FieldInfo field = type2.GetField(memberName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					try
					{
						return field.GetValue(null);
					}
					catch
					{
					}
				}
				PropertyInfo property = type2.GetProperty(memberName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					try
					{
						return property.GetValue(null, null);
					}
					catch
					{
					}
				}
				type2 = type2.BaseType;
			}
			return null;
		}

		private string ReadLocalizedCharacterName(Component character, string prefabName)
		{
			string text = ReadStringMember(character, "m_name");
			if (string.IsNullOrWhiteSpace(text))
			{
				return prefabName;
			}
			if (!text.StartsWith("$", StringComparison.Ordinal))
			{
				return text;
			}
			Type type = FindType("Localization");
			object singleton = GetSingleton(type, "instance");
			if (singleton != null)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				for (int i = 0; i < methods.Length; i++)
				{
					ParameterInfo[] parameters = methods[i].GetParameters();
					if (!(methods[i].Name == "Localize") || parameters.Length != 1 || !(parameters[0].ParameterType == typeof(string)))
					{
						continue;
					}
					try
					{
						string text2 = methods[i].Invoke(singleton, new object[1] { text }) as string;
						if (!string.IsNullOrWhiteSpace(text2) && text2[0] != '$')
						{
							return text2;
						}
					}
					catch
					{
					}
				}
			}
			return text.Substring(1).Replace('_', ' ');
		}

		private static string ReadStringMember(object instance, string name)
		{
			if (instance == null)
			{
				return null;
			}
			Type type = instance.GetType();
			while (type != null)
			{
				FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					try
					{
						return field.GetValue(instance) as string;
					}
					catch
					{
					}
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					try
					{
						return property.GetValue(instance, null) as string;
					}
					catch
					{
					}
				}
				type = type.BaseType;
			}
			return null;
		}

		private static CreatureCategory InferCategory(string prefabName)
		{
			string text = (prefabName ?? string.Empty).ToLowerInvariant();
			if (text.Contains("eikthyr") || text.Contains("gd_king") || text.Contains("bonemass") || text.Contains("dragon") || text.Contains("goblinking") || text.Contains("seekerqueen") || text.Contains("fader") || text.Contains("frozenking") || text.Contains("kallfimbulbringer"))
			{
				return CreatureCategory.Boss;
			}
			if (text.Contains("brenna") || text.Contains("geirrhafa") || text == "zil" || text == "thungr" || text.Contains("dyrnwyn"))
			{
				return CreatureCategory.Boss;
			}
			return CreatureCategory.Regular;
		}

		private static string[] InferBiomes(string prefabName)
		{
			string text = (prefabName ?? string.Empty).ToLowerInvariant();
			if (!text.Contains("ash") && !text.Contains("charred") && !text.Contains("morgan") && !text.Contains("volture"))
			{
				if (!text.Contains("deepnorth") && !text.Contains("frost") && !text.Contains("jotun") && !text.Contains("moose") && !text.Contains("seal") && !text.Contains("frysling"))
				{
					if (!text.Contains("seeker") && !text.Contains("tick") && !text.Contains("gjall") && !text.Contains("hare") && !text.Contains("dverger") && !text.Contains("dvergr"))
					{
						if (!text.Contains("fuling") && !text.Contains("goblin") && !text.Contains("lox") && !text.Contains("deathsquito") && !text.Contains("tar"))
						{
							if (!text.Contains("draugr") && !text.Contains("blob") && !text.Contains("leech") && !text.Contains("wraith") && !text.Contains("abomination"))
							{
								if (!text.Contains("wolf") && !text.Contains("fenring") && !text.Contains("drake") && !text.Contains("hatchling") && !text.Contains("golem") && !text.Contains("cultist") && !text.Contains("ulv") && !text.Contains("bat"))
								{
									if (!text.Contains("greydwarf") && !text.Contains("troll") && !text.Contains("skeleton") && !text.Contains("ghost") && !text.Contains("brenna"))
									{
										if (!text.Contains("serpent") && !text.Contains("fish") && !text.Contains("gull") && !text.Contains("leviathan"))
										{
											if (!text.Contains("boar") && !text.Contains("deer") && !text.Contains("neck") && !text.Contains("greyling") && !text.Contains("eikthyr"))
											{
												return new string[1] { "Unknown" };
											}
											return new string[1] { "Meadows" };
										}
										return new string[1] { "Ocean" };
									}
									return new string[1] { "Black Forest" };
								}
								return new string[1] { "Mountains" };
							}
							return new string[1] { "Swamp" };
						}
						return new string[1] { "Plains" };
					}
					return new string[1] { "Mistlands" };
				}
				return new string[1] { "Deep North" };
			}
			return new string[1] { "Ashlands" };
		}

		private void SpawnSelected(bool atCrosshair)
		{
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			if (_selected == null || (Object)(object)_selected.Prefab == (Object)null)
			{
				_status = "Select a creature first.";
				return;
			}
			RefreshGameReferences();
			if (_selected == null || (Object)(object)_selected.Prefab == (Object)null)
			{
				if (_zNetSceneInstance != null)
				{
					RefreshCatalogue();
				}
				_status = "The catalogue was refreshed. Select the creature again.";
				return;
			}
			if ((Object)(object)_playerComponent == (Object)null)
			{
				_status = "Player not found. Enter a world before spawning creatures.";
				return;
			}
			if (_zNetSceneInstance == null)
			{
				_status = "The network scene is not ready yet. Try again in a few seconds.";
				return;
			}
			if (!IsServer())
			{
				_status = "Only the host/server can spawn networked creatures. Run this action as the host.";
				return;
			}
			Vector3 position;
			Quaternion val;
			if (atCrosshair)
			{
				if (!TryGetCrosshairPosition(out position))
				{
					_status = "The crosshair is not pointing at a surface. Aim at the ground or an object and try again.";
					return;
				}
				val = Quaternion.identity;
			}
			else
			{
				Transform transform = _playerComponent.transform;
				Vector3 val2 = transform.position + transform.forward * 3f;
				RaycastHit val3 = default(RaycastHit);
				position = ((!Physics.Raycast(new Ray(val2 + Vector3.up * 12f, Vector3.down), ref val3, 40f)) ? (val2 + Vector3.up * 0.5f) : (((RaycastHit)(ref val3)).point + Vector3.up * 0.12f));
				val = Quaternion.Euler(0f, transform.eulerAngles.y, 0f);
			}
			int num = 0;
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			string text = (_customName ?? string.Empty).Trim();
			if (text.Length > 40)
			{
				text = text.Substring(0, 40);
			}
			string prefabName = _selected.PrefabName;
			GameObject prefab = _selected.Prefab;
			int level = _level;
			for (int i = 0; i < _count; i++)
			{
				Vector3 val4 = position + GetSpawnOffset(i);
				try
				{
					GameObject val5 = Object.Instantiate<GameObject>(prefab, val4, val);
					if (!((Object)(object)val5 == (Object)null))
					{
						if (_zNetViewType != null && (Object)(object)val5.GetComponent(_zNetViewType) == (Object)null)
						{
							flag = true;
						}
						if (!ApplyLevel(val5, level))
						{
							flag2 = true;
						}
						if (!string.IsNullOrWhiteSpace(text) && !ApplyCustomName(val5, text))
						{
							flag3 = true;
						}
						num++;
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to spawn " + prefabName + ": " + ex));
				}
			}
			if (num == 0)
			{
				_status = "Failed to spawn the creature. See BepInEx/LogOutput.log for details.";
			}
			else if (flag)
			{
				_status = "Spawned " + prefabName + " × " + num + ". This prefab has no ZNetView, so synchronization with other players is not guaranteed.";
			}
			else if (flag2 && flag3)
			{
				_status = "Spawned " + num + " creature(s). Some do not support custom levels or names.";
			}
			else if (flag3)
			{
				_status = "Spawned " + num + " creature(s), but the custom name could not be applied to every instance of this type.";
			}
			else if (flag2)
			{
				_status = "Spawned: " + _selected.EnglishName + " × " + num + ". Some instances do not support level/star settings.";
			}
			else
			{
				_status = "Spawned: " + (string.IsNullOrWhiteSpace(text) ? _selected.EnglishName : text) + " × " + num + ", level " + level + " (" + (level - 1) + "★).";
			}
		}

		private void KillNearbyCreatures()
		{
			RefreshGameReferences();
			if ((Object)(object)_playerComponent == (Object)null)
			{
				_status = "Player not found. Enter a world before using killall.";
				return;
			}
			if (!IsServer())
			{
				_status = "Only the host/server can kill creatures. Run this action as the host.";
				return;
			}
			if (_characterType == null)
			{
				_characterType = FindType("Character");
			}
			if (_characterType == null)
			{
				_status = "The game Character type was not found. See BepInEx/LogOutput.log for details.";
				return;
			}
			try
			{
				MethodInfo method = _characterType.GetMethod("GetAllCharacters", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method == null)
				{
					_status = "Character.GetAllCharacters() was not found in this game version.";
					return;
				}
				if (!(method.Invoke(null, null) is IEnumerable enumerable))
				{
					_status = "Could not retrieve the creatures from the current game scene.";
					return;
				}
				List<object> list = new List<object>();
				foreach (object item in enumerable)
				{
					if (item != null)
					{
						list.Add(item);
					}
				}
				MethodInfo methodInfo = null;
				MethodInfo[] methods = _characterType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				for (int i = 0; i < methods.Length; i++)
				{
					if (!(methods[i].Name != "Damage"))
					{
						ParameterInfo[] parameters = methods[i].GetParameters();
						if (parameters.Length == 1 && parameters[0].ParameterType.Name == "HitData")
						{
							methodInfo = methods[i];
							break;
						}
					}
				}
				if (methodInfo == null)
				{
					_status = "Character.Damage(HitData) was not found in this game version.";
					return;
				}
				Type parameterType = methodInfo.GetParameters()[0].ParameterType;
				int num = 0;
				int num2 = 0;
				for (int j = 0; j < list.Count; j++)
				{
					object obj = list[j];
					Component val = (Component)((obj is Component) ? obj : null);
					if ((Object)(object)val == (Object)null || !TryReadBooleanMethod(obj, "IsPlayer", out var value) || value)
					{
						continue;
					}
					try
					{
						object obj2 = CreateLethalHitData(parameterType);
						if (obj2 == null)
						{
							_status = "Could not prepare HitData to apply damage.";
							return;
						}
						methodInfo.Invoke(obj, new object[1] { obj2 });
						num++;
					}
					catch (Exception ex)
					{
						num2++;
						((BaseUnityPlugin)this).Logger.LogDebug((object)("killall could not damage " + ((Object)val).name + ": " + ex.Message));
					}
				}
				_status = "killall complete: lethal damage applied to " + num + " creature(s)" + ((num2 > 0) ? ("; errors: " + num2) : string.Empty) + ". Players were not affected; tamed creatures were included.";
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to run Creature Spawner killall: " + ex2));
				_status = "Failed to execute killall. See BepInEx/LogOutput.log for details.";
			}
		}

		private static bool TryReadBooleanMethod(object instance, string methodName, out bool value)
		{
			value = false;
			if (instance == null)
			{
				return false;
			}
			MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			if (method == null || method.ReturnType != typeof(bool))
			{
				return false;
			}
			try
			{
				value = Convert.ToBoolean(method.Invoke(instance, null));
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static object CreateLethalHitData(Type hitDataType)
		{
			if (hitDataType == null)
			{
				return null;
			}
			try
			{
				return Activator.CreateInstance(hitDataType, 1E+10f);
			}
			catch
			{
			}
			object obj2;
			try
			{
				obj2 = Activator.CreateInstance(hitDataType, nonPublic: true);
			}
			catch
			{
				return null;
			}
			if (obj2 == null)
			{
				return null;
			}
			FieldInfo field = hitDataType.GetField("m_damage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return null;
			}
			try
			{
				object value = field.GetValue(obj2);
				if (value == null)
				{
					return null;
				}
				FieldInfo field2 = value.GetType().GetField("m_damage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 == null || field2.FieldType != typeof(float))
				{
					return null;
				}
				field2.SetValue(value, 1E+10f);
				field.SetValue(obj2, value);
				return obj2;
			}
			catch
			{
				return null;
			}
		}

		private bool ApplyCustomName(GameObject spawnedObject, string customName)
		{
			if ((Object)(object)spawnedObject == (Object)null || string.IsNullOrWhiteSpace(customName))
			{
				return false;
			}
			Component val = null;
			try
			{
				if (_characterType != null)
				{
					val = spawnedObject.GetComponent(_characterType);
				}
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			bool flag = false;
			MethodInfo[] methods = ((object)val).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < methods.Length; i++)
			{
				if (methods[i].Name != "SetCustomName")
				{
					continue;
				}
				ParameterInfo[] parameters = methods[i].GetParameters();
				if (parameters.Length == 1 && !(parameters[0].ParameterType != typeof(string)))
				{
					try
					{
						methods[i].Invoke(val, new object[1] { customName });
						flag = true;
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Character.SetCustomName failed: " + ex.Message));
						continue;
					}
					break;
				}
			}
			try
			{
				Component val2 = ((_zNetViewType == null) ? null : spawnedObject.GetComponent(_zNetViewType));
				if ((Object)(object)val2 != (Object)null)
				{
					MethodInfo method = ((object)val2).GetType().GetMethod("GetZDO", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
					object obj2 = ((method == null) ? null : method.Invoke(val2, null));
					if (obj2 != null)
					{
						MethodInfo[] methods2 = obj2.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						for (int j = 0; j < methods2.Length; j++)
						{
							ParameterInfo[] parameters2 = methods2[j].GetParameters();
							if (!(methods2[j].Name != "Set") && parameters2.Length == 2 && !(parameters2[0].ParameterType != typeof(string)) && !(parameters2[1].ParameterType != typeof(string)))
							{
								try
								{
									methods2[j].Invoke(obj2, new object[2] { "customName", customName });
									flag = true;
								}
								catch
								{
								}
								try
								{
									methods2[j].Invoke(obj2, new object[2] { "VCS_CustomName", customName });
									flag = true;
								}
								catch
								{
								}
								if (flag)
								{
									break;
								}
							}
						}
					}
				}
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not store custom name in ZDO: " + ex2.Message));
			}
			flag |= TrySetStringMember(val, "m_customName", customName);
			return flag | TrySetStringMember(val, "m_name", customName);
		}

		private static bool TrySetStringMember(object instance, string memberName, string value)
		{
			if (instance == null)
			{
				return false;
			}
			Type type = instance.GetType();
			while (type != null)
			{
				FieldInfo field = type.GetField(memberName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(string))
				{
					try
					{
						field.SetValue(instance, value);
						return true;
					}
					catch
					{
					}
				}
				PropertyInfo property = type.GetProperty(memberName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(string) && property.CanWrite)
				{
					try
					{
						property.SetValue(instance, value, null);
						return true;
					}
					catch
					{
					}
				}
				type = type.BaseType;
			}
			return false;
		}

		private bool IsServer()
		{
			if (_zNetInstance == null)
			{
				return false;
			}
			MethodInfo method = _zNetInstance.GetType().GetMethod("IsServer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			if (method == null)
			{
				return false;
			}
			try
			{
				return Convert.ToBoolean(method.Invoke(_zNetInstance, null));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not determine server authority: " + ex.Message));
				return false;
			}
		}

		private static Vector3 GetSpawnOffset(int index)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if (index == 0)
			{
				return Vector3.zero;
			}
			float num = (float)index * 2.3999631f;
			float num2 = 1.1f * Mathf.Sqrt((float)index);
			return new Vector3(Mathf.Cos(num) * num2, 0f, Mathf.Sin(num) * num2);
		}

		private bool TryGetCrosshairPosition(out Vector3 position)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return false;
			}
			RaycastHit[] array = Physics.RaycastAll(main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f)), 250f);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			Transform val = (((Object)(object)_playerComponent == (Object)null) ? null : _playerComponent.transform);
			for (int num = 0; num < array.Length; num++)
			{
				if (!((Object)(object)((RaycastHit)(ref array[num])).collider == (Object)null) && (!((Object)(object)val != (Object)null) || (!((Object)(object)((Component)((RaycastHit)(ref array[num])).collider).transform == (Object)(object)val) && !((Component)((RaycastHit)(ref array[num])).collider).transform.IsChildOf(val))))
				{
					position = ((RaycastHit)(ref array[num])).point + ((RaycastHit)(ref array[num])).normal * 0.12f;
					return true;
				}
			}
			return false;
		}

		private bool ApplyLevel(GameObject spawnedObject, int level)
		{
			if ((Object)(object)spawnedObject == (Object)null || _characterType == null)
			{
				return false;
			}
			Component val = null;
			try
			{
				val = spawnedObject.GetComponent(_characterType);
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			MethodInfo[] methods = ((object)val).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < methods.Length; i++)
			{
				ParameterInfo[] parameters = methods[i].GetParameters();
				if (methods[i].Name != "SetLevel" || parameters.Length < 1 || parameters[0].ParameterType != typeof(int))
				{
					continue;
				}
				object[] array = new object[parameters.Length];
				array[0] = level;
				bool flag = true;
				for (int j = 1; j < parameters.Length; j++)
				{
					if (!parameters[j].IsOptional)
					{
						flag = false;
						break;
					}
					array[j] = parameters[j].DefaultValue;
				}
				if (flag)
				{
					try
					{
						methods[i].Invoke(val, array);
						return true;
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not apply creature level: " + ex.Message));
						return false;
					}
				}
			}
			return false;
		}

		private void InstallInputGuards()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Expected O, but got Unknown
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Expected O, but got Unknown
			try
			{
				_harmony = new Harmony("com.supernova.valheimcreaturespawner.InputGuard");
				Type type = FindType("ZInput");
				if (type != null)
				{
					MethodInfo method = typeof(CreatureSpawnerPlugin).GetMethod("BlockBooleanInputPrefix", BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						if (methodInfo.ReturnType != typeof(bool))
						{
							continue;
						}
						string name = methodInfo.Name;
						ParameterInfo[] parameters = methodInfo.GetParameters();
						bool flag = false;
						switch (name)
						{
						case "GetButton":
						case "GetButtonDown":
						case "GetButtonUp":
							flag = parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
							break;
						case "GetMouseButton":
						case "GetMouseButtonDown":
						case "GetMouseButtonUp":
							flag = parameters.Length == 1 && parameters[0].ParameterType == typeof(int);
							break;
						case "GetKey":
						case "GetKeyDown":
						case "GetKeyUp":
							flag = parameters.Length >= 1 && parameters.Length <= 2 && parameters[0].ParameterType == typeof(KeyCode) && (parameters.Length == 1 || parameters[1].ParameterType == typeof(bool));
							break;
						}
						if (flag)
						{
							try
							{
								_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
							}
							catch (Exception ex)
							{
								((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not guard " + methodInfo.Name + ": " + ex.Message));
							}
						}
					}
				}
				MethodInfo method2 = typeof(CreatureSpawnerPlugin).GetMethod("BlockMouseScrollWheelPrefix", BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array = (type ?? FindType("ZInput"))?.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (array != null)
				{
					foreach (MethodInfo methodInfo2 in array)
					{
						if (!(methodInfo2.Name != "GetMouseScrollWheel") && !(methodInfo2.ReturnType != typeof(float)) && methodInfo2.GetParameters().Length == 0)
						{
							try
							{
								_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
								((BaseUnityPlugin)this).Logger.LogInfo((object)"Mouse wheel input guard installed for the open spawner HUD.");
							}
							catch (Exception ex2)
							{
								((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not guard camera zoom scroll input: " + ex2.Message));
							}
						}
					}
				}
				PatchBooleanInputMethod(FindType("Player"), "TakeInput");
				PatchBooleanInputMethod(FindType("PlayerController"), "TakeInput");
				Type type2 = FindType("Character");
				if (type2 != null)
				{
					MethodInfo method3 = type2.GetMethod("GetHoverName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
					if (method3 != null && method3.ReturnType == typeof(string))
					{
						MethodInfo method4 = typeof(CreatureSpawnerPlugin).GetMethod("OverrideCustomNamePostfix", BindingFlags.Static | BindingFlags.NonPublic);
						try
						{
							_harmony.Patch((MethodBase)method3, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						}
						catch (Exception ex3)
						{
							((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not install custom-name display patch: " + ex3.Message));
						}
					}
				}
				Type type3 = FindType("GameCamera");
				if (!(type3 != null))
				{
					return;
				}
				MethodInfo method5 = typeof(CreatureSpawnerPlugin).GetMethod("BlockCameraMouseCapturePrefix", BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] methods2 = type3.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				for (int k = 0; k < methods2.Length; k++)
				{
					if (!(methods2[k].Name != "UpdateMouseCapture") && methods2[k].GetParameters().Length == 0)
					{
						try
						{
							_harmony.Patch((MethodBase)methods2[k], new HarmonyMethod(method5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						}
						catch (Exception ex4)
						{
							((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not guard camera cursor capture: " + ex4.Message));
						}
					}
				}
			}
			catch (Exception ex5)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Some input guards could not be installed. Cursor forcing remains active. " + ex5.Message));
			}
		}

		private void PatchBooleanInputMethod(Type type, string name)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			if (type == null)
			{
				return;
			}
			MethodInfo method = typeof(CreatureSpawnerPlugin).GetMethod("BlockBooleanInputPrefix", BindingFlags.Static | BindingFlags.NonPublic);
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < methods.Length; i++)
			{
				if (!(methods[i].Name != name) && !(methods[i].ReturnType != typeof(bool)))
				{
					try
					{
						_harmony.Patch((MethodBase)methods[i], new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not block " + type.Name + "." + name + ": " + ex.Message));
					}
				}
			}
		}

		private static bool ShouldBlockGameInput()
		{
			if ((Object)(object)_activeInstance != (Object)null)
			{
				if (!_activeInstance._isOpen)
				{
					return Time.unscaledTime < _activeInstance._suppressInputUntil;
				}
				return true;
			}
			return false;
		}

		private static bool BlockBooleanInputPrefix(ref bool __result)
		{
			if (!ShouldBlockGameInput())
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool BlockCameraMouseCapturePrefix()
		{
			return !ShouldBlockGameInput();
		}

		private static bool BlockMouseScrollWheelPrefix(ref float __result)
		{
			if (!ShouldBlockGameInput())
			{
				return true;
			}
			__result = 0f;
			return false;
		}

		private static void OverrideCustomNamePostfix(object __instance, ref string __result)
		{
			CreatureSpawnerPlugin activeInstance = _activeInstance;
			Component val = (Component)((__instance is Component) ? __instance : null);
			if ((Object)(object)activeInstance == (Object)null || (Object)(object)val == (Object)null || activeInstance._zNetViewType == null)
			{
				return;
			}
			try
			{
				Component component = val.GetComponent(activeInstance._zNetViewType);
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				MethodInfo method = ((object)component).GetType().GetMethod("GetZDO", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				object obj = ((method == null) ? null : method.Invoke(component, null));
				if (obj == null)
				{
					return;
				}
				MethodInfo[] methods = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				for (int i = 0; i < methods.Length; i++)
				{
					if (methods[i].Name != "GetString")
					{
						continue;
					}
					ParameterInfo[] parameters = methods[i].GetParameters();
					object obj2 = null;
					try
					{
						if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string))
						{
							obj2 = methods[i].Invoke(obj, new object[1] { "VCS_CustomName" });
						}
						else if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string))
						{
							obj2 = methods[i].Invoke(obj, new object[2]
							{
								"VCS_CustomName",
								string.Empty
							});
						}
					}
					catch
					{
					}
					string text = obj2 as string;
					if (!string.IsNullOrWhiteSpace(text))
					{
						__result = text;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				if ((Object)(object)activeInstance != (Object)null)
				{
					((BaseUnityPlugin)activeInstance).Logger.LogDebug((object)("Could not read custom creature name: " + ex.Message));
				}
			}
		}

		private void OnDestroy()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (_harmony != null)
			{
				try
				{
					_harmony.UnpatchSelf();
				}
				catch
				{
				}
				_harmony = null;
			}
			if (_activeInstance == this)
			{
				_activeInstance = null;
			}
			if (_cursorStateStored)
			{
				Cursor.visible = _oldCursorVisible;
				Cursor.lockState = _oldCursorLockState;
				_cursorStateStored = false;
			}
		}
	}
}