Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimCreatureSpawner v0.2.3
BepInEx/plugins/ValheimCreatureSpawner/ValheimCreatureSpawner.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ValheimCreatureSpawner")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ValheimCreatureSpawner")] [assembly: AssemblyTitle("ValheimCreatureSpawner")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SuperNova.ValheimCreatureSpawner { internal enum CreatureCategory { Regular, Boss } internal sealed class CreatureMetadata { public string English; public string Russian; public CreatureCategory Category; public string[] Biomes; public CreatureMetadata(string english, string russian, CreatureCategory category, string biomeList) { English = english; Russian = russian; Category = category; Biomes = (string.IsNullOrWhiteSpace(biomeList) ? new string[0] : biomeList.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries)); } } internal static class CreatureCatalog { private const string CatalogData = "\nEikthyr|Eikthyr|Эйктюр|Boss|Meadows\ngd_king|The Elder|Древний|Boss|Black Forest\nBonemass|Bonemass|Масса костей|Boss|Swamp\nDragon|Moder|Модер|Boss|Mountains\nGoblinKing|Yagluth|Яглут|Boss|Plains\nSeekerQueen|The Queen|Королева|Boss|Mistlands\nFader|Fader|Прародитель|Boss|Ashlands\nFrozenKing|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nFrozenKing_p2|Kall Fimbulbringer (phase 2)|Калль Фимбульбрингер (фаза 2)|Boss|Deep North\nFrozenKing_p3|Kall Fimbulbringer (phase 3)|Калль Фимбульбрингер (фаза 3)|Boss|Deep North\nKallFimbulbringer|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nBrenna|Brenna|Бренна|Boss|Black Forest\nGeirrhafa|Geirrhafa|Гейрафа|Boss|Mountains\nZil|Zil|Зил|Boss|Mistlands\nThungr|Thungr|Тангр|Boss|Mistlands\nCharred_Melee_Dyrnwyn|Lord Reto|Владыка Рето|Boss|Ashlands\nBoar|Boar|Кабан|Regular|Meadows;Black Forest\nBoar_piggy|Boar piglet|Поросёнок кабана|Regular|Meadows;Black Forest\nDeer|Deer|Олень|Regular|Meadows;Black Forest\nDeer_White|White deer|Белый олень|Regular|Deep North\nNeck|Neck|Никс|Regular|Meadows\nGreyling|Greyling|Грейлинг|Regular|Meadows\nGreydwarf|Greydwarf|Грейдворф|Regular|Black Forest\nGreydwarf_Elite|Greydwarf Brute|Грейдворф-берсерк|Regular|Black Forest\nGreydwarf_Shaman|Greydwarf Shaman|Грейдворф-шаман|Regular|Black Forest\nGreydwarf_Spawn|Greydwarf nest spawn|Порождение грейдворфов|Regular|Black Forest\nGreydwarf_Frozen|Frozen greydwarf|Ледяной грейдворф|Regular|Deep North\nGreydwarf_Shaman_Frozen|Frozen greydwarf shaman|Ледяной грейдворф-шаман|Regular|Deep North\nTroll|Troll|Тролль|Regular|Black Forest\nTrollFrost|Gammeltroll|Гаммельтролль|Regular|Deep North\nTroll_sleeping|Sleeping troll|Спящий тролль|Regular|Deep North\nSkeleton|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_NoArcher|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_Poison|Poison skeleton|Ядовитый скелет|Regular|Swamp\nSkeleton_Meadows|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Meadows_noarcher|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Mountains|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Mountains_noarcher|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Swamps|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_Swamps_noarcher|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_aspect|Skeleton aspect|Аспект скелета|Regular|Deep North\nDraugr|Draugr|Драугр|Regular|Swamp\nDraugr_Elite|Draugr Elite|Драугр-элита|Regular|Swamp\nDraugr_Ranged|Draugr Archer|Драугр-лучник|Regular|Swamp\nDraugr_Ranged_down|Draugr Archer (down)|Драугр-лучник (лежит)|Regular|Swamp\nDraugr_Elite_sleeping|Sleeping draugr elite|Спящий драугр-элита|Regular|Deep North\nDraugr_Ranged_sleeping|Sleeping draugr archer|Спящий драугр-лучник|Regular|Deep North\nDraugr_sleeping|Sleeping draugr|Спящий драугр|Regular|Deep North\nBlob|Blob|Сгустень|Regular|Swamp\nBlobElite|Blob elite|Большой сгустень|Regular|Swamp\nBlobTar|Tar blob|Дегтевой сгустень|Regular|Plains\nBlobMork|Shapeless Pulp|Бесформенная слизь|Regular|Deep North\nBlobMorkMini|Tiny Pulp|Крошечная слизь|Regular|Deep North\nBlobAspect|Blob aspect|Аспект сгустня|Regular|Deep North\nLeech|Leech|Пиявка|Regular|Swamp\nWraith|Wraith|Призрак|Regular|Swamp\nGhost|Ghost|Призрак|Regular|Black Forest\nGhost_old|Old ghost|Старый призрак|Regular|Deep North\nGhost_sleeping|Sleeping ghost|Спящий призрак|Regular|Deep North\nGhost_Void|Void ghost|Пустотный призрак|Regular|Deep North\nAbomination|Abomination|Мерзость|Regular|Swamp\nSurtling|Surtling|Суртлинг|Regular|Swamp;Ashlands\nWolf|Wolf|Волк|Regular|Mountains\nWolf_cub|Wolf cub|Волчонок|Regular|Mountains\nWolf_spiritcaller|Spirit-caller wolf|Волк призывателя духов|Regular|Deep North\nFenring|Fenring|Фенринг|Regular|Mountains\nFenring_Cultist|Fenring Cultist|Фенринг-культист|Regular|Mountains\nHatchling|Drake|Дракончик|Regular|Mountains\nStoneGolem|Stone Golem|Каменный голем|Regular|Mountains\nUlv|Ulv|Ульв|Regular|Mountains\nBat|Bat|Летучая мышь|Regular|Mountains\nBear|Bear|Медведь|Regular|Deep North\nCultist|Cultist|Культист|Regular|Mountains\nSerpent|Serpent|Морской змей|Regular|Ocean\nDeathsquito|Deathsquito|Смертожал|Regular|Plains\nLox|Lox|Локс|Regular|Plains\nGoblin|Fuling|Фулинг|Regular|Plains\nGoblinArcher|Fuling Archer|Фулинг-лучник|Regular|Plains\nGoblinShaman|Fuling Shaman|Фулинг-шаман|Regular|Plains\nGoblinBrute|Fuling Berserker|Фулинг-берсерк|Regular|Plains\nAsksvin|Asksvin|Асксвин|Regular|Ashlands\nAsksvin_cub|Asksvin calf|Детёныш асксвина|Regular|Ashlands\nMorgen|Morgen|Морген|Regular|Ashlands\nMorgen_Naked|Morgen (unarmored)|Морген без брони|Regular|Ashlands\nFallenValkyrie|Charred Valkyrie|Обугленная валькирия|Regular|Ashlands\nCharred_Twitcher|Charred Twitcher|Обугленный прыгун|Regular|Ashlands\nCharred_Melee|Charred Warrior|Обугленный воин|Regular|Ashlands\nCharred_Archer|Charred Marksman|Обугленный стрелок|Regular|Ashlands\nCharred_Mage|Charred Mage|Обугленный маг|Regular|Ashlands\nVolture|Volture|Вольтур|Regular|Ashlands\nTick|Tick|Клещ|Regular|Mistlands\nSeeker|Seeker|Искатель|Regular|Mistlands\nSeekerBrood|Seeker Brood|Выводок искателя|Regular|Mistlands\nSeekerBrute|Seeker Soldier|Искатель-солдат|Regular|Mistlands\nGjall|Gjall|Гьялль|Regular|Mistlands\nHare|Hare|Заяц|Regular|Mistlands\nDverger|Dvergr|Дверг|Regular|Mistlands\nDvergerMage|Dvergr Mage|Дверг-маг|Regular|Mistlands\nDvergerMageFire|Dvergr Fire Mage|Дверг-маг огня|Regular|Mistlands\nDvergerMageIce|Dvergr Frost Mage|Дверг-маг льда|Regular|Mistlands\nDvergerMageSupport|Dvergr Support Mage|Дверг-маг поддержки|Regular|Mistlands\nDvergerRogue|Dvergr Rogue|Дверг-разведчик|Regular|Mistlands\nChicken|Chicken|Курица|Regular|Any Biome\nHen|Hen|Курица-несушка|Regular|Any Biome\nFish1|Fish|Рыба|Regular|Rivers;Ocean\nFish2|Fish|Рыба|Regular|Rivers;Ocean\nFish3|Fish|Рыба|Regular|Ocean\nFish4_cave|Cave fish|Пещерная рыба|Regular|Mountain Caves\nCrow|Crow|Ворон|Regular|Any Biome\nAshCrow|Ash crow|Пепельный ворон|Regular|Ashlands\nGull|Gull|Чайка|Regular|Ocean;Meadows;Black Forest;Plains\nLeviathan|Leviathan|Левиафан|Regular|Ocean\nHugin|Hugin|Хугин|Regular|Any Biome\nMunin|Munin|Мунин|Regular|Mistlands;Ashlands\nOdin|Odin|Один|Regular|Any Biome\nValkyrie|Valkyrie|Валькирия|Regular|Any Biome\nHaldor|Haldor|Хальдор|Regular|Black Forest\nHildir|Hildir|Хильдир|Regular|Meadows\nBogWitch|The Bog Witch|Болотная ведьма|Regular|Swamp\nHalstein|Halstein|Хальштейн|Regular|Meadows\nBlub|Blåbær|Блубэр|Regular|Meadows\nHallon|Hallon|Халлон|Regular|Meadows\nBoar_spiritcaller|Spirit-caller boar|Кабан призывателя духов|Regular|Deep North\nMoose|Moose|Лось|Regular|Deep North\nMoose_calf|Moose calf|Лосёнок|Regular|Deep North\nMoose_spiritcaller|Spirit-caller moose|Лось призывателя духов|Regular|Deep North\nSeal|Seal|Тюлень|Regular|Deep North\nSeal_Pup|Seal pup|Детёныш тюленя|Regular|Deep North\nFrysling|Frysling|Фризлинг|Regular|Deep North\nFrostWisp|Frost Wisp|Ледяной дух|Regular|Deep North\nBat_Swamp|Swamp bat|Болотная летучая мышь|Regular|Swamp\nBarka|Barka|Барка|Regular|Deep North\nElaking|Elaking|Элакинг|Regular|Deep North\nElakingLantern|Elaking Lantern|Элакинг с фонарём|Regular|Deep North\nElakingMole|Eyeless One|Безглазый|Regular|Deep North\nFallenWarrior|Fallen Warrior|Павший воин|Regular|Deep North\nJotunWarrior|Krigen|Криген|Regular|Deep North\nJotunWarriorDualWield|Krigen (dual wield)|Криген с двумя оружиями|Regular|Deep North\nJotunWitch|Hexen|Хексен|Regular|Deep North\nShadowPerson|Shadow|Тень|Regular|Deep North\nTendril|Tendril|Усик|Regular|Deep North\nTendril_back|Back tendril|Задний усик|Regular|Deep North\nTentaRoot_wild|Wild tentaroot|Дикая тентакорень|Regular|Deep North\nWrithan|Writhan|Ритхан|Regular|Deep North\nGoblinDeepNorth|Deep North goblin|Гоблин Дальнего севера|Regular|Deep North\nDvergerDeepNorth|Imprisoned Dvergr|Пленённый дверг|Regular|Deep North\nBjorn_sleeping|Sleeping Bjorn|Спящий Бьёрн|Regular|Deep North\nBjorn_spiritcaller|Spirit-caller Bjorn|Бьёрн призывателя духов|Regular|Deep North\nAspect_Eikthyr|Aspect of the Lightning Stag|Аспект Эйктюра|Boss|Any Biome\nAspect_Elder|Aspect of the Living Forest|Аспект Древнего|Boss|Any Biome\nAspect_Bonemass|Aspect of the Twisted Soul|Аспект Массы костей|Boss|Any Biome\nAspect_Moder|Aspect of the Dragon Mother|Аспект Модер|Boss|Any Biome\nAspect_Yagluth|Aspect of the Writhing Dead|Аспект Яглута|Boss|Any Biome\nAspect_SeekerQueen|Aspect of the Crawling Matriarch|Аспект Королевы|Boss|Any Biome\nAspect_Fader|Aspect of the Emerald Flame|Аспект Прародителя|Boss|Any Biome\nAspect_TentaRoot|Aspect of the Tentaroot|Аспект тентакорня|Boss|Any Biome\n"; private static readonly Dictionary<string, CreatureMetadata> Metadata = Build(); private static Dictionary<string, CreatureMetadata> Build() { Dictionary<string, CreatureMetadata> dictionary = new Dictionary<string, CreatureMetadata>(StringComparer.OrdinalIgnoreCase); string[] array = "\nEikthyr|Eikthyr|Эйктюр|Boss|Meadows\ngd_king|The Elder|Древний|Boss|Black Forest\nBonemass|Bonemass|Масса костей|Boss|Swamp\nDragon|Moder|Модер|Boss|Mountains\nGoblinKing|Yagluth|Яглут|Boss|Plains\nSeekerQueen|The Queen|Королева|Boss|Mistlands\nFader|Fader|Прародитель|Boss|Ashlands\nFrozenKing|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nFrozenKing_p2|Kall Fimbulbringer (phase 2)|Калль Фимбульбрингер (фаза 2)|Boss|Deep North\nFrozenKing_p3|Kall Fimbulbringer (phase 3)|Калль Фимбульбрингер (фаза 3)|Boss|Deep North\nKallFimbulbringer|Kall Fimbulbringer|Калль Фимбульбрингер|Boss|Deep North\nBrenna|Brenna|Бренна|Boss|Black Forest\nGeirrhafa|Geirrhafa|Гейрафа|Boss|Mountains\nZil|Zil|Зил|Boss|Mistlands\nThungr|Thungr|Тангр|Boss|Mistlands\nCharred_Melee_Dyrnwyn|Lord Reto|Владыка Рето|Boss|Ashlands\nBoar|Boar|Кабан|Regular|Meadows;Black Forest\nBoar_piggy|Boar piglet|Поросёнок кабана|Regular|Meadows;Black Forest\nDeer|Deer|Олень|Regular|Meadows;Black Forest\nDeer_White|White deer|Белый олень|Regular|Deep North\nNeck|Neck|Никс|Regular|Meadows\nGreyling|Greyling|Грейлинг|Regular|Meadows\nGreydwarf|Greydwarf|Грейдворф|Regular|Black Forest\nGreydwarf_Elite|Greydwarf Brute|Грейдворф-берсерк|Regular|Black Forest\nGreydwarf_Shaman|Greydwarf Shaman|Грейдворф-шаман|Regular|Black Forest\nGreydwarf_Spawn|Greydwarf nest spawn|Порождение грейдворфов|Regular|Black Forest\nGreydwarf_Frozen|Frozen greydwarf|Ледяной грейдворф|Regular|Deep North\nGreydwarf_Shaman_Frozen|Frozen greydwarf shaman|Ледяной грейдворф-шаман|Regular|Deep North\nTroll|Troll|Тролль|Regular|Black Forest\nTrollFrost|Gammeltroll|Гаммельтролль|Regular|Deep North\nTroll_sleeping|Sleeping troll|Спящий тролль|Regular|Deep North\nSkeleton|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_NoArcher|Skeleton|Скелет|Regular|Black Forest;Swamp;Mountains\nSkeleton_Poison|Poison skeleton|Ядовитый скелет|Regular|Swamp\nSkeleton_Meadows|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Meadows_noarcher|Meadows skeleton|Скелет лугов|Regular|Deep North\nSkeleton_Mountains|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Mountains_noarcher|Mountain skeleton|Горный скелет|Regular|Deep North\nSkeleton_Swamps|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_Swamps_noarcher|Swamp skeleton|Болотный скелет|Regular|Deep North\nSkeleton_aspect|Skeleton aspect|Аспект скелета|Regular|Deep North\nDraugr|Draugr|Драугр|Regular|Swamp\nDraugr_Elite|Draugr Elite|Драугр-элита|Regular|Swamp\nDraugr_Ranged|Draugr Archer|Драугр-лучник|Regular|Swamp\nDraugr_Ranged_down|Draugr Archer (down)|Драугр-лучник (лежит)|Regular|Swamp\nDraugr_Elite_sleeping|Sleeping draugr elite|Спящий драугр-элита|Regular|Deep North\nDraugr_Ranged_sleeping|Sleeping draugr archer|Спящий драугр-лучник|Regular|Deep North\nDraugr_sleeping|Sleeping draugr|Спящий драугр|Regular|Deep North\nBlob|Blob|Сгустень|Regular|Swamp\nBlobElite|Blob elite|Большой сгустень|Regular|Swamp\nBlobTar|Tar blob|Дегтевой сгустень|Regular|Plains\nBlobMork|Shapeless Pulp|Бесформенная слизь|Regular|Deep North\nBlobMorkMini|Tiny Pulp|Крошечная слизь|Regular|Deep North\nBlobAspect|Blob aspect|Аспект сгустня|Regular|Deep North\nLeech|Leech|Пиявка|Regular|Swamp\nWraith|Wraith|Призрак|Regular|Swamp\nGhost|Ghost|Призрак|Regular|Black Forest\nGhost_old|Old ghost|Старый призрак|Regular|Deep North\nGhost_sleeping|Sleeping ghost|Спящий призрак|Regular|Deep North\nGhost_Void|Void ghost|Пустотный призрак|Regular|Deep North\nAbomination|Abomination|Мерзость|Regular|Swamp\nSurtling|Surtling|Суртлинг|Regular|Swamp;Ashlands\nWolf|Wolf|Волк|Regular|Mountains\nWolf_cub|Wolf cub|Волчонок|Regular|Mountains\nWolf_spiritcaller|Spirit-caller wolf|Волк призывателя духов|Regular|Deep North\nFenring|Fenring|Фенринг|Regular|Mountains\nFenring_Cultist|Fenring Cultist|Фенринг-культист|Regular|Mountains\nHatchling|Drake|Дракончик|Regular|Mountains\nStoneGolem|Stone Golem|Каменный голем|Regular|Mountains\nUlv|Ulv|Ульв|Regular|Mountains\nBat|Bat|Летучая мышь|Regular|Mountains\nBear|Bear|Медведь|Regular|Deep North\nCultist|Cultist|Культист|Regular|Mountains\nSerpent|Serpent|Морской змей|Regular|Ocean\nDeathsquito|Deathsquito|Смертожал|Regular|Plains\nLox|Lox|Локс|Regular|Plains\nGoblin|Fuling|Фулинг|Regular|Plains\nGoblinArcher|Fuling Archer|Фулинг-лучник|Regular|Plains\nGoblinShaman|Fuling Shaman|Фулинг-шаман|Regular|Plains\nGoblinBrute|Fuling Berserker|Фулинг-берсерк|Regular|Plains\nAsksvin|Asksvin|Асксвин|Regular|Ashlands\nAsksvin_cub|Asksvin calf|Детёныш асксвина|Regular|Ashlands\nMorgen|Morgen|Морген|Regular|Ashlands\nMorgen_Naked|Morgen (unarmored)|Морген без брони|Regular|Ashlands\nFallenValkyrie|Charred Valkyrie|Обугленная валькирия|Regular|Ashlands\nCharred_Twitcher|Charred Twitcher|Обугленный прыгун|Regular|Ashlands\nCharred_Melee|Charred Warrior|Обугленный воин|Regular|Ashlands\nCharred_Archer|Charred Marksman|Обугленный стрелок|Regular|Ashlands\nCharred_Mage|Charred Mage|Обугленный маг|Regular|Ashlands\nVolture|Volture|Вольтур|Regular|Ashlands\nTick|Tick|Клещ|Regular|Mistlands\nSeeker|Seeker|Искатель|Regular|Mistlands\nSeekerBrood|Seeker Brood|Выводок искателя|Regular|Mistlands\nSeekerBrute|Seeker Soldier|Искатель-солдат|Regular|Mistlands\nGjall|Gjall|Гьялль|Regular|Mistlands\nHare|Hare|Заяц|Regular|Mistlands\nDverger|Dvergr|Дверг|Regular|Mistlands\nDvergerMage|Dvergr Mage|Дверг-маг|Regular|Mistlands\nDvergerMageFire|Dvergr Fire Mage|Дверг-маг огня|Regular|Mistlands\nDvergerMageIce|Dvergr Frost Mage|Дверг-маг льда|Regular|Mistlands\nDvergerMageSupport|Dvergr Support Mage|Дверг-маг поддержки|Regular|Mistlands\nDvergerRogue|Dvergr Rogue|Дверг-разведчик|Regular|Mistlands\nChicken|Chicken|Курица|Regular|Any Biome\nHen|Hen|Курица-несушка|Regular|Any Biome\nFish1|Fish|Рыба|Regular|Rivers;Ocean\nFish2|Fish|Рыба|Regular|Rivers;Ocean\nFish3|Fish|Рыба|Regular|Ocean\nFish4_cave|Cave fish|Пещерная рыба|Regular|Mountain Caves\nCrow|Crow|Ворон|Regular|Any Biome\nAshCrow|Ash crow|Пепельный ворон|Regular|Ashlands\nGull|Gull|Чайка|Regular|Ocean;Meadows;Black Forest;Plains\nLeviathan|Leviathan|Левиафан|Regular|Ocean\nHugin|Hugin|Хугин|Regular|Any Biome\nMunin|Munin|Мунин|Regular|Mistlands;Ashlands\nOdin|Odin|Один|Regular|Any Biome\nValkyrie|Valkyrie|Валькирия|Regular|Any Biome\nHaldor|Haldor|Хальдор|Regular|Black Forest\nHildir|Hildir|Хильдир|Regular|Meadows\nBogWitch|The Bog Witch|Болотная ведьма|Regular|Swamp\nHalstein|Halstein|Хальштейн|Regular|Meadows\nBlub|Blåbær|Блубэр|Regular|Meadows\nHallon|Hallon|Халлон|Regular|Meadows\nBoar_spiritcaller|Spirit-caller boar|Кабан призывателя духов|Regular|Deep North\nMoose|Moose|Лось|Regular|Deep North\nMoose_calf|Moose calf|Лосёнок|Regular|Deep North\nMoose_spiritcaller|Spirit-caller moose|Лось призывателя духов|Regular|Deep North\nSeal|Seal|Тюлень|Regular|Deep North\nSeal_Pup|Seal pup|Детёныш тюленя|Regular|Deep North\nFrysling|Frysling|Фризлинг|Regular|Deep North\nFrostWisp|Frost Wisp|Ледяной дух|Regular|Deep North\nBat_Swamp|Swamp bat|Болотная летучая мышь|Regular|Swamp\nBarka|Barka|Барка|Regular|Deep North\nElaking|Elaking|Элакинг|Regular|Deep North\nElakingLantern|Elaking Lantern|Элакинг с фонарём|Regular|Deep North\nElakingMole|Eyeless One|Безглазый|Regular|Deep North\nFallenWarrior|Fallen Warrior|Павший воин|Regular|Deep North\nJotunWarrior|Krigen|Криген|Regular|Deep North\nJotunWarriorDualWield|Krigen (dual wield)|Криген с двумя оружиями|Regular|Deep North\nJotunWitch|Hexen|Хексен|Regular|Deep North\nShadowPerson|Shadow|Тень|Regular|Deep North\nTendril|Tendril|Усик|Regular|Deep North\nTendril_back|Back tendril|Задний усик|Regular|Deep North\nTentaRoot_wild|Wild tentaroot|Дикая тентакорень|Regular|Deep North\nWrithan|Writhan|Ритхан|Regular|Deep North\nGoblinDeepNorth|Deep North goblin|Гоблин Дальнего севера|Regular|Deep North\nDvergerDeepNorth|Imprisoned Dvergr|Пленённый дверг|Regular|Deep North\nBjorn_sleeping|Sleeping Bjorn|Спящий Бьёрн|Regular|Deep North\nBjorn_spiritcaller|Spirit-caller Bjorn|Бьёрн призывателя духов|Regular|Deep North\nAspect_Eikthyr|Aspect of the Lightning Stag|Аспект Эйктюра|Boss|Any Biome\nAspect_Elder|Aspect of the Living Forest|Аспект Древнего|Boss|Any Biome\nAspect_Bonemass|Aspect of the Twisted Soul|Аспект Массы костей|Boss|Any Biome\nAspect_Moder|Aspect of the Dragon Mother|Аспект Модер|Boss|Any Biome\nAspect_Yagluth|Aspect of the Writhing Dead|Аспект Яглута|Boss|Any Biome\nAspect_SeekerQueen|Aspect of the Crawling Matriarch|Аспект Королевы|Boss|Any Biome\nAspect_Fader|Aspect of the Emerald Flame|Аспект Прародителя|Boss|Any Biome\nAspect_TentaRoot|Aspect of the Tentaroot|Аспект тентакорня|Boss|Any Biome\n".Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0 || text.StartsWith("#", StringComparison.Ordinal)) { continue; } string[] array2 = text.Split('|'); if (array2.Length >= 5) { CreatureCategory category = CreatureCategory.Regular; if (array2[3].Equals("Boss", StringComparison.OrdinalIgnoreCase)) { category = CreatureCategory.Boss; } dictionary[array2[0].Trim()] = new CreatureMetadata(array2[1].Trim(), array2[2].Trim(), category, array2[4].Trim()); } } return dictionary; } public static bool TryGet(string prefabName, out CreatureMetadata metadata) { return Metadata.TryGetValue(prefabName ?? string.Empty, out metadata); } } [BepInPlugin("com.supernova.valheimcreaturespawner", "Valheim Creature Spawner", "0.2.2")] public sealed class CreatureSpawnerPlugin : BaseUnityPlugin { private sealed class CreatureEntry { public readonly GameObject Prefab; public readonly string PrefabName; public readonly string EnglishName; public readonly string RussianName; public readonly string LocalizedName; public readonly CreatureCategory Category; public readonly string[] Biomes; public string CategoryLabel { get { if (Category != CreatureCategory.Boss) { return "Regular"; } return "Boss"; } } public string BiomeLabel { get { if (Biomes != null && Biomes.Length != 0) { return string.Join(", ", Biomes); } return "Unknown"; } } public CreatureEntry(GameObject prefab, string prefabName, string englishName, string russianName, string localizedName, CreatureCategory category, string[] biomes) { Prefab = prefab; PrefabName = prefabName ?? string.Empty; EnglishName = (string.IsNullOrWhiteSpace(englishName) ? PrefabName : englishName); RussianName = (string.IsNullOrWhiteSpace(russianName) ? PrefabName : russianName); LocalizedName = localizedName ?? string.Empty; Category = category; Biomes = biomes ?? new string[1] { "Unknown" }; } } public const string PluginGuid = "com.supernova.valheimcreaturespawner"; public const string PluginName = "Valheim Creature Spawner"; public const string PluginVersion = "0.2.2"; private ConfigEntry<KeyCode> _toggleKey; private ConfigEntry<KeyCode> _spawnFrontKey; private ConfigEntry<KeyCode> _spawnAimKey; private ConfigEntry<int> _defaultCount; private ConfigEntry<int> _defaultLevel; private Harmony _harmony; private static CreatureSpawnerPlugin _activeInstance; private float _suppressInputUntil; private readonly List<CreatureEntry> _entries = new List<CreatureEntry>(); private readonly List<CreatureEntry> _filtered = new List<CreatureEntry>(); private readonly string[] _biomeOptions = new string[14] { "All Biomes", "Meadows", "Black Forest", "Swamp", "Mountains", "Plains", "Ocean", "Rivers", "Mistlands", "Ashlands", "Deep North", "Mountain Caves", "Any Biome", "Unknown" }; private Rect _windowRect = new Rect(30f, 35f, 840f, 720f); private Vector2 _listScroll; private bool _isOpen; private bool _searchHasFocus; private bool _nameHasFocus; private bool _confirmKillAll; private float _confirmKillAllUntil; private bool _cursorStateStored; private bool _oldCursorVisible; private CursorLockMode _oldCursorLockState; private bool _catalogReady; private float _nextRefresh; private string _search = string.Empty; private string _customName = string.Empty; private string _status = "Enter a world to load the creature catalogue."; private int _categoryFilter; private int _biomeFilter; private int _count = 1; private int _level = 1; private CreatureEntry _selected; private Type _characterType; private Type _zNetSceneType; private Type _zNetType; private Type _playerType; private Type _zNetViewType; private Component _playerComponent; private object _zNetSceneInstance; private object _lastCatalogScene; private object _zNetInstance; private void Awake() { //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) _toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "ToggleHUD", (KeyCode)287, "Open or close the creature spawner HUD."); _spawnFrontKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "SpawnInFront", (KeyCode)288, "Spawn the selected creature in front of the player."); _spawnAimKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "SpawnAtCrosshair", (KeyCode)289, "Spawn the selected creature at the crosshair target."); _defaultCount = ((BaseUnityPlugin)this).Config.Bind<int>("Spawner", "DefaultCount", 1, "Number of creatures to spawn (1–50)."); _defaultLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Spawner", "DefaultLevel", 1, "Level: 1 = 0 stars, 2 = 1 star, 3 = 2 stars."); _count = Mathf.Clamp(_defaultCount.Value, 1, 50); _level = Mathf.Clamp(_defaultLevel.Value, 1, 3); _characterType = FindType("Character"); _zNetSceneType = FindType("ZNetScene"); _zNetType = FindType("ZNet"); _playerType = FindType("Player"); _zNetViewType = FindType("ZNetView"); _activeInstance = this; InstallInputGuards(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Valheim Creature Spawner loaded. Press " + ((object)_toggleKey.Value/*cast due to .constrained prefix*/).ToString() + " to open HUD.")); ((BaseUnityPlugin)this).Logger.LogInfo((object)"The catalogue is discovered from the active ZNetScene; known creatures use English display names, Russian search aliases, and curated biome/category metadata."); } private void Update() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (_toggleKey != null && (int)_toggleKey.Value != 0 && Input.GetKeyDown(_toggleKey.Value)) { SetOpen(!_isOpen); } if (_confirmKillAll && Time.unscaledTime > _confirmKillAllUntil) { _confirmKillAll = false; } if (_isOpen) { if (Input.GetKeyDown((KeyCode)27)) { SetOpen(open: false); return; } if (!_searchHasFocus && !_nameHasFocus && (int)_spawnFrontKey.Value != 0 && Input.GetKeyDown(_spawnFrontKey.Value)) { SpawnSelected(atCrosshair: false); } if (!_searchHasFocus && !_nameHasFocus && (int)_spawnAimKey.Value != 0 && Input.GetKeyDown(_spawnAimKey.Value)) { SpawnSelected(atCrosshair: true); } } if (Time.unscaledTime >= _nextRefresh) { _nextRefresh = Time.unscaledTime + 4f; RefreshGameReferences(); if (!_catalogReady && _zNetSceneInstance != null) { RefreshCatalogue(); } } } private void LateUpdate() { if (_isOpen) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } } private void OnGUI() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) if (_isOpen) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; float num = Mathf.Max(620f, (float)Screen.width - 20f); float num2 = Mathf.Max(480f, (float)Screen.height - 20f); ((Rect)(ref _windowRect)).width = Mathf.Min(((Rect)(ref _windowRect)).width, num); ((Rect)(ref _windowRect)).height = Mathf.Min(((Rect)(ref _windowRect)).height, num2); ((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _windowRect)).width)); ((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _windowRect)).height)); _windowRect = GUI.Window(731906, _windowRect, new WindowFunction(DrawWindow), "CREATURE SPAWNER · SuperNova"); } } private void DrawWindow(int windowId) { //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_0691: Unknown result type (might be due to invalid IL or missing references) //IL_06a7: Unknown result type (might be due to invalid IL or missing references) //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Label("Search by English name, Russian name, or prefab ID.", Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(62f) }); GUI.SetNextControlName("CreatureSpawner.Search"); _search = GUILayout.TextField(_search, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(220f), GUILayout.ExpandWidth(true) }); _searchHasFocus = GUI.GetNameOfFocusedControl() == "CreatureSpawner.Search"; if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { _search = string.Empty; GUI.FocusControl("CreatureSpawner.Search"); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); DrawCategoryButton("All", 0); DrawCategoryButton("Regular", 1); DrawCategoryButton("Bosses", 2); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Biome:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }); if (GUILayout.Button("◀", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _biomeFilter = (_biomeFilter - 1 + _biomeOptions.Length) % _biomeOptions.Length; } GUILayout.Label(_biomeOptions[_biomeFilter], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) }); if (GUILayout.Button("▶", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _biomeFilter = (_biomeFilter + 1) % _biomeOptions.Length; } GUILayout.Label("Found: " + BuildFilteredList(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); GUILayout.Space(5f); _listScroll = GUILayout.BeginScrollView(_listScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); _filtered.Clear(); for (int i = 0; i < _entries.Count; i++) { CreatureEntry creatureEntry = _entries[i]; if (MatchesFilters(creatureEntry)) { _filtered.Add(creatureEntry); GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>()); if (GUILayout.Button(creatureEntry.EnglishName + " · " + creatureEntry.PrefabName, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(280f), GUILayout.ExpandWidth(true) })) { _selected = creatureEntry; } GUILayout.Label(creatureEntry.CategoryLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); GUILayout.Label(creatureEntry.BiomeLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }); GUILayout.EndHorizontal(); if (_selected == creatureEntry) { GUILayout.Label("Prefab: " + creatureEntry.PrefabName, Array.Empty<GUILayoutOption>()); } } } GUILayout.EndScrollView(); GUILayout.Space(5f); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>()); if (_selected == null) { GUILayout.Label("Select a creature from the list above.", Array.Empty<GUILayoutOption>()); } else { GUILayout.Label("Selected: " + _selected.EnglishName, Array.Empty<GUILayoutOption>()); GUILayout.Label("Prefab ID: " + _selected.PrefabName, Array.Empty<GUILayoutOption>()); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Custom name (optional):", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(205f) }); GUI.SetNextControlName("CreatureSpawner.CustomName"); _customName = GUILayout.TextField(_customName, 48, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(220f), GUILayout.ExpandWidth(true) }); _nameHasFocus = GUI.GetNameOfFocusedControl() == "CreatureSpawner.CustomName"; if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { _customName = string.Empty; GUI.FocusControl("CreatureSpawner.CustomName"); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Count:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(98f) }); if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _count = Mathf.Max(1, _count - 1); } GUILayout.Label(_count.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _count = Mathf.Min(50, _count + 1); } GUILayout.Space(18f); GUILayout.Label("Level / stars:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) }); if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _level = Mathf.Max(1, _level - 1); } GUILayout.Label(_level + " (" + (_level - 1) + "★)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _level = Mathf.Min(3, _level + 1); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.enabled = _selected != null; if (GUILayout.Button("Spawn in front [" + ((object)_spawnFrontKey.Value/*cast due to .constrained prefix*/).ToString() + "]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) })) { SpawnSelected(atCrosshair: false); } if (GUILayout.Button("Spawn at crosshair [" + ((object)_spawnAimKey.Value/*cast due to .constrained prefix*/).ToString() + "]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) })) { SpawnSelected(atCrosshair: true); } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.Space(4f); if (!_confirmKillAll) { Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(0.62f, 0.24f, 0.2f, 1f); if (GUILayout.Button("Kill all nearby creatures [killall]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) })) { _confirmKillAll = true; _confirmKillAllUntil = Time.unscaledTime + 8f; } GUI.backgroundColor = backgroundColor; } else { GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>()); GUILayout.Label("Kill all nearby creatures, including tamed ones? Players are not affected.", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("Confirm", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(100f), GUILayout.Height(30f) })) { _confirmKillAll = false; KillNearbyCreatures(); } if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(75f), GUILayout.Height(30f) })) { _confirmKillAll = false; } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.Label(_status, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Label("F6: close HUD · F7: spawn in front · F8: spawn at crosshair. Player controls are disabled while the HUD is open.", Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 24f)); } private void DrawCategoryButton(string title, int value) { if (GUILayout.Button((_categoryFilter == value) ? ("[ " + title + " ]") : title, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) })) { _categoryFilter = value; } } private bool MatchesFilters(CreatureEntry entry) { if (_categoryFilter == 1 && entry.Category != CreatureCategory.Regular) { return false; } if (_categoryFilter == 2 && entry.Category != CreatureCategory.Boss) { return false; } string text = _biomeOptions[_biomeFilter]; if (text != "All Biomes") { bool flag = false; for (int i = 0; i < entry.Biomes.Length; i++) { if (entry.Biomes[i].Equals(text, StringComparison.OrdinalIgnoreCase)) { flag = true; break; } } if (!flag) { return false; } } if (string.IsNullOrWhiteSpace(_search)) { return true; } string needle = _search.Trim(); if (!ContainsIgnoreCase(entry.PrefabName, needle) && !ContainsIgnoreCase(entry.EnglishName, needle) && !ContainsIgnoreCase(entry.RussianName, needle)) { return ContainsIgnoreCase(entry.LocalizedName, needle); } return true; } private static bool ContainsIgnoreCase(string haystack, string needle) { if (!string.IsNullOrEmpty(haystack)) { return haystack.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private int BuildFilteredList() { int num = 0; for (int i = 0; i < _entries.Count; i++) { if (MatchesFiltersWithoutCount(_entries[i])) { num++; } } return num; } private bool MatchesFiltersWithoutCount(CreatureEntry entry) { if (_categoryFilter == 1 && entry.Category != CreatureCategory.Regular) { return false; } if (_categoryFilter == 2 && entry.Category != CreatureCategory.Boss) { return false; } string text = _biomeOptions[_biomeFilter]; if (text != "All Biomes") { bool flag = false; for (int i = 0; i < entry.Biomes.Length; i++) { if (string.Equals(entry.Biomes[i], text, StringComparison.OrdinalIgnoreCase)) { flag = true; break; } } if (!flag) { return false; } } if (string.IsNullOrWhiteSpace(_search)) { return true; } if (!ContainsIgnoreCase(entry.PrefabName, _search) && !ContainsIgnoreCase(entry.EnglishName, _search) && !ContainsIgnoreCase(entry.RussianName, _search)) { return ContainsIgnoreCase(entry.LocalizedName, _search); } return true; } private void SetOpen(bool open) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) if (_isOpen == open) { return; } _isOpen = open; _nameHasFocus = false; _searchHasFocus = false; if (open) { _cursorStateStored = true; _oldCursorVisible = Cursor.visible; _oldCursorLockState = Cursor.lockState; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; ((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _windowRect)).width)); ((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _windowRect)).height)); RefreshGameReferences(); if (_zNetSceneInstance != null && !_catalogReady) { RefreshCatalogue(); } } else { _searchHasFocus = false; _confirmKillAll = false; _suppressInputUntil = Time.unscaledTime + 0.15f; if (_cursorStateStored) { Cursor.visible = _oldCursorVisible; Cursor.lockState = _oldCursorLockState; _cursorStateStored = false; } } } private void RefreshGameReferences() { if (_characterType == null) { _characterType = FindType("Character"); } if (_zNetSceneType == null) { _zNetSceneType = FindType("ZNetScene"); } if (_zNetType == null) { _zNetType = FindType("ZNet"); } if (_playerType == null) { _playerType = FindType("Player"); } if (_zNetViewType == null) { _zNetViewType = FindType("ZNetView"); } _zNetSceneInstance = GetSingleton(_zNetSceneType, "instance"); if (_zNetSceneInstance != _lastCatalogScene) { _lastCatalogScene = _zNetSceneInstance; _catalogReady = false; _entries.Clear(); _selected = null; } _zNetInstance = GetSingleton(_zNetType, "instance"); object singleton = GetSingleton(_playerType, "m_localPlayer"); _playerComponent = (Component)((singleton is Component) ? singleton : null); } private void RefreshCatalogue() { if (_zNetSceneInstance == null || _characterType == null) { return; } try { List<GameObject> list = ReadPrefabList(_zNetSceneInstance); if (list.Count == 0) { return; } string value = ((_selected == null) ? null : _selected.PrefabName); Dictionary<string, CreatureEntry> dictionary = new Dictionary<string, CreatureEntry>(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < list.Count; i++) { GameObject val = list[i]; if (!((Object)(object)val == (Object)null)) { Component val2 = null; try { val2 = val.GetComponent(_characterType); } catch { } CreatureMetadata metadata; bool flag = CreatureCatalog.TryGet(((Object)val).name, out metadata); if (!((Object)(object)val2 == (Object)null) || flag) { string text = (((Object)(object)val2 == (Object)null) ? ((Object)val).name : ReadLocalizedCharacterName(val2, ((Object)val).name)); string englishName = (flag ? metadata.English : ((Object)val).name); string russianName = (flag ? metadata.Russian : text); CreatureCategory category = (flag ? metadata.Category : InferCategory(((Object)val).name)); string[] biomes = (flag ? metadata.Biomes : InferBiomes(((Object)val).name)); CreatureEntry value2 = new CreatureEntry(val, ((Object)val).name, englishName, russianName, text, category, biomes); dictionary[((Object)val).name] = value2; } } } _entries.Clear(); _entries.AddRange(dictionary.Values); _entries.Sort(delegate(CreatureEntry a, CreatureEntry b) { int num2 = a.Category.CompareTo(b.Category); return (num2 != 0) ? num2 : string.Compare(a.EnglishName, b.EnglishName, StringComparison.CurrentCultureIgnoreCase); }); _selected = null; if (!string.IsNullOrEmpty(value)) { for (int num = 0; num < _entries.Count; num++) { if (_entries[num].PrefabName.Equals(value, StringComparison.OrdinalIgnoreCase)) { _selected = _entries[num]; break; } } } if (_selected == null) { _selected = ((_entries.Count > 0) ? _entries[0] : null); } _catalogReady = _entries.Count > 0; _status = (_catalogReady ? ("Catalogue loaded: " + _entries.Count + " creatures. Spawning is available to the host/server only.") : "No creatures were found in the game prefabs. Check BepInEx/LogOutput.log."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Creature catalogue refreshed: " + _entries.Count + " character prefabs available.")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Could not read the creature catalogue: " + ex)); _status = "Failed to load the catalogue. See BepInEx/LogOutput.log for details."; } } private static List<GameObject> ReadPrefabList(object sceneInstance) { List<GameObject> list = new List<GameObject>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if (sceneInstance == null) { return list; } Type type = sceneInstance.GetType(); while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { if (fields[i].Name != "m_prefabs" && fields[i].Name != "m_namedPrefabs") { continue; } object value; try { value = fields[i].GetValue(sceneInstance); } catch { continue; } if (!(value is IEnumerable enumerable)) { continue; } foreach (object item in enumerable) { GameObject val = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val == (Object)null && item != null) { PropertyInfo property = item.GetType().GetProperty("Value"); if (property != null) { try { object? value2 = property.GetValue(item, null); val = (GameObject)((value2 is GameObject) ? value2 : null); } catch { } } } if ((Object)(object)val != (Object)null && hashSet.Add(((Object)val).name)) { list.Add(val); } } } type = type.BaseType; } return list; } private static Type FindType(string typeName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { try { Type type = assemblies[i].GetType(typeName, throwOnError: false); if (type != null) { return type; } } catch { } } return null; } private static object GetSingleton(Type type, string memberName) { if (type == null) { return null; } Type type2 = type; while (type2 != null) { FieldInfo field = type2.GetField(memberName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { try { return field.GetValue(null); } catch { } } PropertyInfo property = type2.GetProperty(memberName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { try { return property.GetValue(null, null); } catch { } } type2 = type2.BaseType; } return null; } private string ReadLocalizedCharacterName(Component character, string prefabName) { string text = ReadStringMember(character, "m_name"); if (string.IsNullOrWhiteSpace(text)) { return prefabName; } if (!text.StartsWith("$", StringComparison.Ordinal)) { return text; } Type type = FindType("Localization"); object singleton = GetSingleton(type, "instance"); if (singleton != null) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { ParameterInfo[] parameters = methods[i].GetParameters(); if (!(methods[i].Name == "Localize") || parameters.Length != 1 || !(parameters[0].ParameterType == typeof(string))) { continue; } try { string text2 = methods[i].Invoke(singleton, new object[1] { text }) as string; if (!string.IsNullOrWhiteSpace(text2) && text2[0] != '$') { return text2; } } catch { } } } return text.Substring(1).Replace('_', ' '); } private static string ReadStringMember(object instance, string name) { if (instance == null) { return null; } Type type = instance.GetType(); while (type != null) { FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { try { return field.GetValue(instance) as string; } catch { } } PropertyInfo property = type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { try { return property.GetValue(instance, null) as string; } catch { } } type = type.BaseType; } return null; } private static CreatureCategory InferCategory(string prefabName) { string text = (prefabName ?? string.Empty).ToLowerInvariant(); if (text.Contains("eikthyr") || text.Contains("gd_king") || text.Contains("bonemass") || text.Contains("dragon") || text.Contains("goblinking") || text.Contains("seekerqueen") || text.Contains("fader") || text.Contains("frozenking") || text.Contains("kallfimbulbringer")) { return CreatureCategory.Boss; } if (text.Contains("brenna") || text.Contains("geirrhafa") || text == "zil" || text == "thungr" || text.Contains("dyrnwyn")) { return CreatureCategory.Boss; } return CreatureCategory.Regular; } private static string[] InferBiomes(string prefabName) { string text = (prefabName ?? string.Empty).ToLowerInvariant(); if (!text.Contains("ash") && !text.Contains("charred") && !text.Contains("morgan") && !text.Contains("volture")) { if (!text.Contains("deepnorth") && !text.Contains("frost") && !text.Contains("jotun") && !text.Contains("moose") && !text.Contains("seal") && !text.Contains("frysling")) { if (!text.Contains("seeker") && !text.Contains("tick") && !text.Contains("gjall") && !text.Contains("hare") && !text.Contains("dverger") && !text.Contains("dvergr")) { if (!text.Contains("fuling") && !text.Contains("goblin") && !text.Contains("lox") && !text.Contains("deathsquito") && !text.Contains("tar")) { if (!text.Contains("draugr") && !text.Contains("blob") && !text.Contains("leech") && !text.Contains("wraith") && !text.Contains("abomination")) { if (!text.Contains("wolf") && !text.Contains("fenring") && !text.Contains("drake") && !text.Contains("hatchling") && !text.Contains("golem") && !text.Contains("cultist") && !text.Contains("ulv") && !text.Contains("bat")) { if (!text.Contains("greydwarf") && !text.Contains("troll") && !text.Contains("skeleton") && !text.Contains("ghost") && !text.Contains("brenna")) { if (!text.Contains("serpent") && !text.Contains("fish") && !text.Contains("gull") && !text.Contains("leviathan")) { if (!text.Contains("boar") && !text.Contains("deer") && !text.Contains("neck") && !text.Contains("greyling") && !text.Contains("eikthyr")) { return new string[1] { "Unknown" }; } return new string[1] { "Meadows" }; } return new string[1] { "Ocean" }; } return new string[1] { "Black Forest" }; } return new string[1] { "Mountains" }; } return new string[1] { "Swamp" }; } return new string[1] { "Plains" }; } return new string[1] { "Mistlands" }; } return new string[1] { "Deep North" }; } return new string[1] { "Ashlands" }; } private void SpawnSelected(bool atCrosshair) { //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) if (_selected == null || (Object)(object)_selected.Prefab == (Object)null) { _status = "Select a creature first."; return; } RefreshGameReferences(); if (_selected == null || (Object)(object)_selected.Prefab == (Object)null) { if (_zNetSceneInstance != null) { RefreshCatalogue(); } _status = "The catalogue was refreshed. Select the creature again."; return; } if ((Object)(object)_playerComponent == (Object)null) { _status = "Player not found. Enter a world before spawning creatures."; return; } if (_zNetSceneInstance == null) { _status = "The network scene is not ready yet. Try again in a few seconds."; return; } if (!IsServer()) { _status = "Only the host/server can spawn networked creatures. Run this action as the host."; return; } Vector3 position; Quaternion val; if (atCrosshair) { if (!TryGetCrosshairPosition(out position)) { _status = "The crosshair is not pointing at a surface. Aim at the ground or an object and try again."; return; } val = Quaternion.identity; } else { Transform transform = _playerComponent.transform; Vector3 val2 = transform.position + transform.forward * 3f; RaycastHit val3 = default(RaycastHit); position = ((!Physics.Raycast(new Ray(val2 + Vector3.up * 12f, Vector3.down), ref val3, 40f)) ? (val2 + Vector3.up * 0.5f) : (((RaycastHit)(ref val3)).point + Vector3.up * 0.12f)); val = Quaternion.Euler(0f, transform.eulerAngles.y, 0f); } int num = 0; bool flag = false; bool flag2 = false; bool flag3 = false; string text = (_customName ?? string.Empty).Trim(); if (text.Length > 40) { text = text.Substring(0, 40); } string prefabName = _selected.PrefabName; GameObject prefab = _selected.Prefab; int level = _level; for (int i = 0; i < _count; i++) { Vector3 val4 = position + GetSpawnOffset(i); try { GameObject val5 = Object.Instantiate<GameObject>(prefab, val4, val); if (!((Object)(object)val5 == (Object)null)) { if (_zNetViewType != null && (Object)(object)val5.GetComponent(_zNetViewType) == (Object)null) { flag = true; } if (!ApplyLevel(val5, level)) { flag2 = true; } if (!string.IsNullOrWhiteSpace(text) && !ApplyCustomName(val5, text)) { flag3 = true; } num++; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to spawn " + prefabName + ": " + ex)); } } if (num == 0) { _status = "Failed to spawn the creature. See BepInEx/LogOutput.log for details."; } else if (flag) { _status = "Spawned " + prefabName + " × " + num + ". This prefab has no ZNetView, so synchronization with other players is not guaranteed."; } else if (flag2 && flag3) { _status = "Spawned " + num + " creature(s). Some do not support custom levels or names."; } else if (flag3) { _status = "Spawned " + num + " creature(s), but the custom name could not be applied to every instance of this type."; } else if (flag2) { _status = "Spawned: " + _selected.EnglishName + " × " + num + ". Some instances do not support level/star settings."; } else { _status = "Spawned: " + (string.IsNullOrWhiteSpace(text) ? _selected.EnglishName : text) + " × " + num + ", level " + level + " (" + (level - 1) + "★)."; } } private void KillNearbyCreatures() { RefreshGameReferences(); if ((Object)(object)_playerComponent == (Object)null) { _status = "Player not found. Enter a world before using killall."; return; } if (!IsServer()) { _status = "Only the host/server can kill creatures. Run this action as the host."; return; } if (_characterType == null) { _characterType = FindType("Character"); } if (_characterType == null) { _status = "The game Character type was not found. See BepInEx/LogOutput.log for details."; return; } try { MethodInfo method = _characterType.GetMethod("GetAllCharacters", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method == null) { _status = "Character.GetAllCharacters() was not found in this game version."; return; } if (!(method.Invoke(null, null) is IEnumerable enumerable)) { _status = "Could not retrieve the creatures from the current game scene."; return; } List<object> list = new List<object>(); foreach (object item in enumerable) { if (item != null) { list.Add(item); } } MethodInfo methodInfo = null; MethodInfo[] methods = _characterType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { if (!(methods[i].Name != "Damage")) { ParameterInfo[] parameters = methods[i].GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.Name == "HitData") { methodInfo = methods[i]; break; } } } if (methodInfo == null) { _status = "Character.Damage(HitData) was not found in this game version."; return; } Type parameterType = methodInfo.GetParameters()[0].ParameterType; int num = 0; int num2 = 0; for (int j = 0; j < list.Count; j++) { object obj = list[j]; Component val = (Component)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null || !TryReadBooleanMethod(obj, "IsPlayer", out var value) || value) { continue; } try { object obj2 = CreateLethalHitData(parameterType); if (obj2 == null) { _status = "Could not prepare HitData to apply damage."; return; } methodInfo.Invoke(obj, new object[1] { obj2 }); num++; } catch (Exception ex) { num2++; ((BaseUnityPlugin)this).Logger.LogDebug((object)("killall could not damage " + ((Object)val).name + ": " + ex.Message)); } } _status = "killall complete: lethal damage applied to " + num + " creature(s)" + ((num2 > 0) ? ("; errors: " + num2) : string.Empty) + ". Players were not affected; tamed creatures were included."; } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to run Creature Spawner killall: " + ex2)); _status = "Failed to execute killall. See BepInEx/LogOutput.log for details."; } } private static bool TryReadBooleanMethod(object instance, string methodName, out bool value) { value = false; if (instance == null) { return false; } MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method == null || method.ReturnType != typeof(bool)) { return false; } try { value = Convert.ToBoolean(method.Invoke(instance, null)); return true; } catch { return false; } } private static object CreateLethalHitData(Type hitDataType) { if (hitDataType == null) { return null; } try { return Activator.CreateInstance(hitDataType, 1E+10f); } catch { } object obj2; try { obj2 = Activator.CreateInstance(hitDataType, nonPublic: true); } catch { return null; } if (obj2 == null) { return null; } FieldInfo field = hitDataType.GetField("m_damage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return null; } try { object value = field.GetValue(obj2); if (value == null) { return null; } FieldInfo field2 = value.GetType().GetField("m_damage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 == null || field2.FieldType != typeof(float)) { return null; } field2.SetValue(value, 1E+10f); field.SetValue(obj2, value); return obj2; } catch { return null; } } private bool ApplyCustomName(GameObject spawnedObject, string customName) { if ((Object)(object)spawnedObject == (Object)null || string.IsNullOrWhiteSpace(customName)) { return false; } Component val = null; try { if (_characterType != null) { val = spawnedObject.GetComponent(_characterType); } } catch { } if ((Object)(object)val == (Object)null) { return false; } bool flag = false; MethodInfo[] methods = ((object)val).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { if (methods[i].Name != "SetCustomName") { continue; } ParameterInfo[] parameters = methods[i].GetParameters(); if (parameters.Length == 1 && !(parameters[0].ParameterType != typeof(string))) { try { methods[i].Invoke(val, new object[1] { customName }); flag = true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Character.SetCustomName failed: " + ex.Message)); continue; } break; } } try { Component val2 = ((_zNetViewType == null) ? null : spawnedObject.GetComponent(_zNetViewType)); if ((Object)(object)val2 != (Object)null) { MethodInfo method = ((object)val2).GetType().GetMethod("GetZDO", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); object obj2 = ((method == null) ? null : method.Invoke(val2, null)); if (obj2 != null) { MethodInfo[] methods2 = obj2.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int j = 0; j < methods2.Length; j++) { ParameterInfo[] parameters2 = methods2[j].GetParameters(); if (!(methods2[j].Name != "Set") && parameters2.Length == 2 && !(parameters2[0].ParameterType != typeof(string)) && !(parameters2[1].ParameterType != typeof(string))) { try { methods2[j].Invoke(obj2, new object[2] { "customName", customName }); flag = true; } catch { } try { methods2[j].Invoke(obj2, new object[2] { "VCS_CustomName", customName }); flag = true; } catch { } if (flag) { break; } } } } } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not store custom name in ZDO: " + ex2.Message)); } flag |= TrySetStringMember(val, "m_customName", customName); return flag | TrySetStringMember(val, "m_name", customName); } private static bool TrySetStringMember(object instance, string memberName, string value) { if (instance == null) { return false; } Type type = instance.GetType(); while (type != null) { FieldInfo field = type.GetField(memberName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(string)) { try { field.SetValue(instance, value); return true; } catch { } } PropertyInfo property = type.GetProperty(memberName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(string) && property.CanWrite) { try { property.SetValue(instance, value, null); return true; } catch { } } type = type.BaseType; } return false; } private bool IsServer() { if (_zNetInstance == null) { return false; } MethodInfo method = _zNetInstance.GetType().GetMethod("IsServer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method == null) { return false; } try { return Convert.ToBoolean(method.Invoke(_zNetInstance, null)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not determine server authority: " + ex.Message)); return false; } } private static Vector3 GetSpawnOffset(int index) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (index == 0) { return Vector3.zero; } float num = (float)index * 2.3999631f; float num2 = 1.1f * Mathf.Sqrt((float)index); return new Vector3(Mathf.Cos(num) * num2, 0f, Mathf.Sin(num) * num2); } private bool TryGetCrosshairPosition(out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return false; } RaycastHit[] array = Physics.RaycastAll(main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f)), 250f); Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); Transform val = (((Object)(object)_playerComponent == (Object)null) ? null : _playerComponent.transform); for (int num = 0; num < array.Length; num++) { if (!((Object)(object)((RaycastHit)(ref array[num])).collider == (Object)null) && (!((Object)(object)val != (Object)null) || (!((Object)(object)((Component)((RaycastHit)(ref array[num])).collider).transform == (Object)(object)val) && !((Component)((RaycastHit)(ref array[num])).collider).transform.IsChildOf(val)))) { position = ((RaycastHit)(ref array[num])).point + ((RaycastHit)(ref array[num])).normal * 0.12f; return true; } } return false; } private bool ApplyLevel(GameObject spawnedObject, int level) { if ((Object)(object)spawnedObject == (Object)null || _characterType == null) { return false; } Component val = null; try { val = spawnedObject.GetComponent(_characterType); } catch { } if ((Object)(object)val == (Object)null) { return false; } MethodInfo[] methods = ((object)val).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { ParameterInfo[] parameters = methods[i].GetParameters(); if (methods[i].Name != "SetLevel" || parameters.Length < 1 || parameters[0].ParameterType != typeof(int)) { continue; } object[] array = new object[parameters.Length]; array[0] = level; bool flag = true; for (int j = 1; j < parameters.Length; j++) { if (!parameters[j].IsOptional) { flag = false; break; } array[j] = parameters[j].DefaultValue; } if (flag) { try { methods[i].Invoke(val, array); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not apply creature level: " + ex.Message)); return false; } } } return false; } private void InstallInputGuards() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Expected O, but got Unknown //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown try { _harmony = new Harmony("com.supernova.valheimcreaturespawner.InputGuard"); Type type = FindType("ZInput"); if (type != null) { MethodInfo method = typeof(CreatureSpawnerPlugin).GetMethod("BlockBooleanInputPrefix", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.ReturnType != typeof(bool)) { continue; } string name = methodInfo.Name; ParameterInfo[] parameters = methodInfo.GetParameters(); bool flag = false; switch (name) { case "GetButton": case "GetButtonDown": case "GetButtonUp": flag = parameters.Length == 1 && parameters[0].ParameterType == typeof(string); break; case "GetMouseButton": case "GetMouseButtonDown": case "GetMouseButtonUp": flag = parameters.Length == 1 && parameters[0].ParameterType == typeof(int); break; case "GetKey": case "GetKeyDown": case "GetKeyUp": flag = parameters.Length >= 1 && parameters.Length <= 2 && parameters[0].ParameterType == typeof(KeyCode) && (parameters.Length == 1 || parameters[1].ParameterType == typeof(bool)); break; } if (flag) { try { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not guard " + methodInfo.Name + ": " + ex.Message)); } } } } MethodInfo method2 = typeof(CreatureSpawnerPlugin).GetMethod("BlockMouseScrollWheelPrefix", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array = (type ?? FindType("ZInput"))?.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (array != null) { foreach (MethodInfo methodInfo2 in array) { if (!(methodInfo2.Name != "GetMouseScrollWheel") && !(methodInfo2.ReturnType != typeof(float)) && methodInfo2.GetParameters().Length == 0) { try { _harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Mouse wheel input guard installed for the open spawner HUD."); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not guard camera zoom scroll input: " + ex2.Message)); } } } } PatchBooleanInputMethod(FindType("Player"), "TakeInput"); PatchBooleanInputMethod(FindType("PlayerController"), "TakeInput"); Type type2 = FindType("Character"); if (type2 != null) { MethodInfo method3 = type2.GetMethod("GetHoverName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method3 != null && method3.ReturnType == typeof(string)) { MethodInfo method4 = typeof(CreatureSpawnerPlugin).GetMethod("OverrideCustomNamePostfix", BindingFlags.Static | BindingFlags.NonPublic); try { _harmony.Patch((MethodBase)method3, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not install custom-name display patch: " + ex3.Message)); } } } Type type3 = FindType("GameCamera"); if (!(type3 != null)) { return; } MethodInfo method5 = typeof(CreatureSpawnerPlugin).GetMethod("BlockCameraMouseCapturePrefix", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] methods2 = type3.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int k = 0; k < methods2.Length; k++) { if (!(methods2[k].Name != "UpdateMouseCapture") && methods2[k].GetParameters().Length == 0) { try { _harmony.Patch((MethodBase)methods2[k], new HarmonyMethod(method5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex4) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not guard camera cursor capture: " + ex4.Message)); } } } } catch (Exception ex5) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Some input guards could not be installed. Cursor forcing remains active. " + ex5.Message)); } } private void PatchBooleanInputMethod(Type type, string name) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown if (type == null) { return; } MethodInfo method = typeof(CreatureSpawnerPlugin).GetMethod("BlockBooleanInputPrefix", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { if (!(methods[i].Name != name) && !(methods[i].ReturnType != typeof(bool))) { try { _harmony.Patch((MethodBase)methods[i], new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Could not block " + type.Name + "." + name + ": " + ex.Message)); } } } } private static bool ShouldBlockGameInput() { if ((Object)(object)_activeInstance != (Object)null) { if (!_activeInstance._isOpen) { return Time.unscaledTime < _activeInstance._suppressInputUntil; } return true; } return false; } private static bool BlockBooleanInputPrefix(ref bool __result) { if (!ShouldBlockGameInput()) { return true; } __result = false; return false; } private static bool BlockCameraMouseCapturePrefix() { return !ShouldBlockGameInput(); } private static bool BlockMouseScrollWheelPrefix(ref float __result) { if (!ShouldBlockGameInput()) { return true; } __result = 0f; return false; } private static void OverrideCustomNamePostfix(object __instance, ref string __result) { CreatureSpawnerPlugin activeInstance = _activeInstance; Component val = (Component)((__instance is Component) ? __instance : null); if ((Object)(object)activeInstance == (Object)null || (Object)(object)val == (Object)null || activeInstance._zNetViewType == null) { return; } try { Component component = val.GetComponent(activeInstance._zNetViewType); if ((Object)(object)component == (Object)null) { return; } MethodInfo method = ((object)component).GetType().GetMethod("GetZDO", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); object obj = ((method == null) ? null : method.Invoke(component, null)); if (obj == null) { return; } MethodInfo[] methods = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { if (methods[i].Name != "GetString") { continue; } ParameterInfo[] parameters = methods[i].GetParameters(); object obj2 = null; try { if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string)) { obj2 = methods[i].Invoke(obj, new object[1] { "VCS_CustomName" }); } else if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string)) { obj2 = methods[i].Invoke(obj, new object[2] { "VCS_CustomName", string.Empty }); } } catch { } string text = obj2 as string; if (!string.IsNullOrWhiteSpace(text)) { __result = text; break; } } } catch (Exception ex) { if ((Object)(object)activeInstance != (Object)null) { ((BaseUnityPlugin)activeInstance).Logger.LogDebug((object)("Could not read custom creature name: " + ex.Message)); } } } private void OnDestroy() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (_harmony != null) { try { _harmony.UnpatchSelf(); } catch { } _harmony = null; } if (_activeInstance == this) { _activeInstance = null; } if (_cursorStateStored) { Cursor.visible = _oldCursorVisible; Cursor.lockState = _oldCursorLockState; _cursorStateStored = false; } } } }