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 LethalBattleTweaks v1.0.2
LethalBattleTweaks.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CombatSharedFeatures; using GameNetcodeStuff; using HarmonyLib; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LethalBattleTweaks")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("lengjing")] [assembly: AssemblyProduct("LethalBattleTweaks")] [assembly: AssemblyCopyright("Copyright © lengjing 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8e5a2c62-6a18-4f9e-8948-596a50b89631")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.2.0")] namespace CombatSharedFeatures { public static class PublicFeatureConfig { public static ConfigEntry<bool> RefillEnabled { get; private set; } public static ConfigEntry<float> RefillInterval { get; private set; } public static ConfigEntry<int> RefillTotalCap { get; private set; } public static ConfigEntry<int> RefillDelay { get; private set; } public static ConfigEntry<float> SpawnDelay { get; private set; } public static ConfigEntry<int> RefillBatchSize { get; private set; } public static ConfigEntry<int> RefillFlowermanInit { get; private set; } public static ConfigEntry<int> RefillFlowermanMax { get; private set; } public static ConfigEntry<int> RefillFlowermanWeight { get; private set; } public static ConfigEntry<int> RefillNutcrackerInit { get; private set; } public static ConfigEntry<int> RefillNutcrackerMax { get; private set; } public static ConfigEntry<int> RefillNutcrackerWeight { get; private set; } public static ConfigEntry<int> RefillCrawlerInit { get; private set; } public static ConfigEntry<int> RefillCrawlerMax { get; private set; } public static ConfigEntry<int> RefillCrawlerWeight { get; private set; } public static ConfigEntry<int> RefillCentipedeInit { get; private set; } public static ConfigEntry<int> RefillCentipedeMax { get; private set; } public static ConfigEntry<int> RefillCentipedeWeight { get; private set; } public static ConfigEntry<int> RefillHoarderBugInit { get; private set; } public static ConfigEntry<int> RefillHoarderBugMax { get; private set; } public static ConfigEntry<int> RefillHoarderBugWeight { get; private set; } public static ConfigEntry<int> RefillMaskedInit { get; private set; } public static ConfigEntry<int> RefillMaskedMax { get; private set; } public static ConfigEntry<int> RefillMaskedWeight { get; private set; } public static ConfigEntry<int> RefillSandSpiderInit { get; private set; } public static ConfigEntry<int> RefillSandSpiderMax { get; private set; } public static ConfigEntry<int> RefillSandSpiderWeight { get; private set; } public static ConfigEntry<int> RefillButlerInit { get; private set; } public static ConfigEntry<int> RefillButlerMax { get; private set; } public static ConfigEntry<int> RefillButlerWeight { get; private set; } public static ConfigEntry<int> RefillStingrayInit { get; private set; } public static ConfigEntry<int> RefillStingrayMax { get; private set; } public static ConfigEntry<int> RefillStingrayWeight { get; private set; } public static ConfigEntry<int> StartingCredits { get; private set; } public static ConfigEntry<bool> DisableHazards { get; private set; } public static ConfigEntry<bool> DisableVanillaEnemies { get; private set; } public static ConfigEntry<bool> DisableScrap { get; private set; } public static ConfigEntry<bool> NoLockedDoors { get; private set; } public static ConfigEntry<bool> DisableFriendlyMeleeDamage { get; private set; } public static ConfigEntry<bool> ButlerInstantOpenDoors { get; private set; } public static ConfigEntry<bool> NutcrackerNoFriendlyFire { get; private set; } public static ConfigEntry<bool> NutcrackerDropGunAndShells { get; private set; } public static ConfigEntry<bool> ButlerDropKnifeAndBees { get; private set; } public static ConfigEntry<bool> TZPHealingEnabled { get; private set; } public static ConfigEntry<int> TZPHealAmount { get; private set; } public static ConfigEntry<bool> LootDropsEnabled { get; private set; } public static ConfigEntry<float> TZPDropChance { get; private set; } public static ConfigEntry<float> StunGrenadeDropChance { get; private set; } public static ConfigEntry<bool> CorpseCleanupEnabled { get; private set; } public static ConfigEntry<float> CorpseCleanupDelay { get; private set; } private static string Bilingual(string en, string zh) { return en + " / " + zh; } public static void Bind(ConfigFile config) { string text = "Enemy Refill"; RefillEnabled = config.Bind<bool>(text, "Enabled", true, Bilingual("Enable dynamic indoor enemy refill.", "启用设施内动态补怪。")); RefillInterval = config.Bind<float>(text, "Interval", 5f, Bilingual("Seconds between refill checks.", "每次检查是否需要补怪的间隔秒数。")); RefillTotalCap = config.Bind<int>(text, "TotalCap", 18, Bilingual("Total indoor enemies the refill system tries to maintain.", "补怪系统尝试维持的设施内怪物总上限。")); RefillDelay = config.Bind<int>(text, "RefillDelay", 10, Bilingual("Delay after landing before refill starts.", "飞船落地后开始补怪前的延迟秒数。")); SpawnDelay = config.Bind<float>(text, "SpawnDelay", 0.3f, Bilingual("Delay between spawned enemies during a refill batch.", "单次补怪批次中每只怪之间的生成间隔。")); RefillBatchSize = config.Bind<int>(text, "BatchSize", 3, Bilingual("Maximum enemies spawned per refill batch.", "每次补怪批次最多生成的怪物数量。")); RefillFlowermanInit = config.Bind<int>("Enemy Refill - Flowerman", "Init", 0, Bilingual("Initial Flowerman count.", "开局额外生成的小黑数量。")); RefillFlowermanMax = config.Bind<int>("Enemy Refill - Flowerman", "Max", 1, Bilingual("Maximum Flowerman refill count.", "小黑可被补怪到的最大数量。")); RefillFlowermanWeight = config.Bind<int>("Enemy Refill - Flowerman", "Weight", 10, Bilingual("Flowerman refill weight.", "小黑的补怪权重。")); RefillNutcrackerInit = config.Bind<int>("Enemy Refill - Nutcracker", "Init", 0, Bilingual("Initial Nutcracker count.", "开局额外生成的胡桃夹子数量。")); RefillNutcrackerMax = config.Bind<int>("Enemy Refill - Nutcracker", "Max", 1, Bilingual("Maximum Nutcracker refill count.", "胡桃夹子可被补怪到的最大数量。")); RefillNutcrackerWeight = config.Bind<int>("Enemy Refill - Nutcracker", "Weight", 10, Bilingual("Nutcracker refill weight.", "胡桃夹子的补怪权重。")); RefillCrawlerInit = config.Bind<int>("Enemy Refill - Crawler", "Init", 0, Bilingual("Initial Crawler count.", "开局额外生成的半身鱼数量。")); RefillCrawlerMax = config.Bind<int>("Enemy Refill - Crawler", "Max", 1, Bilingual("Maximum Crawler refill count.", "半身鱼可被补怪到的最大数量。")); RefillCrawlerWeight = config.Bind<int>("Enemy Refill - Crawler", "Weight", 10, Bilingual("Crawler refill weight.", "半身鱼的补怪权重。")); RefillCentipedeInit = config.Bind<int>("Enemy Refill - Centipede", "Init", 0, Bilingual("Initial Centipede count.", "开局额外生成的抱脸虫数量。")); RefillCentipedeMax = config.Bind<int>("Enemy Refill - Centipede", "Max", 2, Bilingual("Maximum Centipede refill count.", "抱脸虫可被补怪到的最大数量。")); RefillCentipedeWeight = config.Bind<int>("Enemy Refill - Centipede", "Weight", 10, Bilingual("Centipede refill weight.", "抱脸虫的补怪权重。")); RefillHoarderBugInit = config.Bind<int>("Enemy Refill - HoarderBug", "Init", 0, Bilingual("Initial HoarderBug count.", "开局额外生成的囤积虫数量。")); RefillHoarderBugMax = config.Bind<int>("Enemy Refill - HoarderBug", "Max", 3, Bilingual("Maximum HoarderBug refill count.", "囤积虫可被补怪到的最大数量。")); RefillHoarderBugWeight = config.Bind<int>("Enemy Refill - HoarderBug", "Weight", 10, Bilingual("HoarderBug refill weight.", "囤积虫的补怪权重。")); RefillMaskedInit = config.Bind<int>("Enemy Refill - Masked", "Init", 0, Bilingual("Initial Masked count.", "开局额外生成的假人数量。")); RefillMaskedMax = config.Bind<int>("Enemy Refill - Masked", "Max", 1, Bilingual("Maximum Masked refill count.", "假人可被补怪到的最大数量。")); RefillMaskedWeight = config.Bind<int>("Enemy Refill - Masked", "Weight", 10, Bilingual("Masked refill weight.", "假人的补怪权重。")); RefillSandSpiderInit = config.Bind<int>("Enemy Refill - SandSpider", "Init", 0, Bilingual("Initial SandSpider count.", "开局额外生成的蜘蛛数量。")); RefillSandSpiderMax = config.Bind<int>("Enemy Refill - SandSpider", "Max", 2, Bilingual("Maximum SandSpider refill count.", "蜘蛛可被补怪到的最大数量。")); RefillSandSpiderWeight = config.Bind<int>("Enemy Refill - SandSpider", "Weight", 10, Bilingual("SandSpider refill weight.", "蜘蛛的补怪权重。")); RefillButlerInit = config.Bind<int>("Enemy Refill - Butler", "Init", 0, Bilingual("Initial Butler count.", "开局额外生成的管家数量。")); RefillButlerMax = config.Bind<int>("Enemy Refill - Butler", "Max", 2, Bilingual("Maximum Butler refill count.", "管家可被补怪到的最大数量。")); RefillButlerWeight = config.Bind<int>("Enemy Refill - Butler", "Weight", 10, Bilingual("Butler refill weight.", "管家的补怪权重。")); RefillStingrayInit = config.Bind<int>("Enemy Refill - Stingray", "Init", 0, Bilingual("Initial Stingray count.", "开局额外生成的粘滑鱼数量。")); RefillStingrayMax = config.Bind<int>("Enemy Refill - Stingray", "Max", 1, Bilingual("Maximum Stingray refill count.", "粘滑鱼可被补怪到的最大数量。")); RefillStingrayWeight = config.Bind<int>("Enemy Refill - Stingray", "Weight", 10, Bilingual("Stingray refill weight.", "粘滑鱼的补怪权重。")); StartingCredits = config.Bind<int>("World Rules", "StartingCredits", 60, Bilingual("Starting company credits.", "开局公司金钱。")); DisableHazards = config.Bind<bool>("World Rules", "DisableHazards", false, Bilingual("Disable landmines, turrets, and spikes.", "禁用地雷、炮塔和尖刺。")); DisableVanillaEnemies = config.Bind<bool>("World Rules", "DisableVanillaEnemies", false, Bilingual("Disable vanilla natural enemy spawning.", "禁用原版自然刷怪。")); DisableScrap = config.Bind<bool>("World Rules", "DisableScrap", false, Bilingual("Disable indoor scrap spawning.", "禁用室内废料刷新。")); NoLockedDoors = config.Bind<bool>("World Rules", "NoLockedDoors", true, Bilingual("Automatically unlock locked doors.", "自动解锁上锁的门。")); DisableFriendlyMeleeDamage = config.Bind<bool>("World Rules", "DisableFriendlyMeleeDamage", true, Bilingual("Disable shovel and knife friendly fire.", "禁用铲子和小刀的玩家友伤。")); ButlerInstantOpenDoors = config.Bind<bool>("World Rules", "ButlerInstantOpenDoors", true, Bilingual("Make butlers open doors almost instantly.", "让管家几乎瞬间开门。")); NutcrackerNoFriendlyFire = config.Bind<bool>("World Rules", "NutcrackerNoFriendlyFire", true, Bilingual("Prevent nutcracker shotgun blasts from damaging monsters while still allowing player damage.", "让胡桃夹子不会伤害怪物,但仍然可以伤害玩家。")); NutcrackerDropGunAndShells = config.Bind<bool>("World Rules", "NutcrackerDropGunAndShells", false, Bilingual("Allow nutcrackers to drop their shotgun and shotgun shells on death.", "允许胡桃夹子死亡时掉落枪和子弹。")); ButlerDropKnifeAndBees = config.Bind<bool>("World Rules", "ButlerDropKnifeAndBees", false, Bilingual("Allow butlers to spawn their knife and bees on death.", "允许管家死亡时掉落菜刀并生成蜜蜂。")); TZPHealingEnabled = config.Bind<bool>("TZP Healing", "Enabled", true, Bilingual("Allow TZP inhalant to heal once per canister.", "允许每罐 TZP 提供一次回血。")); TZPHealAmount = config.Bind<int>("TZP Healing", "HealAmount", 20, Bilingual("Healing amount per TZP use.", "每次 TZP 触发时的回血量。")); LootDropsEnabled = config.Bind<bool>("Loot Drops", "Enabled", true, Bilingual("Allow enemies to drop combat supplies.", "允许敌人掉落战斗补给。")); TZPDropChance = config.Bind<float>("Loot Drops", "TZPDropChance", 0.1f, Bilingual("Chance for supported enemies to drop TZP.", "支持的敌人掉落 TZP 的概率。")); StunGrenadeDropChance = config.Bind<float>("Loot Drops", "StunGrenadeDropChance", 0.05f, Bilingual("Chance for supported enemies to drop a stun grenade.", "支持的敌人掉落闪光弹的概率。")); CorpseCleanupEnabled = config.Bind<bool>("Corpse Cleanup", "Enabled", true, Bilingual("Automatically remove enemy corpses after a delay.", "延迟一段时间后自动清理怪物尸体。")); CorpseCleanupDelay = config.Bind<float>("Corpse Cleanup", "Delay", 5f, Bilingual("Delay in seconds before supported enemy corpses are removed.", "支持的怪物尸体在被清理前等待的秒数。")); } } public enum PublicFeatureMode { PublicStandalone, PrivateExtended } public static class PublicFeatureRuntime { [HarmonyPatch(typeof(StartOfRound), "StartGame")] private static class StartOfRoundStartGamePatch { [HarmonyPrefix] private static void Prefix() { if (!((Object)(object)StartOfRound.Instance == (Object)null) && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { HandleRoundStart(); } } } private static BaseUnityPlugin _plugin; private static ConfigFile _config; private static Func<EnemyAI, bool> _privateBossPredicate; private static bool _isInitialized; private static ManualLogSource _logger = Logger.CreateLogSource("PublicFeatureRuntime"); public static BaseUnityPlugin PluginInstance => _plugin; public static ManualLogSource Logger => _logger; public static PublicFeatureMode Mode { get; private set; } public static bool IsEnabled => _isInitialized; public static void Initialize(BaseUnityPlugin plugin, PublicFeatureMode mode, ManualLogSource logger) { if (!((Object)(object)_plugin == (Object)(object)plugin) || !_isInitialized) { _plugin = plugin; _config = plugin.Config; Mode = mode; _logger = logger ?? _logger; PublicFeatureConfig.Bind(_config); _config.SettingChanged += HandleConfigChanged; _isInitialized = true; } } public static void OnPluginStart() { if (_isInitialized) { PublicFeatureEnemyCatalog.CacheAllEnemyTypes(); RefillSystem.Restart(); } } public static void Shutdown() { if (_isInitialized) { RefillSystem.Stop(); if (_config != null) { _config.SettingChanged -= HandleConfigChanged; } _plugin = null; _config = null; _privateBossPredicate = null; _isInitialized = false; } } public static void HandleRoundStart() { if (_isInitialized) { PublicFeatureEnemyCatalog.CacheAllEnemyTypes(); ItemAndLootPatches.ResetRoundState(); RefillSystem.Restart(); } } public static void HandleConfigChanged(object sender, SettingChangedEventArgs e) { if (_isInitialized && e != null && e.ChangedSetting != null && (e.ChangedSetting.Definition.Section ?? string.Empty).StartsWith("Enemy Refill", StringComparison.OrdinalIgnoreCase)) { RefillSystem.Restart(); } } public static void SetPrivateBossPredicate(Func<EnemyAI, bool> predicate) { _privateBossPredicate = predicate; } public static bool IsPrivateBossEnemy(EnemyAI enemy) { if (_privateBossPredicate != null && (Object)(object)enemy != (Object)null) { return _privateBossPredicate(enemy); } return false; } } public static class PublicFeatureEnemyCatalog { private static readonly Dictionary<string, EnemyType> EnemyTypeCache = new Dictionary<string, EnemyType>(); private static readonly Dictionary<string, string> EnemyNameAliases = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "HoarderBug", "Hoarding bug" }, { "SandSpider", "Bunker Spider" }, { "Masked", "Masked" }, { "Centipede", "Centipede" }, { "Flowerman", "Flowerman" }, { "Nutcracker", "Nutcracker" }, { "Crawler", "Crawler" }, { "Butler", "Butler" }, { "Stingray", "Stingray" } }; public static int CachedEnemyCount => EnemyTypeCache.Count; public static void CacheAllEnemyTypes() { if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.levels == null) { return; } EnemyTypeCache.Clear(); SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { foreach (SpawnableEnemyWithRarity enemy in val.Enemies) { CacheEnemyType(enemy.enemyType); } foreach (SpawnableEnemyWithRarity daytimeEnemy in val.DaytimeEnemies) { CacheEnemyType(daytimeEnemy.enemyType); } foreach (SpawnableEnemyWithRarity outsideEnemy in val.OutsideEnemies) { CacheEnemyType(outsideEnemy.enemyType); } } } public static EnemyType GetEnemyTypeByName(string name) { if (string.IsNullOrEmpty(name)) { return null; } string text = name; if (EnemyNameAliases.TryGetValue(name, out var value)) { text = value; } if (EnemyTypeCache.TryGetValue(text, out var value2)) { return value2; } if (text != name && EnemyTypeCache.TryGetValue(name, out value2)) { return value2; } foreach (KeyValuePair<string, EnemyType> item in EnemyTypeCache) { if (item.Key.Equals(text, StringComparison.OrdinalIgnoreCase) || item.Key.Equals(name, StringComparison.OrdinalIgnoreCase)) { return item.Value; } } foreach (KeyValuePair<string, EnemyType> item2 in EnemyTypeCache) { if (item2.Key.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 || item2.Key.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0) { return item2.Value; } } return null; } private static void CacheEnemyType(EnemyType type) { if (!((Object)(object)type == (Object)null) && !EnemyTypeCache.ContainsKey(type.enemyName)) { EnemyTypeCache[type.enemyName] = type; } } } public static class RefillSystem { private struct MonsterConfig { public string Name; public int Init; public int Max; public int Weight; public MonsterConfig(string name, int init, int max, int weight) { Name = name; Init = init; Max = max; Weight = weight; } } [CompilerGenerated] private sealed class <CheckAndRefillEnemiesCoroutine>d__9 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private List<MonsterConfig> <monsterConfigs>5__2; private Dictionary<string, EnemyType> <configTypeMap>5__3; private Dictionary<string, int> <currentCounts>5__4; private int <toSpawn>5__5; private int <i>5__6; private MonsterConfig <selectedConfig>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckAndRefillEnemiesCoroutine>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <monsterConfigs>5__2 = null; <configTypeMap>5__3 = null; <currentCounts>5__4 = null; <selectedConfig>5__7 = default(MonsterConfig); <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <currentCounts>5__4[<selectedConfig>5__7.Name]++; goto IL_03bb; } <>1__state = -1; if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)RoundManager.Instance == (Object)null) { return false; } <monsterConfigs>5__2 = GetMonsterConfigs(); <configTypeMap>5__3 = new Dictionary<string, EnemyType>(); foreach (MonsterConfig item2 in <monsterConfigs>5__2) { <configTypeMap>5__3[item2.Name] = PublicFeatureEnemyCatalog.GetEnemyTypeByName(item2.Name); } List<EnemyAI> spawnedEnemies = RoundManager.Instance.SpawnedEnemies; int num2 = 0; <currentCounts>5__4 = new Dictionary<string, int>(); foreach (MonsterConfig item3 in <monsterConfigs>5__2) { <currentCounts>5__4[item3.Name] = 0; } for (int i = 0; i < spawnedEnemies.Count; i++) { EnemyAI val = spawnedEnemies[i]; if ((Object)(object)val == (Object)null || val.isEnemyDead) { continue; } foreach (MonsterConfig item4 in <monsterConfigs>5__2) { EnemyType val2 = <configTypeMap>5__3[item4.Name]; if ((Object)(object)val2 != (Object)null && (Object)(object)val.enemyType == (Object)(object)val2) { <currentCounts>5__4[item4.Name]++; num2++; break; } } } int num3 = PublicFeatureConfig.RefillTotalCap.Value - num2; if (num3 <= 0) { return false; } <toSpawn>5__5 = Mathf.Min(num3, PublicFeatureConfig.RefillBatchSize.Value); <i>5__6 = 0; goto IL_03d9; IL_03d9: if (<i>5__6 < <toSpawn>5__5) { RefillCandidatesBuffer.Clear(); foreach (MonsterConfig item5 in <monsterConfigs>5__2) { if (<currentCounts>5__4[item5.Name] < item5.Max && item5.Weight > 0) { float item = (float)item5.Weight / (float)(<currentCounts>5__4[item5.Name] + 1); RefillCandidatesBuffer.Add((item5, item)); } } if (RefillCandidatesBuffer.Count != 0) { float num4 = 0f; foreach (var item6 in RefillCandidatesBuffer) { num4 += item6.Score; } float num5 = Random.Range(0f, num4); <selectedConfig>5__7 = RefillCandidatesBuffer.Last().Config; float num6 = 0f; foreach (var item7 in RefillCandidatesBuffer) { num6 += item7.Score; if (num5 < num6) { (<selectedConfig>5__7, _) = item7; break; } } EnemyType val3 = <configTypeMap>5__3[<selectedConfig>5__7.Name]; if ((Object)(object)val3 != (Object)null) { <>2__current = SpawnEnemyCoroutine(val3, 1); <>1__state = 1; return true; } goto IL_03bb; } } return false; IL_03bb: <selectedConfig>5__7 = default(MonsterConfig); <i>5__6++; goto IL_03d9; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RefillEnemiesRoutine>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private float <elapsed>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RefillEnemiesRoutine>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0058; case 1: <>1__state = -1; goto IL_0058; case 2: <>1__state = -1; if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)RoundManager.Instance == (Object)null) { return false; } if (!PublicFeatureConfig.RefillEnabled.Value || !((NetworkBehaviour)RoundManager.Instance).IsHost) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 3; return true; } if (PublicFeatureEnemyCatalog.CachedEnemyCount == 0) { PublicFeatureEnemyCatalog.CacheAllEnemyTypes(); } <>2__current = SpawnInitialEnemiesCoroutine(); <>1__state = 4; return true; case 3: <>1__state = -1; goto IL_0065; case 4: <>1__state = -1; <elapsed>5__2 = 0f; goto IL_0193; case 5: <>1__state = -1; <elapsed>5__2 += 1f; goto IL_0193; case 6: <>1__state = -1; break; case 7: { <>1__state = -1; if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase) { goto IL_0065; } goto IL_0232; } IL_0193: if (<elapsed>5__2 < (float)PublicFeatureConfig.RefillDelay.Value && !((Object)(object)StartOfRound.Instance == (Object)null) && !StartOfRound.Instance.inShipPhase) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 5; return true; } if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase) { goto IL_0065; } goto IL_0232; IL_0058: if ((Object)(object)RoundManager.Instance == (Object)null) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } goto IL_0065; IL_0232: if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.inShipPhase) { if (PublicFeatureConfig.RefillEnabled.Value) { <>2__current = CheckAndRefillEnemiesCoroutine(); <>1__state = 6; return true; } break; } goto IL_0065; IL_0065: if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)RoundManager.Instance == (Object)null) { return false; } <>2__current = (object)new WaitUntil((Func<bool>)(() => (Object)(object)StartOfRound.Instance == (Object)null || (StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.inShipPhase && RoundManager.Instance.allEnemyVents != null && RoundManager.Instance.allEnemyVents.Length != 0))); <>1__state = 2; return true; } <>2__current = (object)new WaitForSeconds(PublicFeatureConfig.RefillInterval.Value); <>1__state = 7; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnEnemyCoroutine>d__11 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public EnemyType type; public int count; private GameObject[] <aiNodes>5__2; private int <i>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnEnemyCoroutine>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <aiNodes>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_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) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)RoundManager.Instance == (Object)null || StartOfRound.Instance.inShipPhase) { return false; } goto IL_0269; } <>1__state = -1; if ((Object)(object)type == (Object)null || count <= 0 || (Object)(object)RoundManager.Instance == (Object)null || (Object)(object)StartOfRound.Instance == (Object)null) { return false; } <aiNodes>5__2 = RoundManager.Instance.insideAINodes; if (<aiNodes>5__2 == null || <aiNodes>5__2.Length == 0) { return false; } ValidSpawnNodesBuffer.Clear(); for (int i = 0; i < <aiNodes>5__2.Length; i++) { ValidSpawnNodesBuffer.Add(i); } <i>5__3 = 0; goto IL_027b; IL_0269: <i>5__3++; goto IL_027b; IL_027b: if (<i>5__3 < count) { if (ValidSpawnNodesBuffer.Count == 0) { for (int j = 0; j < <aiNodes>5__2.Length; j++) { ValidSpawnNodesBuffer.Add(j); } } int index = Random.Range(0, ValidSpawnNodesBuffer.Count); int num2 = ValidSpawnNodesBuffer[index]; GameObject val = <aiNodes>5__2[num2]; if ((Object)(object)val == (Object)null) { ValidSpawnNodesBuffer.RemoveAt(index); <i>5__3--; } else { Vector3 position = val.transform.position; Quaternion val2 = Quaternion.Euler(0f, val.transform.eulerAngles.y, 0f); try { GameObject obj = Object.Instantiate<GameObject>(type.enemyPrefab, position, val2); obj.GetComponentInChildren<NetworkObject>().Spawn(true); EnemyAI component = obj.GetComponent<EnemyAI>(); if ((Object)(object)component != (Object)null) { RoundManager.Instance.SpawnedEnemies.Add(component); component.enemyType.isOutsideEnemy = false; component.allAINodes = <aiNodes>5__2; component.SyncPositionToClients(); if (type.enemyName == "Flowerman") { component.EnableEnemyMesh(true, false, false); } } ValidSpawnNodesBuffer.RemoveAt(index); } catch (Exception arg) { PublicFeatureRuntime.Logger.LogError((object)$"[RefillSystem] Failed to spawn {type.enemyName}: {arg}"); } if (<i>5__3 < count - 1) { <>2__current = (object)new WaitForSeconds(PublicFeatureConfig.SpawnDelay.Value); <>1__state = 1; return true; } } goto IL_0269; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnInitialEnemiesCoroutine>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private List<MonsterConfig>.Enumerator <>7__wrap1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnInitialEnemiesCoroutine>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = default(List<MonsterConfig>.Enumerator); <>1__state = -2; } private bool MoveNext() { bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: { <>1__state = -1; List<MonsterConfig> monsterConfigs = GetMonsterConfigs(); <>7__wrap1 = monsterConfigs.GetEnumerator(); <>1__state = -3; break; } case 1: <>1__state = -3; break; } while (true) { if (<>7__wrap1.MoveNext()) { MonsterConfig current = <>7__wrap1.Current; if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase) { result = false; <>m__Finally1(); break; } if (current.Init > 0) { EnemyType enemyTypeByName = PublicFeatureEnemyCatalog.GetEnemyTypeByName(current.Name); if ((Object)(object)enemyTypeByName != (Object)null) { <>2__current = SpawnEnemyCoroutine(enemyTypeByName, current.Init); <>1__state = 1; result = true; break; } } continue; } <>m__Finally1(); <>7__wrap1 = default(List<MonsterConfig>.Enumerator); result = false; break; } end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly List<MonsterConfig> CachedRefillConfigs = new List<MonsterConfig>(); private static readonly List<(MonsterConfig Config, float Score)> RefillCandidatesBuffer = new List<(MonsterConfig, float)>(); private static readonly List<int> ValidSpawnNodesBuffer = new List<int>(); private static Coroutine _refillCoroutine; public static void Restart() { Stop(); if ((Object)(object)PublicFeatureRuntime.PluginInstance != (Object)null && PublicFeatureConfig.RefillEnabled.Value) { _refillCoroutine = ((MonoBehaviour)PublicFeatureRuntime.PluginInstance).StartCoroutine(RefillEnemiesRoutine()); } } public static void Stop() { if (_refillCoroutine != null && (Object)(object)PublicFeatureRuntime.PluginInstance != (Object)null) { ((MonoBehaviour)PublicFeatureRuntime.PluginInstance).StopCoroutine(_refillCoroutine); _refillCoroutine = null; } } [IteratorStateMachine(typeof(<RefillEnemiesRoutine>d__7))] private static IEnumerator RefillEnemiesRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RefillEnemiesRoutine>d__7(0); } [IteratorStateMachine(typeof(<SpawnInitialEnemiesCoroutine>d__8))] private static IEnumerator SpawnInitialEnemiesCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SpawnInitialEnemiesCoroutine>d__8(0); } [IteratorStateMachine(typeof(<CheckAndRefillEnemiesCoroutine>d__9))] private static IEnumerator CheckAndRefillEnemiesCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckAndRefillEnemiesCoroutine>d__9(0); } private static List<MonsterConfig> GetMonsterConfigs() { CachedRefillConfigs.Clear(); CachedRefillConfigs.Add(new MonsterConfig("Flowerman", PublicFeatureConfig.RefillFlowermanInit.Value, PublicFeatureConfig.RefillFlowermanMax.Value, PublicFeatureConfig.RefillFlowermanWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("Nutcracker", PublicFeatureConfig.RefillNutcrackerInit.Value, PublicFeatureConfig.RefillNutcrackerMax.Value, PublicFeatureConfig.RefillNutcrackerWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("Crawler", PublicFeatureConfig.RefillCrawlerInit.Value, PublicFeatureConfig.RefillCrawlerMax.Value, PublicFeatureConfig.RefillCrawlerWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("Centipede", PublicFeatureConfig.RefillCentipedeInit.Value, PublicFeatureConfig.RefillCentipedeMax.Value, PublicFeatureConfig.RefillCentipedeWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("HoarderBug", PublicFeatureConfig.RefillHoarderBugInit.Value, PublicFeatureConfig.RefillHoarderBugMax.Value, PublicFeatureConfig.RefillHoarderBugWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("Masked", PublicFeatureConfig.RefillMaskedInit.Value, PublicFeatureConfig.RefillMaskedMax.Value, PublicFeatureConfig.RefillMaskedWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("SandSpider", PublicFeatureConfig.RefillSandSpiderInit.Value, PublicFeatureConfig.RefillSandSpiderMax.Value, PublicFeatureConfig.RefillSandSpiderWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("Butler", PublicFeatureConfig.RefillButlerInit.Value, PublicFeatureConfig.RefillButlerMax.Value, PublicFeatureConfig.RefillButlerWeight.Value)); CachedRefillConfigs.Add(new MonsterConfig("Stingray", PublicFeatureConfig.RefillStingrayInit.Value, PublicFeatureConfig.RefillStingrayMax.Value, PublicFeatureConfig.RefillStingrayWeight.Value)); return CachedRefillConfigs; } [IteratorStateMachine(typeof(<SpawnEnemyCoroutine>d__11))] private static IEnumerator SpawnEnemyCoroutine(EnemyType type, int count) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SpawnEnemyCoroutine>d__11(0) { type = type, count = count }; } } [HarmonyPatch(typeof(RoundManager))] public static class WorldRulePatches { [HarmonyPatch("SpawnMapObjects")] [HarmonyPrefix] private static void SpawnMapObjectsPrefix(RoundManager __instance) { if (!((NetworkBehaviour)__instance).IsHost || !PublicFeatureConfig.DisableHazards.Value || __instance.currentLevel.indoorMapHazards == null) { return; } IndoorMapHazard[] indoorMapHazards = __instance.currentLevel.indoorMapHazards; foreach (IndoorMapHazard val in indoorMapHazards) { if (!((Object)(object)val.hazardType == (Object)null) && !((Object)(object)val.hazardType.prefabToSpawn == (Object)null)) { string name = ((Object)val.hazardType.prefabToSpawn).name; if (name.Contains("Landmine") || name.Contains("Turret") || name.Contains("Spike")) { val.numberToSpawn = AnimationCurve.Constant(0f, 1f, 0f); } } } } [HarmonyPatch("PlotOutEnemiesForNextHour")] [HarmonyPrefix] private static bool PlotOutEnemiesPrefix(RoundManager __instance) { if (((NetworkBehaviour)__instance).IsHost) { return !PublicFeatureConfig.DisableVanillaEnemies.Value; } return true; } [HarmonyPatch("SpawnEnemiesOutside")] [HarmonyPrefix] private static bool SpawnEnemiesOutsidePrefix(RoundManager __instance) { if (((NetworkBehaviour)__instance).IsHost) { return !PublicFeatureConfig.DisableVanillaEnemies.Value; } return true; } [HarmonyPatch("SpawnDaytimeEnemiesOutside")] [HarmonyPrefix] private static bool SpawnDaytimeEnemiesOutsidePrefix(RoundManager __instance) { if (((NetworkBehaviour)__instance).IsHost) { return !PublicFeatureConfig.DisableVanillaEnemies.Value; } return true; } [HarmonyPatch("SpawnScrapInLevel")] [HarmonyPrefix] private static bool SpawnScrapInLevelPrefix(RoundManager __instance) { if (((NetworkBehaviour)__instance).IsHost) { return !PublicFeatureConfig.DisableScrap.Value; } return true; } } [HarmonyPatch(typeof(Terminal), "Awake")] public static class PublicTerminalPatch { [HarmonyPostfix] private static void Postfix(Terminal __instance) { if (__instance.groupCredits == 60) { __instance.groupCredits = PublicFeatureConfig.StartingCredits.Value; } } } [HarmonyPatch(typeof(TimeOfDay), "Awake")] public static class PublicTimeOfDayPatch { [HarmonyPostfix] private static void Postfix(TimeOfDay __instance) { if (__instance.quotaVariables != null) { __instance.quotaVariables.startingCredits = PublicFeatureConfig.StartingCredits.Value; } } } [HarmonyPatch(typeof(DoorLock), "LockDoor")] public static class PublicDoorLockPatch { [HarmonyPostfix] private static void Postfix(DoorLock __instance) { if (PublicFeatureConfig.NoLockedDoors.Value && !((Object)(object)RoundManager.Instance == (Object)null) && (((NetworkBehaviour)RoundManager.Instance).IsServer || ((NetworkBehaviour)RoundManager.Instance).IsHost)) { __instance.UnlockDoorServerRpc(); } } } [HarmonyPatch(typeof(ButlerEnemyAI), "Start")] public static class PublicButlerDoorPatch { [HarmonyPostfix] private static void Postfix(ButlerEnemyAI __instance) { if (PublicFeatureConfig.ButlerInstantOpenDoors.Value) { ((EnemyAI)__instance).openDoorSpeedMultiplier = 100f; } } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerFromOtherClientClientRpc")] public static class PublicFriendlyFirePatch { [HarmonyPrefix] private static bool Prefix(PlayerControllerB __instance, int damageAmount, Vector3 hitDirection, int playerWhoHit, int newHealthAmount) { if (!PublicFeatureConfig.DisableFriendlyMeleeDamage.Value) { return true; } if (damageAmount <= 0 || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return true; } CentipedeAI[] array = Object.FindObjectsByType<CentipedeAI>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i].clingingToPlayer == (Object)(object)__instance) { return true; } } if (playerWhoHit >= 0 && playerWhoHit < StartOfRound.Instance.allPlayerScripts.Length) { PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerWhoHit]; if ((Object)(object)val != (Object)null && (Object)(object)val.currentlyHeldObjectServer != (Object)null && (val.currentlyHeldObjectServer is Shovel || val.currentlyHeldObjectServer is KnifeItem)) { return false; } } return true; } } [HarmonyPatch(typeof(ShotgunItem), "ShootGun")] public static class PublicNutcrackerShotgunPatch { [CompilerGenerated] private sealed class <DelayedEarsRinging>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float effectSeverity; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedEarsRinging>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.6f); <>1__state = 1; return true; case 1: <>1__state = -1; SoundManager.Instance.earsRingingTimer = effectSeverity; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPrefix] private static bool Prefix(ShotgunItem __instance, Vector3 shotgunPosition, Vector3 shotgunForward, ref RaycastHit[] ___enemyColliders, EnemyAI ___heldByEnemy) { //IL_001a: 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) if (!PublicFeatureConfig.NutcrackerNoFriendlyFire.Value) { return true; } if (!(___heldByEnemy is NutcrackerEnemyAI)) { return true; } RunNutcrackerShotgunWithoutMonsterDamage(__instance, shotgunPosition, shotgunForward); return false; } private static void RunNutcrackerShotgunWithoutMonsterDamage(ShotgunItem shotgun, Vector3 shotgunPosition, Vector3 shotgunForward) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) shotgun.isReloading = false; bool flag = ((GrabbableObject)shotgun).isHeld && (Object)(object)((GrabbableObject)shotgun).playerHeldBy != (Object)null && (Object)(object)((GrabbableObject)shotgun).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController; if (flag) { ((GrabbableObject)shotgun).playerHeldBy.playerBodyAnimator.SetTrigger("ShootShotgun"); } RoundManager.PlayRandomClip(shotgun.gunShootAudio, shotgun.gunShootSFX, true, 1f, 1840, 1000); WalkieTalkie.TransmitOneShotAudio(shotgun.gunShootAudio, shotgun.gunShootSFX[0], 1f); shotgun.gunShootParticle.Play(true); shotgun.shellsLoaded = Mathf.Clamp(shotgun.shellsLoaded - 1, 0, 2); PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if (!((Object)(object)localPlayerController == (Object)null)) { float num = Vector3.Distance(((Component)localPlayerController).transform.position, ((Component)shotgun.shotgunRayPoint).transform.position); bool flag2 = false; int num2 = 0; float num3 = 0f; Vector3 val = localPlayerController.playerCollider.ClosestPoint(shotgunPosition); if (!flag && !Physics.Linecast(shotgunPosition, val, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) && Vector3.Angle(shotgunForward, val - shotgunPosition) < 30f) { flag2 = true; } if (num < 5f) { num3 = 0.8f; HUDManager.Instance.ShakeCamera((ScreenShakeType)1); num2 = 100; } if (num < 15f) { num3 = 0.5f; HUDManager.Instance.ShakeCamera((ScreenShakeType)1); num2 = 100; } else if (num < 23f) { HUDManager.Instance.ShakeCamera((ScreenShakeType)0); num2 = 40; } else if (num < 30f) { num2 = 20; } if (num3 > 0f && SoundManager.Instance.timeSinceEarsStartedRinging > 16f) { ((MonoBehaviour)shotgun).StartCoroutine(DelayedEarsRinging(num3)); } Ray val2 = default(Ray); ((Ray)(ref val2))..ctor(shotgunPosition, shotgunForward); RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(val2, ref val3, 30f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { ((Component)shotgun.gunBulletsRicochetAudio).transform.position = ((Ray)(ref val2)).GetPoint(((RaycastHit)(ref val3)).distance - 0.5f); shotgun.gunBulletsRicochetAudio.Play(); } if (flag2) { localPlayerController.DamagePlayer(num2, true, true, (CauseOfDeath)7, 0, false, shotgun.shotgunRayPoint.forward * 30f); } } } [IteratorStateMachine(typeof(<DelayedEarsRinging>d__2))] private static IEnumerator DelayedEarsRinging(float effectSeverity) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedEarsRinging>d__2(0) { effectSeverity = effectSeverity }; } } public static class ItemAndLootPatches { private static class HoarderBugItemCacheCleaner { public static void CleanupHoarderBugItemCaches() { if (HoarderBugAI.HoarderBugItems != null) { HoarderBugAI.HoarderBugItems.RemoveAll((HoarderBugItem item) => item == null || (Object)(object)item.itemGrabbableObject == (Object)null || (Object)(object)((Component)item.itemGrabbableObject).gameObject == (Object)null || item.itemGrabbableObject.deactivated || item.itemGrabbableObject.itemUsedUp); } if (HoarderBugAI.grabbableObjectsInMap != null) { HoarderBugAI.grabbableObjectsInMap.RemoveAll((GameObject obj) => (Object)(object)obj == (Object)null); } CleanupLiveHoarderBugReferences(null); } public static void RemoveHoarderBugItem(GrabbableObject grabbable) { if ((Object)(object)grabbable == (Object)null) { return; } if (HoarderBugAI.HoarderBugItems != null) { HoarderBugAI.HoarderBugItems.RemoveAll((HoarderBugItem item) => item == null || (Object)(object)item.itemGrabbableObject == (Object)null || (Object)(object)item.itemGrabbableObject == (Object)(object)grabbable); } if (HoarderBugAI.grabbableObjectsInMap != null) { GameObject grabbableObject = ((Component)grabbable).gameObject; HoarderBugAI.grabbableObjectsInMap.RemoveAll((GameObject obj) => (Object)(object)obj == (Object)null || (Object)(object)obj == (Object)(object)grabbableObject); } CleanupLiveHoarderBugReferences(grabbable); } private static void CleanupLiveHoarderBugReferences(GrabbableObject grabbable) { HoarderBugAI[] array = Object.FindObjectsByType<HoarderBugAI>((FindObjectsSortMode)0); foreach (HoarderBugAI val in array) { if ((Object)(object)val == (Object)null) { continue; } if ((Object)(object)val.targetItem == (Object)null || (Object)(object)val.targetItem == (Object)(object)grabbable) { val.targetItem = null; } if (val.heldItem != null) { GrabbableObject itemGrabbableObject = val.heldItem.itemGrabbableObject; if ((Object)(object)itemGrabbableObject == (Object)null || (Object)(object)itemGrabbableObject == (Object)(object)grabbable) { val.heldItem = null; } } } } } [HarmonyPatch(typeof(HoarderBugAI), "DoAIInterval")] private static class HoarderBugStaleItemCleanupPatch { [HarmonyPrefix] private static void Prefix() { HoarderBugItemCacheCleaner.CleanupHoarderBugItemCaches(); } } [HarmonyPatch(typeof(GrabbableObject), "OnDestroy")] private static class HoarderBugDestroyedItemCleanupPatch { [HarmonyPrefix] private static void Prefix(GrabbableObject __instance) { HoarderBugItemCacheCleaner.RemoveHoarderBugItem(__instance); } } [HarmonyPatch(typeof(NutcrackerEnemyAI), "DropGun")] private static class NutcrackerDropGunPatch { [HarmonyPrefix] private static bool Prefix(NutcrackerEnemyAI __instance) { if (PublicFeatureConfig.NutcrackerDropGunAndShells.Value) { return true; } if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.gun == (Object)null) { return false; } ShotgunItem gun = __instance.gun; __instance.gun = null; if (((NetworkBehaviour)__instance).IsServer || ((NetworkBehaviour)__instance).IsHost) { if ((Object)(object)((NetworkBehaviour)gun).NetworkObject != (Object)null && ((NetworkBehaviour)gun).NetworkObject.IsSpawned) { ((NetworkBehaviour)gun).NetworkObject.Despawn(true); } else if ((Object)(object)((Component)gun).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)gun).gameObject); } } return false; } } [HarmonyPatch(typeof(NutcrackerEnemyAI), "SpawnShotgunShells")] private static class NutcrackerShellDropPatch { [HarmonyPrefix] private static bool Prefix() { return PublicFeatureConfig.NutcrackerDropGunAndShells.Value; } } [HarmonyPatch(typeof(ButlerEnemyAI), "ButlerBlowUpAndPop")] private static class ButlerDeathDropPatch { [CompilerGenerated] private sealed class <ButlerBlowUpWithoutDrops>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ButlerEnemyAI instance; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ButlerBlowUpWithoutDrops>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; ((EnemyAI)instance).creatureAnimator.SetTrigger("Popping"); ((EnemyAI)instance).creatureAnimator.SetLayerWeight(1, 0f); instance.popAudio.PlayOneShot(((EnemyAI)instance).enemyType.audioClips[3]); <>2__current = (object)new WaitForSeconds(1.1f); <>1__state = 1; return true; case 1: { <>1__state = -1; ((EnemyAI)instance).creatureAnimator.SetBool("popFinish", true); instance.popAudio.Play(); instance.popAudioFar.Play(); instance.popParticle.Play(true); float num = Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)instance).transform.position); if (num < 8f) { Landmine.SpawnExplosion(((Component)instance).transform.position + Vector3.up * 0.15f, false, 0f, 2f, 30, 80f, (GameObject)null, false); HUDManager.Instance.ShakeCamera((ScreenShakeType)1); SoundManager.Instance.earsRingingTimer = 0.8f; } else if (num < 27f) { HUDManager.Instance.ShakeCamera((ScreenShakeType)1); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPrefix] private static bool Prefix(ButlerEnemyAI __instance, ref IEnumerator __result) { if (PublicFeatureConfig.ButlerDropKnifeAndBees.Value) { return true; } __result = ButlerBlowUpWithoutDrops(__instance); return false; } [IteratorStateMachine(typeof(<ButlerBlowUpWithoutDrops>d__1))] private static IEnumerator ButlerBlowUpWithoutDrops(ButlerEnemyAI instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ButlerBlowUpWithoutDrops>d__1(0) { instance = instance }; } } [HarmonyPatch(typeof(SandSpiderAI), "KillEnemy")] private static class SandSpiderWebCleanupPatch { [HarmonyPostfix] private static void Postfix(SandSpiderAI __instance) { if ((Object)(object)__instance == (Object)null || (!((NetworkBehaviour)__instance).IsServer && !((NetworkBehaviour)__instance).IsHost)) { return; } try { for (int num = __instance.webTraps.Count - 1; num >= 0; num--) { __instance.BreakWebServerRpc(num, 1); } } catch (Exception arg) { PublicFeatureRuntime.Logger.LogWarning((object)$"[SandSpider] Failed to clear webs on death: {arg}"); } } } [HarmonyPatch(typeof(EnemyAI), "KillEnemy")] private static class EnemyKillDropPatch { [HarmonyPostfix] private static void Postfix(EnemyAI __instance, bool destroy) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } if (!destroy) { TryScheduleCorpseCleanup(__instance); } if (!destroy && PublicFeatureConfig.LootDropsEnabled.Value && !((Object)(object)RoundManager.Instance == (Object)null) && ((NetworkBehaviour)RoundManager.Instance).IsServer && !((Object)(object)__instance.enemyType == (Object)null) && SupportsCombatDrops(__instance) && !PublicFeatureRuntime.IsPrivateBossEnemy(__instance)) { EnsureLootItemsCached(); if ((Object)(object)_tzpItem != (Object)null && Random.value <= PublicFeatureConfig.TZPDropChance.Value) { SpawnLoot(((Component)__instance).transform.position, _tzpItem); } if ((Object)(object)_stunGrenadeItem != (Object)null && Random.value <= PublicFeatureConfig.StunGrenadeDropChance.Value) { SpawnLoot(((Component)__instance).transform.position, _stunGrenadeItem); } } } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerClientRpc")] private static class PlayerDamageSyncPatch { [HarmonyPostfix] private static void Postfix(PlayerControllerB __instance, int newHealthAmount) { if (((NetworkBehaviour)__instance).IsOwner && newHealthAmount >= 20 && __instance.criticallyInjured) { __instance.criticallyInjured = false; if ((Object)(object)__instance.playerBodyAnimator != (Object)null) { __instance.playerBodyAnimator.SetBool("Limp", false); } __instance.bleedingHeavily = false; } } } [HarmonyPatch(typeof(TetraChemicalItem), "Update")] private static class TZPHealingPatch { [HarmonyPostfix] private static void Postfix(TetraChemicalItem __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)((NetworkBehaviour)__instance).NetworkObject == (Object)null || !PublicFeatureConfig.TZPHealingEnabled.Value || (Object)(object)((NetworkBehaviour)__instance).NetworkManager == (Object)null || !((NetworkBehaviour)__instance).NetworkManager.IsServer) { return; } if (UsedTZPIndices.Contains(((NetworkBehaviour)__instance).NetworkObjectId)) { ulong networkObjectId = ((NetworkBehaviour)__instance).NetworkObjectId; if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) { if (!UsedTZPOnGroundSince.TryGetValue(networkObjectId, out var value)) { UsedTZPOnGroundSince[networkObjectId] = Time.time; } else if (Time.time - value > 2f) { UsedTZPOnGroundSince.Remove(networkObjectId); if (((NetworkBehaviour)__instance).NetworkObject.IsSpawned) { ((NetworkBehaviour)__instance).NetworkObject.Despawn(true); } } } else { UsedTZPOnGroundSince.Remove(networkObjectId); } } else { if (!(bool)AccessTools.Field(typeof(TetraChemicalItem), "emittingGas").GetValue(__instance) || (Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) { return; } PlayerControllerB playerHeldBy = ((GrabbableObject)__instance).playerHeldBy; if (!playerHeldBy.isPlayerDead) { HealPlayerFromTzpNetworked(playerHeldBy, PublicFeatureConfig.TZPHealAmount.Value); if (playerHeldBy.criticallyInjured) { playerHeldBy.MakeCriticallyInjured(false); } UsedTZPIndices.Add(((NetworkBehaviour)__instance).NetworkObjectId); } } } } [CompilerGenerated] private sealed class <ApplyPendingTzpCriticalHeal>d__15 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ulong playerId; public PlayerControllerB player; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyPendingTzpCriticalHeal>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1.25f); <>1__state = 1; return true; case 1: { <>1__state = -1; PendingTzpCriticalHealCoroutines.Remove(playerId); if (!PendingTzpCriticalHealTargets.TryGetValue(playerId, out var value)) { return false; } PendingTzpCriticalHealTargets.Remove(playerId); if ((Object)(object)player == (Object)null || player.isPlayerDead) { return false; } if (player.health < 19 || player.health > 20) { return false; } value = Mathf.Clamp(value, 20, 100); if (value <= player.health) { if (player.health >= 20) { player.DamagePlayerClientRpc(0, player.health); } return false; } player.DamagePlayerClientRpc(-(value - player.health), value); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <CorpseCleanupCoroutine>d__11 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public EnemyAI enemy; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CorpseCleanupCoroutine>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)enemy == (Object)null) { return false; } if ((Object)(object)((NetworkBehaviour)enemy).NetworkObject != (Object)null && ((NetworkBehaviour)enemy).NetworkObject.IsSpawned && (((NetworkBehaviour)enemy).IsServer || ((NetworkBehaviour)enemy).IsHost)) { ((NetworkBehaviour)enemy).NetworkObject.Despawn(true); return false; } if ((Object)(object)((Component)enemy).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)enemy).gameObject); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly HashSet<ulong> UsedTZPIndices = new HashSet<ulong>(); private static readonly Dictionary<ulong, float> UsedTZPOnGroundSince = new Dictionary<ulong, float>(); private static readonly Dictionary<ulong, int> PendingTzpCriticalHealTargets = new Dictionary<ulong, int>(); private static readonly Dictionary<ulong, Coroutine> PendingTzpCriticalHealCoroutines = new Dictionary<ulong, Coroutine>(); private static Item _tzpItem; private static Item _stunGrenadeItem; public static void ResetRoundState() { UsedTZPIndices.Clear(); UsedTZPOnGroundSince.Clear(); PendingTzpCriticalHealTargets.Clear(); foreach (Coroutine value in PendingTzpCriticalHealCoroutines.Values) { if (value != null && (Object)(object)PublicFeatureRuntime.PluginInstance != (Object)null) { ((MonoBehaviour)PublicFeatureRuntime.PluginInstance).StopCoroutine(value); } } PendingTzpCriticalHealCoroutines.Clear(); _tzpItem = null; _stunGrenadeItem = null; } private static void EnsureLootItemsCached() { if (((Object)(object)_tzpItem != (Object)null && (Object)(object)_stunGrenadeItem != (Object)null) || (Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.allItemsList == (Object)null) { return; } foreach (Item items in StartOfRound.Instance.allItemsList.itemsList) { if ((Object)(object)_tzpItem == (Object)null && items.itemName == "TZP-Inhalant") { _tzpItem = items; } else if ((Object)(object)_stunGrenadeItem == (Object)null && items.itemName == "Stun grenade") { _stunGrenadeItem = items; } } } private static bool SupportsCombatDrops(EnemyAI enemy) { if (!(enemy is FlowermanAI) && !(enemy is ButlerEnemyAI) && !(enemy is NutcrackerEnemyAI) && !(enemy is MaskedPlayerEnemy) && !(enemy is SandSpiderAI) && !(enemy is CentipedeAI) && !(enemy is CrawlerAI) && !(enemy is HoarderBugAI) && !(enemy is BaboonBirdAI) && !(enemy is StingrayAI) && !(enemy is CaveDwellerAI)) { return enemy is GiantKiwiAI; } return true; } private static bool SupportsCorpseCleanup(EnemyAI enemy) { if (!(enemy is FlowermanAI) && !(enemy is ButlerEnemyAI) && !(enemy is NutcrackerEnemyAI) && !(enemy is MaskedPlayerEnemy) && !(enemy is SandSpiderAI) && !(enemy is CentipedeAI) && !(enemy is CrawlerAI) && !(enemy is HoarderBugAI) && !(enemy is BaboonBirdAI) && !(enemy is StingrayAI) && !(enemy is CaveDwellerAI)) { return enemy is GiantKiwiAI; } return true; } private static void TryScheduleCorpseCleanup(EnemyAI enemy) { if (!PublicFeatureConfig.CorpseCleanupEnabled.Value || (Object)(object)enemy == (Object)null || !SupportsCorpseCleanup(enemy) || PublicFeatureRuntime.IsPrivateBossEnemy(enemy) || (!((NetworkBehaviour)enemy).IsServer && !((NetworkBehaviour)enemy).IsHost)) { return; } try { if (Traverse.Create((object)enemy).Field<Coroutine>("deathCoroutine").Value == null) { float delay = Mathf.Max(0f, PublicFeatureConfig.CorpseCleanupDelay.Value); Coroutine value = ((MonoBehaviour)enemy).StartCoroutine(CorpseCleanupCoroutine(enemy, delay)); Traverse.Create((object)enemy).Field("deathCoroutine").SetValue((object)value); } } catch (Exception arg) { PublicFeatureRuntime.Logger.LogError((object)$"[CorpseCleanup] Failed to schedule cleanup for {enemy.enemyType?.enemyName ?? ((Object)enemy).name}: {arg}"); } } [IteratorStateMachine(typeof(<CorpseCleanupCoroutine>d__11))] private static IEnumerator CorpseCleanupCoroutine(EnemyAI enemy, float delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CorpseCleanupCoroutine>d__11(0) { enemy = enemy, delay = delay }; } private static void SpawnLoot(Vector3 position, Item item) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null || (Object)(object)item.spawnPrefab == (Object)null) { return; } try { Vector3 val = position + Vector3.up * 0.5f + Random.insideUnitSphere * 0.2f; GameObject val2 = Object.Instantiate<GameObject>(item.spawnPrefab, val, Random.rotation); GrabbableObject component = val2.GetComponent<GrabbableObject>(); if ((Object)(object)component != (Object)null) { component.startFallingPosition = val; component.FallToGround(true, true, default(Vector3)); NetworkObject component2 = val2.GetComponent<NetworkObject>(); if ((Object)(object)component2 != (Object)null) { component2.Spawn(true); } } } catch (Exception arg) { PublicFeatureRuntime.Logger.LogError((object)$"[LootDrops] Failed to spawn {item.itemName}: {arg}"); } } private static void HealPlayerFromTzpNetworked(PlayerControllerB player, int amount) { if ((Object)(object)player == (Object)null || player.isPlayerDead || amount <= 0) { return; } ulong playerClientId = player.playerClientId; if (PendingTzpCriticalHealTargets.TryGetValue(playerClientId, out var value)) { int num = Mathf.Clamp(Mathf.Max(player.health, value) + amount, 20, 100); if (num > value) { PendingTzpCriticalHealTargets[playerClientId] = num; } return; } int health = player.health; int num2 = Mathf.Clamp(health + amount, 0, 100); if (num2 <= health) { return; } if (player.health > 0 && (player.health < 20 || player.criticallyInjured) && num2 >= 20) { if (player.health < 19) { player.DamagePlayerClientRpc(-(19 - player.health), 19); } else if (player.health != 19) { player.DamagePlayerClientRpc(0, 19); } SchedulePendingTzpCriticalHeal(player, num2); } else { player.DamagePlayerClientRpc(-(num2 - player.health), num2); } } private static void SchedulePendingTzpCriticalHeal(PlayerControllerB player, int finalHealth) { if (!((Object)(object)player == (Object)null) && !player.isPlayerDead && !((Object)(object)PublicFeatureRuntime.PluginInstance == (Object)null)) { ulong playerClientId = player.playerClientId; PendingTzpCriticalHealTargets[playerClientId] = finalHealth; if (!PendingTzpCriticalHealCoroutines.TryGetValue(playerClientId, out var value) || value == null) { PendingTzpCriticalHealCoroutines[playerClientId] = ((MonoBehaviour)PublicFeatureRuntime.PluginInstance).StartCoroutine(ApplyPendingTzpCriticalHeal(player, playerClientId)); } } } [IteratorStateMachine(typeof(<ApplyPendingTzpCriticalHeal>d__15))] private static IEnumerator ApplyPendingTzpCriticalHeal(PlayerControllerB player, ulong playerId) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ApplyPendingTzpCriticalHeal>d__15(0) { player = player, playerId = playerId }; } } } namespace PublicCombatMod { [BepInPlugin("com.lengjing.lethalbattletweaks", "LethalBattleTweaks", "1.0.2")] public class Plugin : BaseUnityPlugin { private Harmony _harmony; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _harmony = new Harmony("com.lengjing.lethalbattletweaks"); _harmony.PatchAll(); PublicFeatureRuntime.Initialize((BaseUnityPlugin)(object)this, PublicFeatureMode.PublicStandalone, ((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalBattleTweaks loaded."); } private void Start() { PublicFeatureRuntime.OnPluginStart(); } private void OnDestroy() { PublicFeatureRuntime.Shutdown(); } } }