Decompiled source of LethalBattleTweaks v1.0.2

LethalBattleTweaks.dll

Decompiled a month ago
using 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();
		}
	}
}