Decompiled source of ValheimNexus v1.2.0

BepInEx\plugins\ValheimSpawner\ValheimSpawner.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
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("ValheimSpawner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ValheimSpawner")]
[assembly: AssemblyTitle("ValheimSpawner")]
[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.ValheimSpawner
{
	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.valheimspawner", "SuperNova Valheim Nexus", "1.2.0")]
	public sealed class ValheimSpawnerPlugin : BaseUnityPlugin
	{
		private enum ItemCategory
		{
			Weapons,
			Armor,
			Food,
			Materials,
			Other
		}

		private sealed class ItemEntry
		{
			public readonly GameObject Prefab;

			public readonly string PrefabName;

			public readonly string DisplayName;

			public readonly string EnglishName;

			public readonly string LocalizedName;

			public readonly string ItemTypeLabel;

			public readonly ItemCategory Category;

			public readonly int MaxQuality;

			public ItemEntry(GameObject prefab, string prefabName, string englishName, string localizedName, string itemTypeLabel, ItemCategory category, int maxQuality)
			{
				Prefab = prefab;
				PrefabName = prefabName ?? string.Empty;
				EnglishName = (string.IsNullOrWhiteSpace(englishName) ? HumanizePrefabName(PrefabName) : englishName);
				LocalizedName = (string.IsNullOrWhiteSpace(localizedName) ? EnglishName : localizedName);
				DisplayName = EnglishName;
				ItemTypeLabel = itemTypeLabel ?? string.Empty;
				Category = category;
				MaxQuality = Mathf.Clamp(maxQuality, 1, 10);
			}
		}

		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.valheimspawner";

		public const string PluginName = "SuperNova Valheim Nexus";

		public const string PluginVersion = "1.2.0";

		private const int ExtendedNonWeaponQualityCap = 10;

		private ConfigEntry<KeyCode> _toggleKey;

		private ConfigEntry<KeyCode> _spawnFrontKey;

		private ConfigEntry<KeyCode> _spawnAimKey;

		private ConfigEntry<int> _defaultCount;

		private ConfigEntry<int> _defaultLevel;

		private ConfigEntry<string> _languageSetting;

		private Harmony _harmony;

		private static ValheimSpawnerPlugin _activeInstance;

		private float _suppressInputUntil;

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

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

		private readonly List<ItemEntry> _itemEntries = new List<ItemEntry>();

		private readonly List<ItemEntry> _filteredItems = new List<ItemEntry>();

		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 static readonly Dictionary<string, string> RussianItemNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "AxeStone", "Каменный топор" },
			{ "AxeFlint", "Кремнёвый топор" },
			{ "AxeBronze", "Бронзовый топор" },
			{ "AxeIron", "Железный топор" },
			{ "AxeBlackMetal", "Чернометаллический топор" },
			{ "AxeJotunBane", "Топор йотунов" },
			{ "AxeBer", "Бер" },
			{ "AtgeirBronze", "Бронзовая алебарда" },
			{ "AtgeirIron", "Железная алебарда" },
			{ "AtgeirBlackmetal", "Чернометаллическая алебарда" },
			{ "AtgeirHimminAfl", "Химмин-Афль" },
			{ "Battleaxe", "Боевой топор" },
			{ "BattleaxeCrystal", "Кристальный боевой топор" },
			{ "BattleaxeBloodthirst", "Жажда крови" },
			{ "Bow", "Лук" },
			{ "BowFineWood", "Лук из ценной древесины" },
			{ "BowHuntsman", "Лук охотника" },
			{ "BowDraugrFang", "Клык драугра" },
			{ "BowSpineSnap", "Хребтолом" },
			{ "CrossbowArbalest", "Арбалет" },
			{ "KnifeFlint", "Кремнёвый нож" },
			{ "KnifeCopper", "Медный нож" },
			{ "KnifeSilver", "Серебряный нож" },
			{ "KnifeBlackMetal", "Чернометаллический нож" },
			{ "KnifeSkollAndHati", "Сколль и Хати" },
			{ "KnifeButcher", "Нож мясника" },
			{ "MaceBronze", "Бронзовая булава" },
			{ "MaceIron", "Железная булава" },
			{ "MaceSilver", "Серебряная булава" },
			{ "MaceNeedle", "Игла" },
			{ "MacePorcupine", "Дикобраз" },
			{ "MaceDemolisher", "Разрушитель" },
			{ "SledgeStagbreaker", "Оленебой" },
			{ "SledgeIron", "Железная кувалда" },
			{ "SpearFlint", "Кремнёвое копьё" },
			{ "SpearBronze", "Бронзовое копьё" },
			{ "SpearElderbark", "Древеснокорое копьё" },
			{ "SpearWolfFang", "Копьё с волчьим клыком" },
			{ "SpearCarapace", "Карапасное копьё" },
			{ "SpearChitin", "Гарпун бездны" },
			{ "SwordBronze", "Бронзовый меч" },
			{ "SwordIron", "Железный меч" },
			{ "SwordSilver", "Серебряный меч" },
			{ "SwordBlackmetal", "Чернометаллический меч" },
			{ "SwordMistwalker", "Туманоход" },
			{ "SwordNiedhogg", "Нидхёгг" },
			{ "SwordKrom", "Кром" },
			{ "SwordDyrnwyn", "Дюрнвин" },
			{ "StaffFireball", "Посох огненного шара" },
			{ "StaffIceShards", "Посох ледяных осколков" },
			{ "StaffShield", "Посох защиты" },
			{ "StaffSkeleton", "Посох скелетов" },
			{ "StaffGreenRoots", "Посох зелёных корней" },
			{ "StaffLightning", "Посох молнии" },
			{ "Torch", "Факел" },
			{ "ArrowWood", "Деревянная стрела" },
			{ "ArrowFire", "Огненная стрела" },
			{ "ArrowFlint", "Кремнёвая стрела" },
			{ "ArrowBronze", "Бронзовая стрела" },
			{ "ArrowIron", "Железная стрела" },
			{ "ArrowSilver", "Серебряная стрела" },
			{ "ArrowObsidian", "Обсидиановая стрела" },
			{ "ArrowNeedle", "Игла" },
			{ "ArrowCarapace", "Карапасная стрела" },
			{ "ArrowCharred", "Обугленная стрела" },
			{ "ArrowFrost", "Морозная стрела" },
			{ "ArrowPoison", "Отравленная стрела" },
			{ "BoltWood", "Деревянный болт" },
			{ "BoltBone", "Костяной болт" },
			{ "BoltIron", "Железный болт" },
			{ "BoltBlackmetal", "Чернометаллический болт" },
			{ "BoltCarapace", "Карапасный болт" },
			{ "BoltCharred", "Обугленный болт" },
			{ "ShieldWood", "Деревянный щит" },
			{ "ShieldWoodTower", "Деревянный башенный щит" },
			{ "ShieldBoneTower", "Костяной башенный щит" },
			{ "ShieldBronzeBuckler", "Бронзовый круглый щит" },
			{ "ShieldIronSquare", "Железный щит" },
			{ "ShieldBanded", "Полосатый щит" },
			{ "ShieldSerpentscale", "Щит из чешуи змея" },
			{ "ShieldBlackmetal", "Чернометаллический щит" },
			{ "ShieldBlackmetalTower", "Чернометаллический башенный щит" },
			{ "ShieldCarapace", "Карапасный щит" },
			{ "ShieldCarapaceBuckler", "Карапасный круглый щит" },
			{ "ShieldFlametal", "Пламеннометаллический щит" }
		};

		private Rect _windowRect = new Rect(30f, 35f, 980f, 740f);

		private Vector2 _listScroll;

		private Vector2 _itemListScroll;

		private int _mainTab;

		private int _itemCount = 1;

		private string _itemCountInput = "1";

		private int _itemQuality = 1;

		private bool _spawnTamed;

		private bool _infiniteHealth;

		private bool _infiniteStamina;

		private bool _infiniteEitr;

		private bool _adminFly;

		private bool _adminCreative;

		private bool _adminHotkeys;

		private float _nextAdminRefresh;

		private float _skillXpMultiplier = 1f;

		private string _skillXpInput = "1";

		private string _adminToast = string.Empty;

		private float _adminToastUntil;

		private string _itemSearch = string.Empty;

		private readonly Dictionary<ItemCategory, string> _itemTypeFilters = new Dictionary<ItemCategory, string>();

		private bool _isRussian;

		private bool _itemCatalogReady;

		private object _objectDbInstance;

		private object _lastObjectDb;

		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 catalogue.";

		private int _categoryFilter;

		private int _biomeFilter;

		private int _count = 1;

		private int _level = 1;

		private CreatureEntry _selected;

		private ItemEntry _selectedItem;

		private Type _objectDbType;

		private Type _itemDropType;

		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_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: 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 ValheimSpawner 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", "DefaultCreatureCount", 1, "Starting creature count; initialized to 1 each launch.");
			_defaultLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Spawner", "DefaultCreatureLevel", 1, "Creature level: 1 = no stars, 2 = one star, 3 = two stars.");
			_languageSetting = ((BaseUnityPlugin)this).Config.Bind<string>("General", "DisplayLanguage", "English", "HUD starts in English each launch; use the HUD language button to switch for the current session.");
			_languageSetting.Value = "English";
			_isRussian = false;
			_defaultCount.Value = 1;
			_count = 1;
			_level = Mathf.Clamp(_defaultLevel.Value, 1, 3);
			_itemCount = 1;
			_itemCountInput = "1";
			_itemQuality = 1;
			_characterType = FindType("Character");
			_zNetSceneType = FindType("ZNetScene");
			_objectDbType = FindType("ObjectDB");
			_itemDropType = FindType("ItemDrop");
			_zNetType = FindType("ZNet");
			_playerType = FindType("Player");
			_zNetViewType = FindType("ZNetView");
			_activeInstance = this;
			InstallInputGuards();
			InstallAdminPatches();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ValheimSpawner loaded. Press " + ((object)_toggleKey.Value/*cast due to .constrained prefix*/).ToString() + " to open HUD."));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Creature and item prefabs are discovered from the active game database at runtime.");
		}

		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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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 (_adminHotkeys && !_isOpen && (Object)(object)_playerComponent != (Object)null)
			{
				if (Input.GetKeyDown((KeyCode)122))
				{
					SetAdminFly(!_adminFly);
				}
				if (Input.GetKeyDown((KeyCode)98))
				{
					SetAdminCreative(!_adminCreative);
				}
			}
			if ((Object)(object)_playerComponent != (Object)null && Time.unscaledTime >= _nextAdminRefresh)
			{
				_nextAdminRefresh = Time.unscaledTime + 0.1f;
				ApplyAdminVitals();
			}
			if (_isOpen)
			{
				if (Input.GetKeyDown((KeyCode)27))
				{
					SetOpen(open: false);
					return;
				}
				if (_mainTab == 0 && !_searchHasFocus && !_nameHasFocus && (int)_spawnFrontKey.Value != 0 && Input.GetKeyDown(_spawnFrontKey.Value))
				{
					SpawnSelected(atCrosshair: false);
				}
				if (_mainTab == 0 && !_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();
				}
				if (!_itemCatalogReady && _objectDbInstance != null)
				{
					RefreshItemCatalogue();
				}
			}
		}

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

		private void OnGUI()
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			if (!_isOpen)
			{
				DrawAdminToast();
				return;
			}
			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), "SUPERNOVA VALHEIM NEXUS");
			DrawAdminToast();
		}

		private void DrawAdminToast()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(_adminToast) && !(Time.unscaledTime >= _adminToastUntil))
			{
				GUI.Box(new Rect(Mathf.Max(10f, ((float)Screen.width - 380f) * 0.5f), 55f, 380f, 38f), _adminToast);
			}
		}

		private void DrawWindow(int windowId)
		{
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawMainTabButton(T("Creatures", "Существа"), 0);
			DrawMainTabButton(T("Weapons", "Оружие"), 1);
			DrawMainTabButton(T("Armor", "Броня"), 2);
			DrawMainTabButton(T("Food", "Еда"), 3);
			DrawMainTabButton(T("Materials", "Материалы"), 4);
			DrawMainTabButton(T("Other items", "Прочее"), 5);
			DrawMainTabButton(T("Admin Corner", "Админ-уголок"), 6);
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(T("Valheim Wiki ↗", "Вики Valheim ↗"), (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(120f),
				GUILayout.Height(28f)
			}))
			{
				try
				{
					Application.OpenURL("https://valheim.fandom.com/wiki/Valheim_Wiki");
					_status = T("Opening Valheim Wiki in your browser.", "Открываю Valheim Wiki в браузере.");
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not open Valheim Wiki: " + ex.Message));
					_status = T("Could not open the wiki link. Open it manually: valheim.fandom.com/wiki/Valheim_Wiki", "Не удалось открыть ссылку. Открой вручную: valheim.fandom.com/wiki/Valheim_Wiki");
				}
			}
			if (GUILayout.Button(_isRussian ? "Язык: RU" : "Language: EN", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(105f),
				GUILayout.Height(28f)
			}))
			{
				_isRussian = !_isRussian;
				_languageSetting.Value = (_isRussian ? "Russian" : "English");
				_status = T("Language changed to English.", "Язык изменён на русский.");
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			if (_mainTab == 0)
			{
				DrawCreaturePanel();
			}
			else if (_mainTab == 6)
			{
				DrawAdminPanel();
			}
			else
			{
				DrawItemPanel(GetItemCategoryForTab(_mainTab));
			}
			GUILayout.EndVertical();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 24f));
		}

		private void DrawMainTabButton(string title, int tab)
		{
			if (GUILayout.Button((_mainTab == tab) ? ("[ " + title + " ]") : title, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(30f)
			}))
			{
				if (_mainTab != tab && tab > 0 && _mainTab > 0)
				{
					ResetItemAmountAfterSuccessfulAdd();
				}
				_mainTab = tab;
				if (_mainTab > 0 && _mainTab < 6 && _selectedItem != null && _selectedItem.Category != GetItemCategoryForTab(_mainTab))
				{
					_selectedItem = null;
				}
				_searchHasFocus = false;
				_nameHasFocus = false;
				GUI.FocusControl(string.Empty);
				if (_mainTab > 0 && _mainTab < 6 && !_itemCatalogReady && _objectDbInstance != null)
				{
					RefreshItemCatalogue();
				}
			}
		}

		private void DrawCreaturePanel()
		{
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_070a: Unknown result type (might be due to invalid IL or missing references)
			//IL_070f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0763: Unknown result type (might be due to invalid IL or missing references)
			//IL_0768: Unknown result type (might be due to invalid IL or missing references)
			//IL_07be: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0825: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label(T("Search by English name, Russian name, localized name or prefab ID.", "Поиск по английскому и русскому названию, локализованному имени или prefab ID."), Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(T("Search:", "Поиск:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(62f) });
			GUI.SetNextControlName("ValheimSpawner.CreatureSearch");
			_search = GUILayout.TextField(_search, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.MinWidth(220f),
				GUILayout.ExpandWidth(true)
			});
			_searchHasFocus = GUI.GetNameOfFocusedControl() == "ValheimSpawner.CreatureSearch";
			if (GUILayout.Button(T("Clear", "Очистить"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
			{
				_search = string.Empty;
				GUI.FocusControl("ValheimSpawner.CreatureSearch");
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawCategoryButton(T("All", "Все"), 0);
			DrawCategoryButton(T("Regular", "Обычные"), 1);
			DrawCategoryButton(T("Bosses", "Боссы"), 2);
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(T("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(T(_biomeOptions[_biomeFilter], TranslateBiome(_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(T("Found: ", "Найдено: ") + BuildFilteredList(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.EndHorizontal();
			_spawnTamed = GUILayout.Toggle(_spawnTamed, T("Spawn tamed (where supported)", "Призывать приручёнными (если поддерживается)"), Array.Empty<GUILayoutOption>());
			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(GetCreatureDisplayName(creatureEntry) + "  ·  " + creatureEntry.PrefabName, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.MinWidth(280f),
						GUILayout.ExpandWidth(true)
					}))
					{
						_selected = creatureEntry;
					}
					GUILayout.Label((creatureEntry.Category == CreatureCategory.Boss) ? T("Boss", "Босс") : T("Regular", "Обычное"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
					GUILayout.Label(T(creatureEntry.BiomeLabel, TranslateBiomeList(creatureEntry.Biomes)), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
					GUILayout.EndHorizontal();
					if (_selected == creatureEntry)
					{
						GUILayout.Label(T("Prefab: ", "Prefab ID: ") + creatureEntry.PrefabName, Array.Empty<GUILayoutOption>());
					}
				}
			}
			GUILayout.EndScrollView();
			GUILayout.Space(5f);
			GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
			if (_selected == null)
			{
				GUILayout.Label(T("Select a creature from the list above.", "Выбери существо из списка выше."), Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label(T("Selected: ", "Выбрано: ") + GetCreatureDisplayName(_selected), Array.Empty<GUILayoutOption>());
				GUILayout.Label("Prefab ID: " + _selected.PrefabName, Array.Empty<GUILayoutOption>());
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(T("Custom name (optional):", "Своё имя (необязательно):"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(205f) });
			GUI.SetNextControlName("ValheimSpawner.CustomName");
			_customName = GUILayout.TextField(_customName, 48, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.MinWidth(220f),
				GUILayout.ExpandWidth(true)
			});
			_nameHasFocus = GUI.GetNameOfFocusedControl() == "ValheimSpawner.CustomName";
			if (GUILayout.Button(T("Clear", "Очистить"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
			{
				_customName = string.Empty;
				GUI.FocusControl("ValheimSpawner.CustomName");
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(T("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(T("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(T("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(T("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(T("Kill all nearby creatures  [killall]", "Убить всех существ поблизости  [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(T("Kill nearby creatures, including tamed ones? Players are not affected.", "Убить существ поблизости, включая приручённых? Игроки не затрагиваются."), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				if (GUILayout.Button(T("Confirm", "Подтвердить"), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(100f),
					GUILayout.Height(30f)
				}))
				{
					_confirmKillAll = false;
					KillNearbyCreatures();
				}
				if (GUILayout.Button(T("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(T("F6: close HUD  ·  F7: spawn in front  ·  F8: spawn at crosshair. Player controls are disabled while the HUD is open.", "F6: закрыть HUD  ·  F7: создать перед собой  ·  F8: создать под прицелом. Управление персонажем отключено, пока открыт HUD."), Array.Empty<GUILayoutOption>());
		}

		private void DrawItemPanel(ItemCategory category)
		{
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label(T("The list is read from the active ObjectDB. Items are added directly to your inventory.", "Список загружается из ObjectDB активной игры. Предметы добавляются прямо в инвентарь."), Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(T("Search:", "Поиск:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(62f) });
			GUI.SetNextControlName("ValheimSpawner.ItemSearch");
			_itemSearch = GUILayout.TextField(_itemSearch, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.MinWidth(220f),
				GUILayout.ExpandWidth(true)
			});
			_searchHasFocus = GUI.GetNameOfFocusedControl() == "ValheimSpawner.ItemSearch";
			if (GUILayout.Button(T("Clear", "Очистить"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
			{
				_itemSearch = string.Empty;
				GUI.FocusControl("ValheimSpawner.ItemSearch");
			}
			GUILayout.EndHorizontal();
			DrawItemTypeFilters(category);
			if (_selectedItem != null && (_selectedItem.Category != category || !MatchesItemFilters(_selectedItem, category)))
			{
				_selectedItem = null;
			}
			GUILayout.Label(T("Found: ", "Найдено: ") + CountFilteredItems(category), Array.Empty<GUILayoutOption>());
			_itemListScroll = GUILayout.BeginScrollView(_itemListScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			_filteredItems.Clear();
			for (int i = 0; i < _itemEntries.Count; i++)
			{
				ItemEntry itemEntry = _itemEntries[i];
				if (itemEntry.Category == category && MatchesItemFilters(itemEntry, category))
				{
					_filteredItems.Add(itemEntry);
					GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
					if (GUILayout.Button(GetItemDisplayName(itemEntry) + "  ·  " + GetVisiblePrefabId(itemEntry.PrefabName), (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.MinWidth(300f),
						GUILayout.ExpandWidth(true)
					}))
					{
						_selectedItem = itemEntry;
					}
					GUILayout.Label(GetItemTypeDisplay(itemEntry.ItemTypeLabel), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(135f) });
					GUILayout.EndHorizontal();
					if (_selectedItem == itemEntry)
					{
						GUILayout.Label(T("Prefab ID: ", "Prefab ID: ") + itemEntry.PrefabName, Array.Empty<GUILayoutOption>());
					}
				}
			}
			GUILayout.EndScrollView();
			GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
			if (_selectedItem == null || _selectedItem.Category != category)
			{
				GUILayout.Label(T("Select an item from the list above.", "Выбери предмет из списка выше."), Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label(T("Selected: ", "Выбрано: ") + GetItemDisplayName(_selectedItem), Array.Empty<GUILayoutOption>());
				GUILayout.Label("Prefab ID: " + GetVisiblePrefabId(_selectedItem.PrefabName), Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(T("Amount:", "Количество:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
				if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
				{
					_itemCount = Mathf.Max(1, _itemCount - 1);
					_itemCountInput = _itemCount.ToString();
				}
				GUI.SetNextControlName("ValheimSpawner.ItemCount");
				string text = GUILayout.TextField(_itemCountInput, 6, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(78f) });
				if (text != _itemCountInput)
				{
					_itemCountInput = text;
					if (int.TryParse(_itemCountInput, out var result))
					{
						_itemCount = Mathf.Clamp(result, 1, 9999);
					}
				}
				if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
				{
					_itemCount = Mathf.Min(9999, _itemCount + 1);
					_itemCountInput = _itemCount.ToString();
				}
				if (GUI.GetNameOfFocusedControl() != "ValheimSpawner.ItemCount")
				{
					_itemCountInput = _itemCount.ToString();
				}
				GUILayout.Space(20f);
				_itemQuality = Mathf.Clamp(_itemQuality, 1, Mathf.Max(1, _selectedItem.MaxQuality));
				GUILayout.Label(T("Quality:", "Качество:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
				if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
				{
					_itemQuality = Mathf.Max(1, _itemQuality - 1);
				}
				GUILayout.Label(_itemQuality.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) });
				if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
				{
					_itemQuality = Mathf.Min(Mathf.Max(1, _selectedItem.MaxQuality), _itemQuality + 1);
				}
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUI.enabled = (Object)(object)_playerComponent != (Object)null;
				if (GUILayout.Button(T("Add to inventory", "Добавить в инвентарь"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(36f) }))
				{
					AddSelectedItemToInventory();
				}
				GUI.enabled = true;
				GUILayout.EndHorizontal();
			}
			GUILayout.EndVertical();
			GUILayout.Label(_status, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.Label(T("Selected items are added directly to your inventory. Use the Creatures tab to spawn creatures into the world.", "Выбранные предметы добавляются прямо в инвентарь. Для создания существ в мире используй вкладку «Существа»."), Array.Empty<GUILayoutOption>());
		}

		private ItemCategory GetItemCategoryForTab(int tab)
		{
			return tab switch
			{
				1 => ItemCategory.Weapons, 
				2 => ItemCategory.Armor, 
				3 => ItemCategory.Food, 
				4 => ItemCategory.Materials, 
				_ => ItemCategory.Other, 
			};
		}

		private void DrawItemTypeFilters(ItemCategory category)
		{
			if (!_itemTypeFilters.TryGetValue(category, out var value))
			{
				value = string.Empty;
			}
			List<string> list = new List<string>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			for (int i = 0; i < _itemEntries.Count; i++)
			{
				ItemEntry itemEntry = _itemEntries[i];
				if (itemEntry.Category == category && !string.IsNullOrWhiteSpace(itemEntry.ItemTypeLabel) && hashSet.Add(itemEntry.ItemTypeLabel))
				{
					list.Add(itemEntry.ItemTypeLabel);
				}
			}
			list.Sort(StringComparer.CurrentCultureIgnoreCase);
			GUILayout.Label(T("Filter by type:", "Фильтр по типу:"), Array.Empty<GUILayoutOption>());
			int num = Mathf.Clamp(Mathf.FloorToInt((((Rect)(ref _windowRect)).width - 45f) / 145f), 3, 6);
			int num2 = 0;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawItemTypeFilterButton(T("All types", "Все типы"), string.Empty, category, value);
			num2++;
			for (int j = 0; j < list.Count; j++)
			{
				if (num2 >= num)
				{
					GUILayout.EndHorizontal();
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					num2 = 0;
				}
				DrawItemTypeFilterButton(GetItemTypeDisplay(list[j]), list[j], category, value);
				num2++;
			}
			GUILayout.EndHorizontal();
		}

		private void DrawItemTypeFilterButton(string label, string value, ItemCategory category, string selectedType)
		{
			if (GUILayout.Button(string.Equals(value ?? string.Empty, selectedType ?? string.Empty, StringComparison.OrdinalIgnoreCase) ? ("[ " + label + " ]") : label, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(27f)
			}))
			{
				_itemTypeFilters[category] = value ?? string.Empty;
			}
		}

		private string T(string english, string russian)
		{
			if (!_isRussian)
			{
				return english;
			}
			return russian;
		}

		private string GetCreatureDisplayName(CreatureEntry entry)
		{
			if (entry == null)
			{
				return string.Empty;
			}
			if (_isRussian && !string.IsNullOrWhiteSpace(entry.RussianName))
			{
				return entry.RussianName;
			}
			if (!string.IsNullOrWhiteSpace(entry.EnglishName))
			{
				return GetEnglishSafeName(entry.EnglishName, entry.PrefabName);
			}
			return HumanizePrefabName(entry.PrefabName);
		}

		private static string TranslateBiome(string biome)
		{
			return biome switch
			{
				"All Biomes" => "Все биомы", 
				"Meadows" => "Луга", 
				"Black Forest" => "Чёрный лес", 
				"Swamp" => "Болото", 
				"Mountains" => "Горы", 
				"Plains" => "Равнины", 
				"Ocean" => "Океан", 
				"Rivers" => "Реки", 
				"Mistlands" => "Туманные земли", 
				"Ashlands" => "Пепельные земли", 
				"Deep North" => "Дальний Север", 
				"Mountain Caves" => "Горные пещеры", 
				"Any Biome" => "Любой биом", 
				_ => "Неизвестно", 
			};
		}

		private string TranslateBiomeList(string[] biomes)
		{
			if (biomes == null || biomes.Length == 0)
			{
				return T("Unknown", "Неизвестно");
			}
			string[] array = new string[biomes.Length];
			for (int i = 0; i < biomes.Length; i++)
			{
				array[i] = TranslateBiome(biomes[i]);
			}
			return string.Join(", ", array);
		}

		private string GetVisiblePrefabId(string prefabName)
		{
			if (!_isRussian && ContainsCyrillic(prefabName))
			{
				return HumanizePrefabName(prefabName);
			}
			return prefabName ?? string.Empty;
		}

		private string GetItemDisplayName(ItemEntry entry)
		{
			if (entry == null)
			{
				return string.Empty;
			}
			if (!_isRussian)
			{
				return entry.EnglishName;
			}
			if (RussianItemNames.TryGetValue(entry.PrefabName, out var value))
			{
				return value;
			}
			if (!string.IsNullOrWhiteSpace(entry.LocalizedName) && ContainsCyrillic(entry.LocalizedName))
			{
				return entry.LocalizedName;
			}
			return entry.EnglishName;
		}

		private static string GetEnglishSafeName(string localizedName, string prefabName)
		{
			string text = (localizedName ?? string.Empty).Trim();
			bool flag = !string.IsNullOrWhiteSpace(text) && string.Equals(text, prefabName ?? string.Empty, StringComparison.OrdinalIgnoreCase);
			if (!string.IsNullOrWhiteSpace(text) && text[0] != '$' && !ContainsCyrillic(text) && !flag)
			{
				return text;
			}
			return HumanizePrefabName(prefabName);
		}

		private static bool ContainsCyrillic(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			foreach (char c in value)
			{
				if ((c >= 'Ѐ' && c <= 'ԯ') || (c >= '\u2de0' && c <= '\u2dff') || (c >= 'Ꙁ' && c <= '\ua69f'))
				{
					return true;
				}
			}
			return false;
		}

		private static string HumanizePrefabName(string prefabName)
		{
			if (string.IsNullOrWhiteSpace(prefabName))
			{
				return "Unknown Item";
			}
			StringBuilder stringBuilder = new StringBuilder(prefabName.Length + 12);
			for (int i = 0; i < prefabName.Length; i++)
			{
				char c = prefabName[i];
				if (c == '_' || c == '-' || char.IsWhiteSpace(c))
				{
					if (stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != ' ')
					{
						stringBuilder.Append(' ');
					}
					continue;
				}
				if ((c >= 'Ѐ' && c <= 'ԯ') || (c >= '\u2de0' && c <= '\u2dff') || (c >= 'Ꙁ' && c <= '\ua69f'))
				{
					if (stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != ' ')
					{
						stringBuilder.Append(' ');
					}
					continue;
				}
				bool flag = i > 0 && char.IsLetterOrDigit(prefabName[i - 1]);
				bool flag2 = i > 0 && (char.IsLower(prefabName[i - 1]) || char.IsDigit(prefabName[i - 1]));
				bool flag3 = char.IsUpper(c);
				bool flag4 = i > 0 && i + 1 < prefabName.Length && char.IsUpper(prefabName[i - 1]) && flag3 && char.IsLower(prefabName[i + 1]);
				if (stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != ' ' && flag && ((flag2 && flag3) || flag4))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			string text = stringBuilder.ToString().Trim();
			while (text.Contains("  "))
			{
				text = text.Replace("  ", " ");
			}
			if (text.Length == 0)
			{
				return "Unknown Item";
			}
			string[] array = text.Split(' ');
			for (int j = 0; j < array.Length; j++)
			{
				if (array[j].Length > 0)
				{
					array[j] = char.ToUpperInvariant(array[j][0]) + array[j].Substring(1);
				}
			}
			return string.Join(" ", array);
		}

		private string GetItemTypeDisplay(string itemType)
		{
			switch ((itemType ?? string.Empty).Trim())
			{
			case "Ammo":
				return T("Ammo", "Боеприпасы");
			case "AmmoNonEquipable":
				return T("Ammunition", "Боеприпасы");
			case "Bow":
				return T("Bow", "Лук");
			case "OneHandedWeapon":
				return T("One-handed weapon", "Одноручное оружие");
			case "TwoHandedWeapon":
				return T("Two-handed weapon", "Двуручное оружие");
			case "TwoHandedWeaponLeft":
				return T("Two-handed weapon (left hand)", "Двуручное оружие (левая рука)");
			case "Torch":
				return T("Torch", "Факел");
			case "Attach_Atgeir":
				return T("Atgeir", "Алебарда");
			case "Weapon":
				return T("Weapon", "Оружие");
			case "Helmet":
				return T("Helmet", "Шлем");
			case "Chest":
				return T("Chest armor", "Нагрудник");
			case "Legs":
				return T("Leg armor", "Штаны");
			case "Hands":
				return T("Gloves", "Перчатки");
			case "Shoulder":
				return T("Cape", "Плащ");
			case "Utility":
				return T("Accessory", "Аксессуар");
			case "Trinkets":
			case "Trinket":
				return T("Trinkets", "Обереги");
			case "Shield":
				return T("Shield", "Щит");
			case "Tool":
				return T("Tool", "Инструмент");
			case "Consumable":
				return T("Consumable", "Расходуемое");
			case "Fish":
				return T("Fish", "Рыба");
			case "Misc":
				return T("Miscellaneous", "Разное");
			case "None":
				return T("Unspecified", "Не указано");
			case "Customization":
				return T("Customization", "Внешний вид");
			case "Material":
				return T("Material", "Материал");
			case "Trophy":
			case "Trophie":
				return T("Trophy", "Трофей");
			default:
				if (!string.IsNullOrEmpty(itemType))
				{
					if (_isRussian || !ContainsCyrillic(itemType))
					{
						return itemType;
					}
					return HumanizePrefabName(itemType);
				}
				return T("Other", "Прочее");
			}
		}

		private int CountFilteredItems(ItemCategory category)
		{
			int num = 0;
			for (int i = 0; i < _itemEntries.Count; i++)
			{
				if (_itemEntries[i].Category == category && MatchesItemFilters(_itemEntries[i], category))
				{
					num++;
				}
			}
			return num;
		}

		private bool MatchesItemFilters(ItemEntry entry, ItemCategory category)
		{
			if (!MatchesItemSearch(entry))
			{
				return false;
			}
			if (!_itemTypeFilters.TryGetValue(category, out var value) || string.IsNullOrEmpty(value))
			{
				return true;
			}
			return string.Equals(entry.ItemTypeLabel, value, StringComparison.OrdinalIgnoreCase);
		}

		private bool MatchesItemSearch(ItemEntry entry)
		{
			if (entry == null)
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(_itemSearch))
			{
				return true;
			}
			string needle = _itemSearch.Trim();
			if (!ContainsIgnoreCase(entry.PrefabName, needle) && !ContainsIgnoreCase(entry.EnglishName, needle) && !ContainsIgnoreCase(entry.LocalizedName, needle))
			{
				return ContainsIgnoreCase(entry.ItemTypeLabel, needle);
			}
			return true;
		}

		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_012c: 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();
				}
				if (_objectDbInstance != null && !_itemCatalogReady)
				{
					RefreshItemCatalogue();
				}
			}
			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");
			}
			if (_objectDbType == null)
			{
				_objectDbType = FindType("ObjectDB");
			}
			if (_itemDropType == null)
			{
				_itemDropType = FindType("ItemDrop");
			}
			_zNetSceneInstance = GetSingleton(_zNetSceneType, "instance");
			if (_zNetSceneInstance != _lastCatalogScene)
			{
				_lastCatalogScene = _zNetSceneInstance;
				_catalogReady = false;
				_entries.Clear();
				_selected = null;
			}
			_objectDbInstance = GetSingleton(_objectDbType, "instance");
			if (_objectDbInstance != _lastObjectDb)
			{
				_lastObjectDb = _objectDbInstance;
				_itemCatalogReady = false;
				_itemEntries.Clear();
				_selectedItem = 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 ? (T("Catalogue loaded: ", "Каталог существ загружен: ") + _entries.Count + T(" creatures. Spawning is available to the host/server only.", " существ. Создание доступно только хосту/серверу.")) : T("No creatures were found in the game prefabs. Check BepInEx/LogOutput.log.", "В игровых префабах не найдены существа. Проверь 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 = T("Failed to load the creature catalogue. See BepInEx/LogOutput.log.", "Не удалось загрузить каталог существ. См. BepInEx/LogOutput.log.");
			}
		}

		private void RefreshItemCatalogue()
		{
			if (_objectDbInstance == null || _itemDropType == null)
			{
				return;
			}
			try
			{
				if (!(ReadMember(_objectDbInstance, "m_items") is IEnumerable enumerable))
				{
					return;
				}
				string value = ((_selectedItem == null) ? null : _selectedItem.PrefabName);
				Dictionary<string, ItemEntry> dictionary = new Dictionary<string, ItemEntry>(StringComparer.OrdinalIgnoreCase);
				foreach (object item in enumerable)
				{
					GameObject val = (GameObject)((item is GameObject) ? item : null);
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Component val2 = null;
					try
					{
						val2 = val.GetComponent(_itemDropType);
					}
					catch
					{
					}
					if (!((Object)(object)val2 == (Object)null))
					{
						object obj2 = ReadMember(ReadMember(val2, "m_itemData"), "m_shared");
						if (obj2 != null)
						{
							string text = Convert.ToString(ReadMember(obj2, "m_itemType")) ?? "Misc";
							string raw = ReadStringMember(obj2, "m_name");
							string localizedName = LocalizeName(raw, ((Object)val).name);
							string englishSafeName = GetEnglishSafeName(localizedName, ((Object)val).name);
							float foodValue = ReadFloatMember(obj2, "m_food");
							ItemCategory category = ClassifyItem(text, foodValue, ((Object)val).name);
							int declaredMaxQuality = Mathf.Clamp(ReadIntMember(obj2, "m_maxQuality", 1), 1, 10);
							int selectableMaxQuality = GetSelectableMaxQuality(category, text, ((Object)val).name, declaredMaxQuality);
							ItemEntry value2 = new ItemEntry(val, ((Object)val).name, englishSafeName, localizedName, text, category, selectableMaxQuality);
							dictionary[((Object)val).name] = value2;
						}
					}
				}
				_itemEntries.Clear();
				_itemEntries.AddRange(dictionary.Values);
				_itemEntries.Sort(delegate(ItemEntry a, ItemEntry b)
				{
					int num2 = a.Category.CompareTo(b.Category);
					return (num2 != 0) ? num2 : string.Compare(a.EnglishName, b.EnglishName, StringComparison.CurrentCultureIgnoreCase);
				});
				_selectedItem = null;
				if (!string.IsNullOrEmpty(value))
				{
					for (int num = 0; num < _itemEntries.Count; num++)
					{
						if (_itemEntries[num].PrefabName.Equals(value, StringComparison.OrdinalIgnoreCase))
						{
							_selectedItem = _itemEntries[num];
							break;
						}
					}
				}
				_itemCatalogReady = true;
				if (_itemEntries.Count == 0)
				{
					_status = T("No supported item prefabs were found in ObjectDB.", "В ObjectDB не найдены поддерживаемые предметы.");
				}
				else
				{
					_status = T("Item catalogue loaded: ", "Каталог предметов загружен: ") + _itemEntries.Count;
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Item catalogue refreshed: " + _itemEntries.Count + " item prefabs available."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not read the item catalogue: " + ex));
				_status = T("Failed to load the item catalogue. See BepInEx/LogOutput.log.", "Не удалось загрузить каталог предметов. См. BepInEx/LogOutput.log.");
			}
		}

		private static ItemCategory ClassifyItem(string itemType, float foodValue, string prefabName)
		{
			string text = (itemType ?? string.Empty).Trim();
			string text2 = (prefabName ?? string.Empty).ToLowerInvariant();
			if (IsWeaponType(text, text2))
			{
				return ItemCategory.Weapons;
			}
			if (text.Equals("Shield", StringComparison.OrdinalIgnoreCase) || text2.Contains("shield") || text.Equals("Helmet", StringComparison.OrdinalIgnoreCase) || text.Equals("Chest", StringComparison.OrdinalIgnoreCase) || text.Equals("Legs", StringComparison.OrdinalIgnoreCase) || text.Equals("Hands", StringComparison.OrdinalIgnoreCase) || text.Equals("Shoulder", StringComparison.OrdinalIgnoreCase) || text.Equals("Utility", StringComparison.OrdinalIgnoreCase) || text.Equals("Trinket", StringComparison.OrdinalIgnoreCase) || text.Equals("Trinkets", StringComparison.OrdinalIgnoreCase) || text2.Contains("trinket"))
			{
				return ItemCategory.Armor;
			}
			if (foodValue > 0.01f)
			{
				return ItemCategory.Food;
			}
			if (text.Equals("Material", StringComparison.OrdinalIgnoreCase) || text.IndexOf("Trophie", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Trophy", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return ItemCategory.Materials;
			}
			return ItemCategory.Other;
		}

		private static bool IsWeaponType(string itemType, string lowerPrefabName)
		{
			string text = (itemType ?? string.Empty).Trim();
			string text2 = lowerPrefabName ?? string.Empty;
			if (text.IndexOf("Weapon", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Ammo", StringComparison.OrdinalIgnoreCase) >= 0 || text.Equals("Bow", StringComparison.OrdinalIgnoreCase) || text.Equals("Attach_Atgeir", StringComparison.OrdinalIgnoreCase) || text.Equals("Torch", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (!text2.Contains("arrow") && !text2.Contains("bolt") && !text2.Contains("spear") && !text2.Contains("atgeir") && !text2.Contains("crossbow"))
			{
				return text2.Contains("bow_");
			}
			return true;
		}

		private static object ReadMember(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);
					}
					catch
					{
					}
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.GetIndexParameters().Length == 0)
				{
					try
					{
						return property.GetValue(instance, null);
					}
					catch
					{
					}
				}
				type = type.BaseType;
			}
			return null;
		}

		private static float ReadFloatMember(object instance, string name)
		{
			object obj = ReadMember(instance, name);
			try
			{
				return (obj == null) ? 0f : Convert.ToSingle(obj);
			}
			catch
			{
				return 0f;
			}
		}

		private static int ReadIntMember(object instance, string name, int fallback)
		{
			object obj = ReadMember(instance, name);
			try
			{
				return (obj == null) ? fallback : Convert.ToInt32(obj);
			}
			catch
			{
				return fallback;
			}
		}

		private string LocalizeName(string raw, string fallback)
		{
			if (string.IsNullOrWhiteSpace(raw))
			{
				return fallback;
			}
			if (!raw.StartsWith("$", StringComparison.Ordinal))
			{
				return raw;
			}
			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 text = methods[i].Invoke(singleton, new object[1] { raw }) as string;
						if (!string.IsNullOrWhiteSpace(text) && text[0] != '$')
						{
							return text;
						}
					}
					catch
					{
					}
				}
			}
			return fallback;
		}

		private void AddSelectedItemToInventory()
		{
			if (_selectedItem == null || (Object)(object)_selectedItem.Prefab == (Object)null)
			{
				_status = T("Select an item first.", "Сначала выбери предмет.");
				return;
			}
			RefreshGameReferences();
			if ((Object)(object)_playerComponent == (Object)null)
			{
				_status = T("Player not found. Enter a world first.", "Игрок не найден. Сначала войди в мир.");
				return;
			}
			if (!IsServer())
			{
				_status = T("Inventory spawning is available to the host/server only.", "Добавление предметов доступно только хосту/серверу.");
				return;
			}
			try
			{
				MethodInfo method = ((object)_playerComponent).GetType().GetMethod("GetInventory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				object obj = ((method == null) ? null : method.Invoke(_playerComponent, null));
				if (obj == null)
				{
					_status = T("Could not access the player's inventory.", "Не удалось получить доступ к инвентарю игрока.");
					return;
				}
				int num = Mathf.Clamp(_itemCount, 1, 9999);
				int num2 = Mathf.Clamp(_itemQuality, 1, Mathf.Max(1, _selectedItem.MaxQuality));
				if (_selectedItem.Category == ItemCategory.Food)
				{
					bool flag = TryAddFoodToInventory(obj, num, num2);
					if (flag)
					{
						ResetItemAmountAfterSuccessfulAdd();
					}
					_status = (flag ? (T("Added ", "Добавлено ") + num + T(" × ", " × ") + GetItemDisplayName(_selectedItem) + T(" to inventory.", " в инвентарь.")) : T("Could not add food. Check inventory space and BepInEx/LogOutput.log.", "Не удалось добавить еду. Проверь место в инвентаре и BepInEx/LogOutput.log."));
					return;
				}
				if (IsBodyArmorItem(_selectedItem))
				{
					int num3 = TryAddArmorToInventory(obj, num, num2);
					if (num3 > 0)
					{
						ResetItemAmountAfterSuccessfulAdd();
					}
					_status = ((num3 > 0) ? (T("Added ", "Добавлено ") + num3 + T(" × ", " × ") + GetItemDisplayName(_selectedItem) + T(" to inventory at full durability.", " в инвентарь с полной прочностью.")) : T("Could not add armor. Check inventory space and BepInEx/LogOutput.log.", "Не удалось добавить броню. Проверь место в инвентаре и BepInEx/LogOutput.log."));
					return;
				}
				if (num2 > 4 && IsExtendedQualityNonWeaponItem(_selectedItem))
				{
					int num4 = TryAddArmorToInventory(obj, num, num2);
					if (num4 > 0)
					{
						ResetItemAmountAfterSuccessfulAdd();
					}
					_status = ((num4 > 0) ? (T("Added ", "Добавлено ") + num4 + T(" × ", " × ") + GetItemDisplayName(_selectedItem) + T(" at extended quality with full durability.", " с расширенным качеством и полной прочностью.")) : T("Could not add this item at extended quality. Check BepInEx/LogOutput.log.", "Не удалось добавить предмет с расширенным качеством. Проверь BepInEx/LogOutput.log."));
					return;
				}
				if (IsWeaponOrShieldItem(_selectedItem))
				{
					int num5 = TryAddWeaponOrShieldToInventory(obj, num, num2);
					if (num5 > 0)
					{
						ResetItemAmountAfterSuccessfulAdd();
					}
					_status = ((num5 > 0) ? (T("Added ", "Добавлено ") + num5 + T(" × ", " × ") + GetItemDisplayName(_selectedItem) + T(" to inventory at full durability.", " в инвентарь с полной прочностью.")) : T("Could not add weapon or shield. Check inventory space and BepInEx/LogOutput.log.", "Не удалось добавить оружие или щит. Проверь место в инвентаре и BepInEx/LogOutput.log."));
					return;
				}
				MethodInfo[] methods = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				bool flag2 = false;
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name != "AddItem")
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if (parameters.Length != 6 || parameters[1].ParameterType != typeof(int) || parameters[2].ParameterType != typeof(int) || parameters[3].ParameterType != typeof(int) || parameters[4].ParameterType != typeof(long) || parameters[5].ParameterType != typeof(string))
					{
						continue;
					}
					object obj2;
					if (parameters[0].ParameterType == typeof(GameObject))
					{
						obj2 = _selectedItem.Prefab;
					}
					else
					{
						if (!(parameters[0].ParameterType == typeof(string)))
						{
							continue;
						}
						obj2 = _selectedItem.PrefabName;
					}
					try
					{
						object obj3 = methodInfo.Invoke(obj, new object[6]
						{
							obj2,
							num,
							num2,
							0,
							0L,
							string.Empty
						});
						if (methodInfo.ReturnType == typeof(void) || obj3 != null)
						{
							flag2 = true;
							break;
						}
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("AddItem overload failed: " + ex.Message));
					}
				}
				if (!flag2)
				{
					object obj4 = ReadMember(_selectedItem.Prefab.GetComponent(_itemDropType), "m_itemData");
					MethodInfo methodInfo2 = obj4?.GetType().GetMethod("Clone", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
					object obj5 = ((methodInfo2 == null) ? null : methodInfo2.Invoke(obj4, null));
					if (obj5 != null)
					{
						TrySetIntMember(obj5, "m_stack", num);
						TrySetIntMember(obj5, "m_quality", num2);
						for (int j = 0; j < methods.Length; j++)
						{
							if (methods[j].Name != "AddItem")
							{
								continue;
							}
							ParameterInfo[] parameters2 = methods[j].GetParameters();
							if (parameters2.Length == 1 && parameters2[0].ParameterType.IsInstanceOfType(obj5))
							{
								try
								{
									methods[j].Invoke(obj, new object[1] { obj5 });
									flag2 = true;
								}
								catch (Exception ex2)
								{
									((BaseUnityPlugin)this).Logger.LogDebug((object)("ItemData AddItem fallback failed: " + ex2.Message));
									continue;
								}
								break;
							}
							if (parameters2.Length == 4 && parameters2[0].ParameterType.IsInstanceOfType(obj5) && parameters2[1].ParameterType == typeof(int) && parameters2[2].ParameterType == typeof(int) && parameters2[3].ParameterType == typeof(int))
							{
								try
								{
									methods[j].Invoke(obj, new object[4] { obj5, num, 0, 0 });
									flag2 = true;
								}
								catch (Exception ex3)
								{
									((BaseUnityPlugin)this).Logger.LogDebug((object)("ItemData AddItem overload fallback failed: " + ex3.Message));
									continue;
								}
								break;
							}
						}
					}
				}
				if (flag2)
				{
					ResetItemAmountAfterSuccessfulAdd();
				}
				_status = (flag2 ? (T("Added ", "Добавлено ") + num + T(" × ", " × ") + GetItemDisplayName(_selectedItem) + T(" to inventory.", " в инвентарь.")) : T("Could not add this item. See BepInEx/LogOutput.log.", "Не удалось добавить предмет. См. BepInEx/LogOutput.log."));
			}
			catch (Exception ex4)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to add item to inventory: " + ex4));
				_status = T("Failed to add item. See BepInEx/LogOutput.log.", "Не удалось добавить предмет. См. BepInEx/LogOutput.log.");
			}
		}

		private void ResetItemAmountAfterSuccessfulAdd()
		{
			_itemCount = 1;
			_itemCountInput = "1";
		}

		private static bool IsBodyArmorItem(ItemEntry entry)
		{
			if (entry == null || entry.Category != ItemCategory.Armor)
			{
				return false;
			}
			string text = (entry.ItemTypeLabel ?? string.Empty).Trim();
			string text2 = (entry.PrefabName ?? string.Empty).ToLowerInvariant();
			if (text.Equals("Shield", StringComparison.OrdinalIgnoreCase) || text2.Contains("shield"))
			{
				return false;
			}
			if (!text.Equals("Helmet", StringComparison.OrdinalIgnoreCase) && !text.Equals("Chest", StringComparison.OrdinalIgnoreCase) && !text.Equals("Legs", StringComparison.OrdinalIgnoreCase) && !text.Equals("Hands", StringComparison.OrdinalIgnoreCase))
			{
				return text.Equals("Shoulder", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool IsWeaponOrShieldItem(ItemEntry entry)
		{
			if (entry == null)
			{
				return false;
			}
			string text = (entry.ItemTypeLabel ?? string.Empty).Trim();
			string text2 = (entry.PrefabName ?? string.Empty).ToLowerInvariant();
			if (text.Equals("Shield", StringComparison.OrdinalIgnoreCase) || text2.Contains("shield"))
			{
				return true;
			}
			if (entry.Category != ItemCategory.Weapons)
			{
				return IsWeaponType(text, text2);
			}
			return true;
		}

		private static int GetSelectableMaxQuality(ItemCategory category, string itemType, string prefabName, int declaredMaxQuality)
		{
			int num = Mathf.Clamp(declaredMaxQuality, 1, 10);
			string text = (itemType ?? string.Empty).Trim();
			string text2 = (prefabName ?? string.Empty).ToLowerInvariant();
			if (category == ItemCategory.Weapons || IsWeaponType(text, text2) || text.Equals("Shield", StringComparison.OrdinalIgnoreCase) || (text2.Contains("shield") && !IsWeaponType(text, text2)))
			{
				if (num <= 1)
				{
					return num;
				}
				return 10;
			}
			bool num2 = category == ItemCategory.Armor && (text.Equals("Helmet", StringComparison.OrdinalIgnoreCase) || text.Equals("Chest", StringComparison.OrdinalIgnoreCase) || text.Equals("Legs", StringComparison.OrdinalIgnoreCase) || text.Equals("Hands", StringComparison.OrdinalIgnoreCase) || text.Equals("Shoulder", StringComparison.OrdinalIgnoreCase) || text.Equals("Utility", StringComparison.OrdinalIgnoreCase) || text.Equals("Trinket", StringComparison.OrdinalIgnoreCase) || text.Equals("Trinkets", StringComparison.OrdinalIgnoreCase));
			bool flag = category == ItemCategory.Other && text.Equals("Tool", StringComparison.OrdinalIgnoreCase);
			if ((num2 || flag) && num > 1)
			{
				return 10;
			}
			return num;
		}

		private static bool IsExtendedQualityNonWeaponItem(ItemEntry entry)
		{
			if (entry == null)
			{
				return false;
			}
			string text = (entry.ItemTypeLabel ?? string.Empty).Trim();
			string text2 = (entry.PrefabName ?? string.Empty).ToLowerInvariant();
			if (entry.Category == ItemCategory.Weapons || IsWeaponType(text, text2) || text.Equals("Shield", StringComparison.OrdinalIgnoreCase) || text2.Contains("shield"))
			{
				return false;
			}
			if (entry.Category == ItemCategory.Armor)
			{
				if (!text.Equals("Helmet", StringComparison.OrdinalIgnoreCase) && !text.Equals("Chest", StringComparison.OrdinalIgnoreCase) && !text.Equals("Legs", StringComparison.OrdinalIgnoreCase) && !text.Equals("Hands", StringComparison.OrdinalIgnoreCase) && !text.Equals("Shoulder", StringComparison.OrdinalIgnoreCase) && !text.Equals("Utility", StringComparison.OrdinalIgnoreCase) && !text.Equals("Trinket", StringComparison.OrdinalIgnoreCase))
				{
					return text.Equals("Trinkets", StringComparison.OrdinalIgnoreCase);
				}
				return true;
			}
			if (entry.Category == ItemCategory.Other)
			{
				return text.Equals("Tool", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private int TryAddArmorToInventory(object inventory, int amount, int quality)
		{
			try
			{
				object obj = ReadMember(_selectedItem.Prefab.GetComponent(_itemDropType), "m_itemData");
				if (obj == null)
				{
					return 0;
				}
				MethodInfo method = obj.GetType().GetMethod("Clone", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method == null)
				{
					return 0;
				}
				MethodInfo[] methods = inventory.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo methodInfo = null;
				for (int i = 0; i < methods.Length; i++)
				{
					if (!(methods[i].Name != "AddItem"))
					{
						ParameterInfo[] parameters = methods[i].GetParameters();
						if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(obj.GetType()))
						{
							methodInfo = methods[i];
							break;
						}
					}
				}
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Equipment item fix: no compatible Inventory.AddItem(ItemData) overload was found.");
					return 0;
				}
				object value = ReadMember(obj, "m_shared");
				int num = 0;
				int num2 = Mathf.Clamp(amount, 1, 9999);
				for (int j = 0; j < num2; j++)
				{
					object obj2 = method.Invoke(obj, null);
					if (obj2 == null)
					{
						break;
					}
					TrySetIntMember(obj2, "m_stack", 1);
					TrySetIntMember(obj2, "m_quality", quality);
					TrySetReferenceMember(obj2, "m_dropPrefab", _selectedItem.Prefab);
					if (ReadMember(obj2, "m_shared") == null)
					{
						TrySetReferenceMember(obj2, "m_shared", value);
					}
					object obj3 = ReadMember(obj2, "m_shared");
					bool flag = false;
					try
					{
						flag = Convert.ToBoolean(ReadMember(obj3, "m_useDurability"));
					}
					catch
					{
					}
					if (flag)
					{
						float itemMaxDurability = GetItemMaxDurability(obj2, obj3, quality);
						if (itemMaxDurability > 0f)
						{
							TrySetFloatMember(obj2, "m_durability", itemMaxDurability);
						}
					}
					try
					{
						object obj5 = methodInfo.Invoke(inventory, new object[1] { obj2 });
						if (!((methodInfo.ReturnType == typeof(bool)) ? (obj5 is bool && (bool)obj5) : (methodInfo.ReturnType == typeof(void) || obj5 != null)))
						{
							break;
						}
						num++;
						continue;
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Equipment item AddItem failed: " + ex.Message));
					}
					break;
				}
				if (num > 0)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Equipment items added with explicit prefab references and full durability: " + num));
				}
				return num;
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not add equipment with a valid prefab reference and full durability: " + ex2));
				return 0;
			}
		}

		private int TryAddWeaponOrShieldToInventory(object inventory, int amount, int quality)
		{
			try
			{
				if (_selectedItem == null || (Object)(object)_selectedItem.Prefab == (Object)null)
				{
					return 0;
				}
				object obj = ReadMember(_selectedItem.Prefab.GetComponent(_itemDropType), "m_itemData");
				if (obj == null)
				{
					return 0;
				}
				MethodInfo method = obj.GetType().GetMethod("Clone", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method == null)
				{
					return 0;
				}
				MethodInfo[] methods = inventory.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo methodInfo = null;
				for (int i = 0; i < methods.Length; i++)
				{
					if (!(methods[i].Name != "AddItem"))
					{
						ParameterInfo[] parameters = methods[i].GetParameters();
						if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(obj.GetType()))
						{
							methodInfo = methods[i];
							break;
						}
					}
				}
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Weapon/shield fix: no compatible Inventory.AddItem(ItemData) overload was found.");
					return 0;
				}
				object value = ReadMember(obj, "m_shared");
				int num = Mathf.Clamp(amount, 1, 9999);
				int num2 = Mathf.Clamp(quality, 1, Mathf.Max(1, _selectedItem.MaxQuality));
				int num3 = 0;
				for (int j = 0; j < num; j++)
				{
					object obj2 = method.Invoke(obj, null);
					if (obj2 == null)
					{
						break;
					}
					TrySetIntMember(obj2, "m_stack", 1);
					TrySetIntMember(obj2, "m_quality", num2);
					if (!TrySetReferenceMember(obj2, "m_dropPrefab", _selectedItem.Prefab) && ReadMember(obj2, "m_dropPrefab") != _selectedItem.Prefab)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Weapon/shield fix: could not set m_dropPrefab for " + _selectedItem.PrefabName));
						break;
					}
					if (ReadMember(obj2, "m_shared") == null)
					{
						TrySetReferenceMember(obj2, "m_shared", value);
					}
					object obj3 = ReadMember(obj2, "m_shared");
					bool flag = false;
					try
					{
						flag = Convert.ToBoolean(ReadMember(obj3, "m_useDurability"));
					}
					catch
					{
					}
					if (flag)
					{
						float itemMaxDurability = GetItemMaxDurability(obj2, obj3, num2);
						if (itemMax