Decompiled source of Thanks AK47 v1.0.1

plugins/com.github.PeakTest.Thanks.AK47.dll

Decompiled 6 months 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using PEAKLib.Core;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PeakCringe AK47")]
[assembly: AssemblyDescription("AK47 weapon mod for PEAK game")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("baphometcrafts")]
[assembly: AssemblyProduct("PeakCringe_AK47")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("927916CE-8113-4CE1-A65E-D4BD77E780B4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Thanks_AK47;

[BepInPlugin("com.github.PeakTest.Thanks.AK47", "Thanks AK47", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	[CompilerGenerated]
	private sealed class <DelayedReplaceBlowgunModel>d__109 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DelayedReplaceBlowgunModel>d__109(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.5f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				Instance.ReplaceBlowgunInstances();
				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 <DestroyZombieAfterDelay>d__129 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float delay;

		public Character zombie;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DestroyZombieAfterDelay>d__129(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)zombie != (Object)null && (Object)(object)((Component)zombie).gameObject != (Object)null)
				{
					PhotonView component = ((Component)zombie).GetComponent<PhotonView>();
					if ((Object)(object)component != (Object)null)
					{
						if (component.IsMine)
						{
							PhotonNetwork.Destroy(((Component)zombie).gameObject);
						}
						else if (PhotonNetwork.IsMasterClient)
						{
							PhotonNetwork.Destroy(component);
						}
					}
					else
					{
						Object.Destroy((Object)(object)((Component)zombie).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();
		}
	}

	[CompilerGenerated]
	private sealed class <PeriodicPlayerScan>d__112 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <PeriodicPlayerScan>d__112(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(2f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				break;
			case 2:
				<>1__state = -1;
				break;
			}
			if (PhotonNetwork.IsMasterClient)
			{
				try
				{
					foreach (Character allCharacter in Character.AllCharacters)
					{
						if (allCharacter.isBot || (Object)(object)allCharacter.refs?.view == (Object)null)
						{
							continue;
						}
						int ownerActorNr = allCharacter.refs.view.OwnerActorNr;
						bool flag = IsAlive(allCharacter);
						bool flag2 = false;
						if (_playerDeathState.TryGetValue(ownerActorNr, out var value))
						{
							flag2 = value;
						}
						_playerDeathState[ownerActorNr] = !flag;
						if (!flag)
						{
							continue;
						}
						if (!_receivedItem.Contains(ownerActorNr))
						{
							if (TryGiveItemTo(allCharacter))
							{
								_receivedItem.Add(ownerActorNr);
								Log.LogInfo((object)("[AK47] Gave weapon to " + allCharacter.characterName + " (first spawn)"));
							}
						}
						else if (flag2 && TryGiveItemTo(allCharacter))
						{
							Log.LogInfo((object)("[AK47] Gave weapon to " + allCharacter.characterName + " (respawned)"));
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[AK47] Player scan error: " + ex));
				}
			}
			<>2__current = (object)new WaitForSeconds(2f);
			<>1__state = 2;
			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();
		}
	}

	public const string Id = "com.github.PeakTest.Thanks.AK47";

	public const string Name = "Thanks AK47";

	public const string Version = "1.0.1";

	private static HashSet<int> _receivedItem = new HashSet<int>();

	private static Dictionary<int, bool> _playerDeathState = new Dictionary<int, bool>();

	private static Character _localCharacter;

	private static float _lastFireTime;

	private static bool _hasWeapon;

	private static Coroutine _scanCoroutine;

	public static AudioClip _gunshotSound;

	private static bool _resourcesLoaded;

	public static GameObject _ak47Prefab;

	private static GameObject _ak47VFX;

	private static object _ak47SFXInstance;

	private static object _ak47ItemContent;

	private static Mesh _ak47Mesh;

	private static Material _ak47Material;

	private static Material[] _ak47Materials;

	private static HashSet<Material> _processedMaterials = new HashSet<Material>();

	private static float _lastMaterialUpdateTime = 0f;

	private static float _lastModelReplaceTime = 0f;

	private static HashSet<GameObject> _replacedBlowguns = new HashSet<GameObject>();

	public static Plugin Instance { get; private set; }

	internal static ManualLogSource Log { get; private set; }

	public static ConfigEntry<float> FireInterval { get; private set; }

	public static ConfigEntry<float> ZombieTimeReduction { get; private set; }

	public static ConfigEntry<float> StunDuration { get; private set; }

	public static ConfigEntry<float> MaxDistance { get; private set; }

	public static ConfigEntry<float> BulletSize { get; private set; }

	public static ConfigEntry<int> InventorySlot { get; private set; }

	public static ConfigEntry<ushort> ItemIdToGive { get; private set; }

	public static ConfigEntry<float> ChargeBarScale { get; private set; }

	public static ConfigEntry<float> ZombieMoveSpeed { get; private set; }

	public static ConfigEntry<KeyCode> SpawnWeaponKey { get; private set; }

	public static ConfigEntry<bool> ZombieSpawnEnabled { get; private set; }

	public static ConfigEntry<float> ZombieSpawnInterval { get; private set; }

	public static ConfigEntry<float> ZombieSpawnRadius { get; private set; }

	public static ConfigEntry<int> ZombieSpawnCount { get; private set; }

	public static ConfigEntry<int> InitialZombieCount { get; private set; }

	public static ConfigEntry<float> ZombieSpawnDelay { get; private set; }

	public static ConfigEntry<int> MaxZombies { get; private set; }

	public static ConfigEntry<float> ZombieMaxLifetime { get; private set; }

	public static void PlayGunshotSound(Vector3 position)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: 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_0076: Expected O, but got Unknown
		if (!((Object)(object)_gunshotSound == (Object)null))
		{
			GameObject val = new GameObject("GunshotSound");
			val.transform.position = position;
			AudioSource obj = val.AddComponent<AudioSource>();
			obj.clip = _gunshotSound;
			obj.volume = 0.7f;
			obj.pitch = 1.4f;
			obj.spatialBlend = 1f;
			obj.Play();
			Object.Destroy((Object)val, _gunshotSound.length / 1.3f + 0.1f);
		}
	}

	private void Awake()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		Log.LogInfo((object)"Thanks AK47 v1.0.0 Loading...");
		try
		{
			InitConfig();
			LoadAk47BundleInAwake();
			new Harmony("com.github.PeakTest.Thanks.AK47").PatchAll(Assembly.GetExecutingAssembly());
			SceneManager.sceneLoaded += OnSceneLoaded;
			Log.LogInfo((object)"Thanks AK47 loaded successfully!");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] Awake error: " + ex));
		}
	}

	private void LoadAk47BundleInAwake()
	{
		try
		{
			Type type = typeof(PeakBundle).Assembly.GetType("PEAKLib.Core.BundleLoader");
			if (type == null)
			{
				Log.LogWarning((object)"[AK47] BundleLoader type not found");
				return;
			}
			MethodInfo method = type.GetMethod("LoadBundleWithName", BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				Log.LogWarning((object)"[AK47] LoadBundleWithName method not found");
				return;
			}
			Delegate @delegate = Delegate.CreateDelegate(typeof(Action<>).MakeGenericType(typeof(PeakBundle)), this, "OnBundleLoaded");
			method.Invoke(null, new object[3] { this, "ak.peakbundle", @delegate });
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] LoadAk47BundleInAwake error: " + ex));
		}
	}

	private void InitConfig()
	{
		FireInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Weapon Settings 武器设置", "Fire Interval 射击间隔", 0.5f, "Fire interval in seconds / 每次射击的间隔时间(秒)");
		ZombieTimeReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Weapon Settings 武器设置", "Zombie Time Reduction 僵尸时间减少", 20f, "Seconds reduced from zombie survival time per hit / 每次命中僵尸减少的存活时间(秒)");
		StunDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Weapon Settings 武器设置", "Stun Duration 眩晕时间", 3f, "Player stun duration in seconds / 玩家被命中后的眩晕时间(秒)");
		MaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Weapon Settings 武器设置", "Max Distance 最大射程", 100f, "Maximum shooting distance / 子弹最大飞行距离");
		BulletSize = ((BaseUnityPlugin)this).Config.Bind<float>("Weapon Settings 武器设置", "Bullet Size 子弹大小", 0.1f, "Bullet collision size / 子弹碰撞体积大小");
		InventorySlot = ((BaseUnityPlugin)this).Config.Bind<int>("Inventory Settings 物品栏设置", "Slot 槽位", 1, "Inventory slot (0-3) / 物品栏槽位(0-3)");
		ItemIdToGive = ((BaseUnityPlugin)this).Config.Bind<ushort>("Item Settings 物品设置", "Item ID 物品ID", (ushort)70, "Item ID to give (70=Blowgun) / 给予的物品ID(70=吹箭筒)");
		ChargeBarScale = ((BaseUnityPlugin)this).Config.Bind<float>("UI Settings UI设置", "Charge Bar Scale 充能条缩放", 0.5f, "Charge bar UI scale (0.5=half size) / 充能条UI缩放比例(0.5=缩小一半)");
		ZombieMoveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Settings 僵尸设置", "Move Speed 移动速度", 1f, "Zombie movement speed multiplier (1.0=normal) / 僵尸移动速度倍率(1.0=正常速度)");
		SpawnWeaponKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys 快捷键", "Spawn Weapon Key 生成武器按键", (KeyCode)116, "Key to spawn weapon for host / 主机按此键生成武器");
		ZombieSpawnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Zombie Spawn 僵尸生成", "Enabled 启用", true, "Enable zombie spawning / 是否启用僵尸生成功能");
		ZombieSpawnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Spawn 僵尸生成", "Spawn Interval 生成间隔", 15f, "Zombie spawn interval in seconds / 僵尸生成间隔时间(秒)");
		ZombieSpawnRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Spawn 僵尸生成", "Spawn Radius 生成半径", 30f, "Zombie spawn radius around players / 玩家周围僵尸生成半径");
		ZombieSpawnCount = ((BaseUnityPlugin)this).Config.Bind<int>("Zombie Spawn 僵尸生成", "Spawn Count 每次生成数量", 2, "Number of zombies to spawn per wave / 每次生成的僵尸数量");
		InitialZombieCount = ((BaseUnityPlugin)this).Config.Bind<int>("Zombie Spawn 僵尸生成", "Initial Count 初始数量", 3, "Initial zombie count / 玩家加入时初始生成的僵尸数量");
		ZombieSpawnDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Spawn 僵尸生成", "Initial Delay 初始延迟", 15f, "Delay before zombie spawning starts / 首次生成僵尸前的延迟时间(秒)");
		MaxZombies = ((BaseUnityPlugin)this).Config.Bind<int>("Zombie Spawn 僵尸生成", "Max Count 最大数量", 5, "Maximum zombies allowed / 场景中同时存在的最大僵尸数量");
		ZombieMaxLifetime = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Spawn 僵尸生成", "Max Lifetime 最大存活时间", 120f, "Maximum zombie lifetime in seconds / 僵尸最大存活时间(秒)");
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		if (_scanCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(_scanCoroutine);
			_scanCoroutine = null;
		}
		_receivedItem.Clear();
		ZombieSpawner.StopZombieSpawning();
		ZombieSpawner.ClearZombies();
		bool flag = ((Scene)(ref scene)).name != null && ((Scene)(ref scene)).name.Contains("Airport");
		if (((Scene)(ref scene)).name != null && !((Scene)(ref scene)).name.Contains("Pretitle") && !((Scene)(ref scene)).name.Contains("Title") && !flag)
		{
			_resourcesLoaded = false;
			_scanCoroutine = ((MonoBehaviour)this).StartCoroutine(PeriodicPlayerScan());
			ZombieSpawner.StartZombieSpawning();
			Log.LogInfo((object)("[AK47] Game scene loaded: " + ((Scene)(ref scene)).name + ", starting zombie spawning"));
		}
		else if (flag)
		{
			_resourcesLoaded = false;
			_scanCoroutine = ((MonoBehaviour)this).StartCoroutine(PeriodicPlayerScan());
			Log.LogInfo((object)("[AK47] Lobby scene loaded: " + ((Scene)(ref scene)).name + ", giving weapon (no zombies)"));
		}
		else
		{
			Log.LogInfo((object)("[AK47] Non-game scene loaded: " + ((Scene)(ref scene)).name + ", zombie spawning disabled"));
		}
	}

	private void LoadResources()
	{
		if (_resourcesLoaded)
		{
			return;
		}
		try
		{
			AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
			AudioClip val = null;
			Log.LogInfo((object)"[AK47] Listing all audio clips in game...");
			List<string> list = new List<string>();
			AudioClip[] array2 = array;
			foreach (AudioClip val2 in array2)
			{
				list.Add(((Object)val2).name);
			}
			list.Sort();
			foreach (string item in list)
			{
				Log.LogInfo((object)("[AK47] Audio clip: " + item));
			}
			array2 = array;
			foreach (AudioClip val3 in array2)
			{
				string text = ((Object)val3).name.ToLower();
				if (text.Contains("garand_fire") || text.Contains("gundog_fire"))
				{
					Log.LogInfo((object)("[AK47] Found rifle sound: " + ((Object)val3).name));
					if ((Object)(object)val == (Object)null || text.Contains("garand_fire1"))
					{
						val = val3;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				_gunshotSound = val;
				Log.LogInfo((object)("[AK47] Selected gunshot sound: " + ((Object)_gunshotSound).name));
			}
			else
			{
				Log.LogWarning((object)"[AK47] No gunshot sound found in game resources");
			}
			ReplaceBlowgunSound();
			ListAllItems();
			_resourcesLoaded = true;
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] LoadResources error: " + ex));
		}
	}

	private void OnBundleLoaded(PeakBundle peakBundle)
	{
		try
		{
			if (peakBundle == null)
			{
				Log.LogError((object)"[AK47] peakBundle is null");
				return;
			}
			MethodInfo[] methods = typeof(PeakBundle).GetMethods(BindingFlags.Instance | BindingFlags.Public);
			MethodInfo methodInfo = null;
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo2 in array)
			{
				if (methodInfo2.Name == "LoadAsset" && methodInfo2.IsGenericMethodDefinition)
				{
					methodInfo = methodInfo2;
					break;
				}
			}
			Log.LogInfo((object)$"[AK47] loadAssetMethod found: {methodInfo != null}");
			Type type = null;
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "PEAKLib.Items");
			if (assembly != null)
			{
				type = assembly.GetType("PEAKLib.Items.UnityEditor.UnityItemContent");
				Log.LogInfo((object)("[AK47] Found PEAKLib.Items assembly, unityItemContentType: " + (type?.FullName ?? "null")));
			}
			else
			{
				Log.LogWarning((object)"[AK47] PEAKLib.Items assembly not found");
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly2 in assemblies)
				{
					Type type2 = assembly2.GetType("PEAKLib.Items.UnityEditor.UnityItemContent");
					if (type2 != null)
					{
						type = type2;
						Log.LogInfo((object)("[AK47] Found UnityItemContent in assembly: " + assembly2.FullName));
						break;
					}
				}
			}
			Log.LogInfo((object)("[AK47] unityItemContentType final: " + (type?.FullName ?? "null")));
			if (type != null && methodInfo != null)
			{
				try
				{
					object obj = methodInfo.MakeGenericMethod(type).Invoke(peakBundle, new object[1] { "IC_AK" });
					Log.LogInfo((object)("[AK47] IC_AK load result: " + (obj?.GetType()?.FullName ?? "null")));
					if (obj != null)
					{
						_ak47ItemContent = obj;
						FieldInfo field = type.GetField("ItemPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						PropertyInfo property = type.GetProperty("ItemPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						Log.LogInfo((object)("[AK47] itemPrefabField: " + (field?.Name ?? "null") + ", itemPrefabProperty: " + (property?.Name ?? "null")));
						if (property != null)
						{
							object? value = property.GetValue(obj);
							_ak47Prefab = (GameObject)((value is GameObject) ? value : null);
						}
						else if (field != null)
						{
							object? value2 = field.GetValue(obj);
							_ak47Prefab = (GameObject)((value2 is GameObject) ? value2 : null);
						}
						ManualLogSource log = Log;
						GameObject ak47Prefab = _ak47Prefab;
						log.LogInfo((object)("[AK47] Loaded UnityItemContent IC_AK, prefab: " + (((ak47Prefab != null) ? ((Object)ak47Prefab).name : null) ?? "null")));
					}
					else
					{
						Log.LogWarning((object)"[AK47] IC_AK asset not found in bundle");
					}
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"[AK47] Error loading IC_AK: {arg}");
				}
			}
			Type type3 = typeof(Item).Assembly.GetType("SFX_Instance");
			if (type3 != null && methodInfo != null)
			{
				try
				{
					object obj2 = methodInfo.MakeGenericMethod(type3).Invoke(peakBundle, new object[1] { "SFX_AK" });
					if (obj2 != null)
					{
						_ak47SFXInstance = obj2;
						Log.LogInfo((object)"[AK47] Loaded SFX_AK from bundle");
						FieldInfo field2 = type3.GetField("clips", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field2 != null && field2.GetValue(obj2) is AudioClip[] array2 && array2.Length != 0)
						{
							_gunshotSound = array2[0];
							ManualLogSource log2 = Log;
							AudioClip gunshotSound = _gunshotSound;
							log2.LogInfo((object)("[AK47] Found gunshot sound in SFX_AK: " + ((gunshotSound != null) ? ((Object)gunshotSound).name : null)));
						}
						if ((Object)(object)_gunshotSound == (Object)null)
						{
							FieldInfo field3 = type3.GetField("clip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							if (field3 != null)
							{
								object? value3 = field3.GetValue(obj2);
								_gunshotSound = (AudioClip)((value3 is AudioClip) ? value3 : null);
								ManualLogSource log3 = Log;
								AudioClip gunshotSound2 = _gunshotSound;
								log3.LogInfo((object)("[AK47] Found gunshot sound (clip) in SFX_AK: " + ((gunshotSound2 != null) ? ((Object)gunshotSound2).name : null)));
							}
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[AK47] Error loading SFX_AK: " + ex.Message));
				}
			}
			if ((Object)(object)_ak47Prefab != (Object)null)
			{
				MeshFilter[] componentsInChildren = _ak47Prefab.GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter val in componentsInChildren)
				{
					if ((Object)(object)val.sharedMesh != (Object)null && (((Object)val.sharedMesh).name == "Cube" || (Object)(object)_ak47Mesh == (Object)null))
					{
						_ak47Mesh = val.sharedMesh;
					}
				}
				SkinnedMeshRenderer[] componentsInChildren2 = _ak47Prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
				{
					if ((Object)(object)((Renderer)val2).sharedMaterial != (Object)null && (Object)(object)_ak47Material == (Object)null)
					{
						_ak47Material = ((Renderer)val2).sharedMaterial;
					}
					if (((Renderer)val2).sharedMaterials != null && ((Renderer)val2).sharedMaterials.Length != 0)
					{
						_ak47Materials = ((Renderer)val2).sharedMaterials;
					}
				}
				MeshRenderer[] componentsInChildren3 = _ak47Prefab.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val3 in componentsInChildren3)
				{
					if ((Object)(object)((Renderer)val3).sharedMaterial != (Object)null && (Object)(object)_ak47Material == (Object)null)
					{
						_ak47Material = ((Renderer)val3).sharedMaterial;
					}
					if (((Renderer)val3).sharedMaterials != null && ((Renderer)val3).sharedMaterials.Length != 0 && _ak47Materials == null)
					{
						_ak47Materials = ((Renderer)val3).sharedMaterials;
					}
				}
				ManualLogSource log4 = Log;
				Mesh ak47Mesh = _ak47Mesh;
				string arg2 = ((ak47Mesh != null) ? ((Object)ak47Mesh).name : null);
				Material[] ak47Materials = _ak47Materials;
				log4.LogInfo((object)$"[AK47] Loaded AK47 prefab with mesh: {arg2}, materials: {((ak47Materials != null) ? ak47Materials.Length : 0)}");
			}
			GameObject val4 = peakBundle.LoadAsset<GameObject>("VFX_AK");
			if ((Object)(object)val4 != (Object)null)
			{
				_ak47VFX = val4;
				Log.LogInfo((object)"[AK47] Loaded VFX_AK from bundle");
			}
			Object[] array3 = peakBundle.LoadAllAssets();
			foreach (Object obj3 in array3)
			{
				AudioClip val5 = (AudioClip)(object)((obj3 is AudioClip) ? obj3 : null);
				if (val5 != null && (Object)(object)_gunshotSound == (Object)null)
				{
					string text = ((Object)val5).name.ToLower();
					if (text.Contains("shot") || text.Contains("gun") || text.Contains("fire") || text.Contains("bang") || text.Contains("shoot") || text.Contains("ak") || text.Contains("rifle") || text.Contains("weapon"))
					{
						_gunshotSound = val5;
						Log.LogInfo((object)("[AK47] Found gunshot sound from all assets: " + ((Object)val5).name));
					}
				}
			}
			ModDefinition mod = peakBundle.Mod;
			if (mod != null)
			{
				mod.RegisterContent();
			}
			ReplaceBlowgunModel();
			ReplaceBlowgunLocalization();
		}
		catch (Exception ex2)
		{
			Log.LogError((object)("[AK47] OnBundleLoaded error: " + ex2));
		}
	}

	private void ReplaceBlowgunModel()
	{
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_ak47Prefab == (Object)null)
		{
			Log.LogWarning((object)"[AK47] _ak47Prefab is null, cannot replace blowgun model");
			return;
		}
		try
		{
			MethodInfo method = typeof(ItemDatabase).GetMethod("TryGetItem", BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				return;
			}
			object[] array = new object[2]
			{
				(ushort)70,
				null
			};
			if (!(bool)method.Invoke(null, array) || array[1] == null)
			{
				return;
			}
			object obj = array[1];
			Item val = (Item)((obj is Item) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Log.LogInfo((object)("[AK47] Found blowgun item: " + ((Object)val).name));
			Transform val2 = ((Component)val).transform.Find("Blowgun");
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)val).transform;
			}
			Log.LogInfo((object)("[AK47] Blowgun transform: " + ((Object)val2).name));
			MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
			MeshRenderer component2 = ((Component)val2).GetComponent<MeshRenderer>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
			{
				MeshFilter componentInChildren = _ak47Prefab.GetComponentInChildren<MeshFilter>();
				MeshRenderer componentInChildren2 = _ak47Prefab.GetComponentInChildren<MeshRenderer>();
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren2 != (Object)null)
				{
					component.sharedMesh = componentInChildren.sharedMesh;
					((Renderer)component2).sharedMaterials = ((Renderer)componentInChildren2).sharedMaterials;
					Vector3 localScale = ((Component)componentInChildren).transform.localScale;
					val2.localScale = localScale * 1.6f;
					val2.localRotation = ((Component)componentInChildren).transform.localRotation * Quaternion.Euler(0f, 0f, -12f);
					val2.localPosition = ((Component)componentInChildren).transform.localPosition + new Vector3(-0.01f, -0.01f, 0f);
					ManualLogSource log = Log;
					Mesh sharedMesh = componentInChildren.sharedMesh;
					log.LogInfo((object)("[AK47] Replaced blowgun prefab mesh with AK47 mesh: " + ((sharedMesh != null) ? ((Object)sharedMesh).name : null)));
				}
			}
			FieldInfo field = typeof(Item).GetField("localizationKey", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(val, "AK47");
			}
			FieldInfo field2 = typeof(Item).GetField("titleKey", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 != null)
			{
				field2.SetValue(val, "AK47");
			}
			Log.LogInfo((object)"[AK47] Replaced blowgun prefab model with AK47");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] ReplaceBlowgunModel error: " + ex));
		}
	}

	private void ReplaceBlowgunLocalization()
	{
		try
		{
			Type type = typeof(Item).Assembly.GetType("LocalizedText");
			if (type != null)
			{
				FieldInfo field = type.GetField("mainTable", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object value = field.GetValue(null);
					if (value != null)
					{
						PropertyInfo property = value.GetType().GetProperty("Item");
						if (property != null)
						{
							List<string> list = new List<string>(15);
							for (int i = 0; i < 15; i++)
							{
								list.Add("AK-47");
							}
							property.SetValue(value, list, new object[1] { "NAME_AK" });
							Log.LogInfo((object)"[AK47] Added NAME_AK localization");
						}
					}
				}
			}
			MethodInfo method = typeof(ItemDatabase).GetMethod("TryGetItem", BindingFlags.Static | BindingFlags.Public);
			if (!(method != null))
			{
				return;
			}
			object[] array = new object[2]
			{
				(ushort)70,
				null
			};
			if (!(bool)method.Invoke(null, array) || array[1] == null)
			{
				return;
			}
			object obj = array[1];
			Item val = (Item)((obj is Item) ? obj : null);
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			FieldInfo field2 = typeof(Item).GetField("localizationKey", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 != null)
			{
				field2.SetValue(val, "NAME_AK");
				Log.LogInfo((object)"[AK47] Set blowgun localizationKey to NAME_AK");
			}
			FieldInfo field3 = typeof(Item).GetField("titleKey", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field3 != null)
			{
				field3.SetValue(val, "NAME_AK");
				Log.LogInfo((object)"[AK47] Set blowgun titleKey to NAME_AK");
			}
			if (_ak47ItemContent == null || !((Object)(object)_ak47Prefab != (Object)null))
			{
				return;
			}
			GameObject ak47Prefab = _ak47Prefab;
			FieldInfo field4 = typeof(Item).GetField("icon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field4 != null)
			{
				object value2 = field4.GetValue(ak47Prefab);
				if (value2 != null)
				{
					field4.SetValue(val, value2);
					Log.LogInfo((object)"[AK47] Replaced blowgun icon with AK47 icon");
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] ReplaceBlowgunLocalization error: " + ex));
		}
	}

	private void ReplaceBlowgunInstances()
	{
	}

	private void ReplaceBlowgunInstances_Old()
	{
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_ak47Prefab == (Object)null)
		{
			return;
		}
		try
		{
			Item[] array = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
			int num = 0;
			Item[] array2 = array;
			foreach (Item val in array2)
			{
				if (_replacedBlowguns.Contains(((Component)val).gameObject))
				{
					continue;
				}
				string name = val.GetName();
				string name2 = ((Object)((Component)val).gameObject).name;
				if ((name == null || !name.Contains("吹箭筒")) && (name == null || !name.Contains("Blowgun")) && (name == null || !name.Contains("HealingDart")) && (name == null || !name.Contains("Dart")) && (name2 == null || !name2.Contains("HealingDart")) && (name2 == null || !name2.Contains("Dart")))
				{
					continue;
				}
				Log.LogInfo((object)("[AK47] Found blowgun item: " + name + ", gameObject: " + name2 + ", replacing model"));
				MeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if (!((Object)val2).name.Contains("Hand"))
					{
						((Renderer)val2).enabled = false;
						Log.LogInfo((object)("[AK47] Disabled MeshRenderer: " + ((Object)val2).name));
					}
				}
				SkinnedMeshRenderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<SkinnedMeshRenderer>();
				foreach (SkinnedMeshRenderer val3 in componentsInChildren2)
				{
					if (!((Object)val3).name.Contains("Hand"))
					{
						((Renderer)val3).enabled = false;
						Log.LogInfo((object)("[AK47] Disabled SkinnedMeshRenderer: " + ((Object)val3).name));
					}
				}
				GameObject val4 = Object.Instantiate<GameObject>(_ak47Prefab, ((Component)val).transform);
				val4.transform.localPosition = Vector3.zero;
				val4.transform.localRotation = Quaternion.identity;
				val4.transform.localScale = Vector3.one;
				componentsInChildren = val4.GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val5 in componentsInChildren)
				{
					((Renderer)val5).enabled = true;
					Log.LogInfo((object)("[AK47] Enabled MeshRenderer on AK47: " + ((Object)val5).name));
				}
				componentsInChildren2 = val4.GetComponentsInChildren<SkinnedMeshRenderer>();
				foreach (SkinnedMeshRenderer val6 in componentsInChildren2)
				{
					((Renderer)val6).enabled = true;
					Log.LogInfo((object)("[AK47] Enabled SkinnedMeshRenderer on AK47: " + ((Object)val6).name));
				}
				Log.LogInfo((object)"[AK47] Instantiated AK47 prefab as child of blowgun");
				_replacedBlowguns.Add(((Component)val).gameObject);
				num++;
			}
			if (num > 0)
			{
				Log.LogInfo((object)$"[AK47] Replaced {num} blowgun instances with AK47 model");
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] ReplaceBlowgunInstances error: " + ex));
		}
	}

	[IteratorStateMachine(typeof(<DelayedReplaceBlowgunModel>d__109))]
	private static IEnumerator DelayedReplaceBlowgunModel()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DelayedReplaceBlowgunModel>d__109(0);
	}

	private void ReplaceBlowgunSound()
	{
		try
		{
			MethodInfo method = typeof(ItemDatabase).GetMethod("TryGetItem", BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				return;
			}
			object[] array = new object[2]
			{
				(ushort)70,
				null
			};
			if (!(bool)method.Invoke(null, array) || array[1] == null)
			{
				return;
			}
			object obj = array[1];
			Type type = obj.GetType();
			FieldInfo field = type.GetField("prefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				field = type.GetField("_prefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (!(field != null) || !((Object)(object)_gunshotSound != (Object)null))
			{
				return;
			}
			object? value = field.GetValue(obj);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val2 in componentsInChildren)
			{
				if ((Object)(object)val2.clip != (Object)null)
				{
					val2.clip = _gunshotSound;
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] ReplaceBlowgunSound error: " + ex));
		}
	}

	private void ListAllItems()
	{
		try
		{
			FieldInfo field = typeof(ItemDatabase).GetField("items", BindingFlags.Static | BindingFlags.Public);
			if (!(field != null) || !(field.GetValue(null) is IDictionary dictionary))
			{
				return;
			}
			Debug.Log((object)"[AK47] === Listing all items ===");
			Log.LogInfo((object)"[AK47] === Listing all items ===");
			foreach (DictionaryEntry item in dictionary)
			{
				object key = item.Key;
				object? value = item.Value;
				Item val = (Item)((value is Item) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					string name = val.GetName();
					Debug.Log((object)("[AK47] Item ID: " + key?.ToString() + " Name: " + name));
					Log.LogInfo((object)("[AK47] Item ID: " + key?.ToString() + " Name: " + name));
				}
			}
			Debug.Log((object)"[AK47] === End of item list ===");
			Log.LogInfo((object)"[AK47] === End of item list ===");
		}
		catch (Exception ex)
		{
			Debug.Log((object)("[AK47] ListAllItems error: " + ex));
			Log.LogError((object)("[AK47] ListAllItems error: " + ex));
		}
	}

	[IteratorStateMachine(typeof(<PeriodicPlayerScan>d__112))]
	private IEnumerator PeriodicPlayerScan()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PeriodicPlayerScan>d__112(0);
	}

	private static bool IsAlive(Character c)
	{
		if ((Object)(object)c == (Object)null)
		{
			return false;
		}
		try
		{
			CharacterData data = c.data;
			if ((Object)(object)data == (Object)null)
			{
				return true;
			}
			FieldInfo field = ((object)data).GetType().GetField("dead", BindingFlags.Instance | BindingFlags.Public);
			if (field != null)
			{
				return !(bool)field.GetValue(data);
			}
			return true;
		}
		catch
		{
			return true;
		}
	}

	private static bool TryGiveItemTo(Character c)
	{
		try
		{
			Player player = c.player;
			if ((Object)(object)player == (Object)null || player.itemSlots == null)
			{
				Log.LogInfo((object)"[AK47] Player or itemSlots is null");
				return false;
			}
			int num = InventorySlot.Value;
			if (num < 0 || num >= player.itemSlots.Length)
			{
				Log.LogInfo((object)("[AK47] Invalid slot: " + num));
				return false;
			}
			if (!player.itemSlots[num].IsEmpty())
			{
				Log.LogInfo((object)("[AK47] Slot " + num + " is not empty, trying other slots..."));
				for (int i = 0; i < player.itemSlots.Length; i++)
				{
					if (player.itemSlots[i].IsEmpty())
					{
						num = i;
						Log.LogInfo((object)("[AK47] Found empty slot: " + num));
						break;
					}
				}
				if (!player.itemSlots[num].IsEmpty())
				{
					Log.LogInfo((object)"[AK47] No empty slots available");
					return false;
				}
			}
			Item val = null;
			MethodInfo method = typeof(ItemDatabase).GetMethod("TryGetItem", BindingFlags.Static | BindingFlags.Public);
			object[] array = new object[2] { ItemIdToGive.Value, null };
			bool num2 = (bool)method.Invoke(null, array);
			object obj = array[1];
			val = (Item)((obj is Item) ? obj : null);
			if (!num2 || (Object)(object)val == (Object)null)
			{
				Log.LogError((object)("[AK47] Item not found with ID: " + ItemIdToGive.Value));
				return false;
			}
			Log.LogInfo((object)("[AK47] Got item: " + val.GetName()));
			Type type = typeof(Item).Assembly.GetType("ItemInstanceData");
			object obj2 = type.GetConstructor(new Type[1] { typeof(Guid) }).Invoke(new object[1] { Guid.NewGuid() });
			FieldInfo field = type.GetField("data", BindingFlags.Instance | BindingFlags.Public);
			if (field != null)
			{
				object value = field.GetValue(obj2);
				MethodInfo method2 = value.GetType().GetMethod("Add");
				object obj3 = typeof(Item).Assembly.GetType("Item")?.GetField("UsesKey", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
				if (obj3 != null)
				{
					method2.Invoke(value, new object[2] { obj3, 999 });
					Log.LogInfo((object)"[AK47] Set uses to 999 via data dictionary");
				}
				else
				{
					Type type2 = typeof(Item).Assembly.GetType("Item+DataType");
					if (type2 != null)
					{
						object obj4 = Enum.Parse(type2, "Uses");
						method2.Invoke(value, new object[2] { obj4, 999 });
						Log.LogInfo((object)"[AK47] Set uses to 999 via enum");
					}
				}
			}
			typeof(Item).Assembly.GetType("ItemInstanceDataHandler").GetMethod("AddInstanceData", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[1] { obj2 });
			((object)player.itemSlots[num]).GetType().GetMethod("SetItem").Invoke(player.itemSlots[num], new object[2] { val, obj2 });
			Type type3 = typeof(Item).Assembly.GetType("InventorySyncData");
			Type type4 = typeof(Item).Assembly.GetType("InventorySyncData+SlotData");
			type4.MakeArrayType();
			List<object> list = new List<object>();
			ItemSlot[] itemSlots = player.itemSlots;
			foreach (ItemSlot val2 in itemSlots)
			{
				object obj5 = Activator.CreateInstance(type4);
				FieldInfo field2 = type4.GetField("item", BindingFlags.Instance | BindingFlags.Public);
				FieldInfo field3 = type4.GetField("data", BindingFlags.Instance | BindingFlags.Public);
				object value2 = ((object)val2).GetType().GetProperty("item")?.GetValue(val2);
				object value3 = ((object)val2).GetType().GetProperty("data")?.GetValue(val2);
				if (field2 != null)
				{
					field2.SetValue(obj5, value2);
				}
				if (field3 != null)
				{
					field3.SetValue(obj5, value3);
				}
				list.Add(obj5);
			}
			Array array2 = Array.CreateInstance(type4, list.Count);
			for (int k = 0; k < list.Count; k++)
			{
				array2.SetValue(list[k], k);
			}
			object value4 = ((object)player).GetType().GetField("backpackSlot")?.GetValue(player);
			object value5 = ((object)player).GetType().GetField("tempFullSlot")?.GetValue(player);
			object obj6 = Activator.CreateInstance(type3);
			FieldInfo field4 = type3.GetField("slots", BindingFlags.Instance | BindingFlags.Public);
			FieldInfo field5 = type3.GetField("backpackSlot", BindingFlags.Instance | BindingFlags.Public);
			FieldInfo field6 = type3.GetField("tempFullSlot", BindingFlags.Instance | BindingFlags.Public);
			if (field4 != null)
			{
				field4.SetValue(obj6, array2);
			}
			if (field5 != null)
			{
				field5.SetValue(obj6, value4);
			}
			if (field6 != null)
			{
				field6.SetValue(obj6, value5);
			}
			MethodInfo methodInfo = typeof(Item).Assembly.GetType("Zorro.Core.Serizalization.IBinarySerializable")?.GetMethod("ToManagedArray")?.MakeGenericMethod(type3);
			if (methodInfo != null)
			{
				object obj7 = methodInfo.Invoke(null, new object[1] { obj6 });
				c.refs.view.RPC("SyncInventoryRPC", (RpcTarget)0, new object[2] { obj7, false });
			}
			Log.LogInfo((object)("[AK47] Gave item to player " + c.characterName + " in slot " + num));
			Debug.Log((object)("[AK47] Successfully gave item to " + c.characterName));
			Log.LogInfo((object)("[AK47] Successfully gave item to " + c.characterName));
			if ((Object)(object)c.refs?.view != (Object)null)
			{
				_ = c.refs.view.IsMine;
				Log.LogInfo((object)$"[AK47] Checking IsMine: {c.refs.view.IsMine}, OwnerActorNr: {c.refs.view.OwnerActorNr}");
			}
			if (!c.isBot && !c.isZombie)
			{
				_localCharacter = c;
				_hasWeapon = true;
				Log.LogInfo((object)$"[AK47] Set local player: {c.characterName}, isBot={c.isBot}, isZombie={c.isZombie}");
			}
			return true;
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] TryGiveItemTo error: " + ex));
			return false;
		}
	}

	private void Update()
	{
		if (!_resourcesLoaded)
		{
			LoadResources();
		}
		ZombieSpawner.UpdateZombieTimers();
		UpdateZombieSpeed();
		CheckSpawnWeaponKey();
		if (Time.time - _lastModelReplaceTime >= 1f)
		{
			_lastModelReplaceTime = Time.time;
			ReplaceBlowgunInstances();
		}
		if (_hasWeapon && (Object)(object)_localCharacter != (Object)null)
		{
			if (Input.GetMouseButton(0) && Time.time - _lastFireTime >= FireInterval.Value)
			{
				TryFire();
			}
		}
		else if (Input.GetMouseButton(0) && Time.time - _lastFireTime >= FireInterval.Value)
		{
			Log.LogInfo((object)$"[AK47] Update: _hasWeapon={_hasWeapon}, _localCharacter={(Object)(object)_localCharacter != (Object)null}");
		}
	}

	private void CheckSpawnWeaponKey()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (Input.GetKeyDown(SpawnWeaponKey.Value))
			{
				if (PhotonNetwork.IsMasterClient && (Object)(object)_localCharacter != (Object)null)
				{
					SpawnWeaponAtPlayer();
					Log.LogInfo((object)$"[AK47] Spawn weapon key pressed: {SpawnWeaponKey.Value}");
				}
				else
				{
					Log.LogInfo((object)$"[AK47] Cannot spawn weapon: IsMasterClient={PhotonNetwork.IsMasterClient}, _localCharacter={(Object)(object)_localCharacter != (Object)null}");
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] CheckSpawnWeaponKey error: " + ex));
		}
	}

	private void SpawnWeaponAtPlayer()
	{
		try
		{
			if ((Object)(object)_localCharacter == (Object)null)
			{
				Log.LogWarning((object)"[AK47] Cannot spawn weapon: local character is null");
			}
			else if (TryGiveItemTo(_localCharacter))
			{
				Log.LogInfo((object)"[AK47] Gave weapon to local player via T key");
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] SpawnWeaponAtPlayer error: " + ex));
		}
	}

	private void UpdateZombieSpeed()
	{
		if (ZombieMoveSpeed.Value == 1f)
		{
			return;
		}
		try
		{
			Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
			foreach (Character val in array)
			{
				if (!val.isZombie && !val.isBot)
				{
					continue;
				}
				FieldInfo field = ((object)val).GetType().GetField("agent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					field = ((object)val).GetType().GetField("_agent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (field == null)
				{
					field = ((object)val).GetType().GetField("navMeshAgent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (!(field != null))
				{
					continue;
				}
				object value = field.GetValue(val);
				if (value == null)
				{
					continue;
				}
				PropertyInfo property = value.GetType().GetProperty("speed");
				if (property != null)
				{
					FieldInfo field2 = ((object)val).GetType().GetField("baseSpeed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 == null)
					{
						field2 = ((object)val).GetType().GetField("_baseSpeed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					}
					float num = 3.5f;
					if (field2 != null)
					{
						num = (float)field2.GetValue(val);
					}
					property.SetValue(value, num * ZombieMoveSpeed.Value);
				}
			}
		}
		catch
		{
		}
	}

	private void UpdateDartEffectColorsOnce()
	{
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Expected O, but got Unknown
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time - _lastMaterialUpdateTime < 5f)
		{
			return;
		}
		_lastMaterialUpdateTime = Time.time;
		try
		{
			Renderer[] array = Object.FindObjectsByType<Renderer>((FindObjectsSortMode)0);
			foreach (Renderer val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMaterial == (Object)null)
				{
					continue;
				}
				string name = ((Object)((Component)val).gameObject).name;
				if ((!name.Contains("Dart") && !name.Contains("Trail") && !name.Contains("Projectile")) || name.Contains("HealingDart") || name.Contains("Hand") || name.Contains("Blowgun"))
				{
					continue;
				}
				Material sharedMaterial = val.sharedMaterial;
				if (!_processedMaterials.Contains(sharedMaterial) && sharedMaterial.HasProperty("_Color") && sharedMaterial.GetColor("_Color") != Color.black)
				{
					Material val2 = new Material(sharedMaterial);
					val2.SetColor("_Color", Color.black);
					if (val2.HasProperty("_Tint"))
					{
						val2.SetColor("_Tint", Color.black);
					}
					val.sharedMaterial = val2;
					_processedMaterials.Add(val2);
				}
			}
		}
		catch
		{
		}
	}

	private void ReplaceBlowgunInstanceSound()
	{
		try
		{
			if ((Object)(object)_localCharacter != (Object)null)
			{
				FieldInfo field = ((object)_localCharacter).GetType().GetField("poofSFX", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.GetValue(_localCharacter) is Array array)
				{
					Debug.Log((object)("[AK47] Found " + array.Length + " poofSFX"));
					Log.LogInfo((object)("[AK47] Found " + array.Length + " poofSFX"));
					foreach (object item in array)
					{
						if (item == null)
						{
							continue;
						}
						Type type = item.GetType();
						Debug.Log((object)("[AK47] poofSFX type: " + type.FullName));
						Log.LogInfo((object)("[AK47] poofSFX type: " + type.FullName));
						Debug.Log((object)"[AK47] === SFX_Instance fields ===");
						Log.LogInfo((object)"[AK47] === SFX_Instance fields ===");
						FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (FieldInfo fieldInfo in fields)
						{
							Debug.Log((object)("[AK47] SFX Field: " + fieldInfo.Name + " (" + fieldInfo.FieldType.Name + ")"));
							Log.LogInfo((object)("[AK47] SFX Field: " + fieldInfo.Name + " (" + fieldInfo.FieldType.Name + ")"));
							if (fieldInfo.FieldType == typeof(AudioClip[]))
							{
								if (fieldInfo.GetValue(item) is AudioClip[] array2 && (Object)(object)_gunshotSound != (Object)null)
								{
									Debug.Log((object)("[AK47] Found AudioClip[] with " + array2.Length + " clips"));
									Log.LogInfo((object)("[AK47] Found AudioClip[] with " + array2.Length + " clips"));
									for (int j = 0; j < array2.Length; j++)
									{
										string[] obj = new string[6]
										{
											"[AK47] Replacing clip[",
											j.ToString(),
											"]: ",
											null,
											null,
											null
										};
										AudioClip obj2 = array2[j];
										obj[3] = ((obj2 != null) ? ((Object)obj2).name : null) ?? "null";
										obj[4] = " -> ";
										obj[5] = ((Object)_gunshotSound).name;
										Debug.Log((object)string.Concat(obj));
										ManualLogSource log = Log;
										string[] obj3 = new string[6]
										{
											"[AK47] Replacing clip[",
											j.ToString(),
											"]: ",
											null,
											null,
											null
										};
										AudioClip obj4 = array2[j];
										obj3[3] = ((obj4 != null) ? ((Object)obj4).name : null) ?? "null";
										obj3[4] = " -> ";
										obj3[5] = ((Object)_gunshotSound).name;
										log.LogInfo((object)string.Concat(obj3));
										array2[j] = _gunshotSound;
									}
								}
							}
							else if (fieldInfo.FieldType == typeof(AudioClip))
							{
								object? value = fieldInfo.GetValue(item);
								AudioClip val = (AudioClip)((value is AudioClip) ? value : null);
								Debug.Log((object)("[AK47] Found AudioClip in poofSFX: " + fieldInfo.Name + " = " + (((val != null) ? ((Object)val).name : null) ?? "null")));
								Log.LogInfo((object)("[AK47] Found AudioClip in poofSFX: " + fieldInfo.Name + " = " + (((val != null) ? ((Object)val).name : null) ?? "null")));
								if ((Object)(object)_gunshotSound != (Object)null)
								{
									fieldInfo.SetValue(item, _gunshotSound);
									Debug.Log((object)("[AK47] Replaced poofSFX sound to " + ((Object)_gunshotSound).name));
									Log.LogInfo((object)("[AK47] Replaced poofSFX sound to " + ((Object)_gunshotSound).name));
								}
							}
						}
						PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (PropertyInfo propertyInfo in properties)
						{
							if (!(propertyInfo.PropertyType == typeof(AudioClip)))
							{
								continue;
							}
							try
							{
								object? value2 = propertyInfo.GetValue(item);
								AudioClip val2 = (AudioClip)((value2 is AudioClip) ? value2 : null);
								Debug.Log((object)("[AK47] Found AudioClip property in poofSFX: " + propertyInfo.Name + " = " + (((val2 != null) ? ((Object)val2).name : null) ?? "null")));
								Log.LogInfo((object)("[AK47] Found AudioClip property in poofSFX: " + propertyInfo.Name + " = " + (((val2 != null) ? ((Object)val2).name : null) ?? "null")));
								if ((Object)(object)_gunshotSound != (Object)null && propertyInfo.CanWrite)
								{
									propertyInfo.SetValue(item, _gunshotSound);
									Debug.Log((object)("[AK47] Replaced poofSFX sound property to " + ((Object)_gunshotSound).name));
									Log.LogInfo((object)("[AK47] Replaced poofSFX sound property to " + ((Object)_gunshotSound).name));
								}
							}
							catch
							{
							}
						}
					}
				}
			}
			Item[] array3 = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
			foreach (Item val3 in array3)
			{
				string name = val3.GetName();
				if ((name == null || !name.Contains("吹箭筒")) && (name == null || !name.Contains("Blowgun")) && (name == null || !name.Contains("HealingDart")) && (name == null || !name.Contains("Dart")))
				{
					continue;
				}
				AudioSource[] componentsInChildren = ((Component)val3).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val4 in componentsInChildren)
				{
					if ((Object)(object)val4.clip != (Object)null && (Object)(object)_gunshotSound != (Object)null)
					{
						Debug.Log((object)("[AK47] Found AudioSource with clip: " + ((Object)val4.clip).name));
						Log.LogInfo((object)("[AK47] Found AudioSource with clip: " + ((Object)val4.clip).name));
						val4.clip = _gunshotSound;
						Debug.Log((object)("[AK47] Replaced AudioSource clip to " + ((Object)_gunshotSound).name));
						Log.LogInfo((object)("[AK47] Replaced AudioSource clip to " + ((Object)_gunshotSound).name));
					}
				}
				Type type2 = typeof(Item).Assembly.GetType("SFX_Instance");
				if (!(type2 != null))
				{
					continue;
				}
				Component[] componentsInChildren2 = ((Component)val3).GetComponentsInChildren(type2, true);
				Debug.Log((object)("[AK47] Found " + componentsInChildren2.Length + " SFX_Instance components"));
				Log.LogInfo((object)("[AK47] Found " + componentsInChildren2.Length + " SFX_Instance components"));
				Component[] array4 = componentsInChildren2;
				foreach (Component val5 in array4)
				{
					FieldInfo[] fields = ((object)val5).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo2 in fields)
					{
						if (fieldInfo2.FieldType == typeof(AudioClip))
						{
							object? value3 = fieldInfo2.GetValue(val5);
							AudioClip val6 = (AudioClip)((value3 is AudioClip) ? value3 : null);
							Debug.Log((object)("[AK47] Found AudioClip in SFX_Instance: " + fieldInfo2.Name + " = " + (((val6 != null) ? ((Object)val6).name : null) ?? "null")));
							Log.LogInfo((object)("[AK47] Found AudioClip in SFX_Instance: " + fieldInfo2.Name + " = " + (((val6 != null) ? ((Object)val6).name : null) ?? "null")));
							if ((Object)(object)_gunshotSound != (Object)null)
							{
								fieldInfo2.SetValue(val5, _gunshotSound);
								Debug.Log((object)("[AK47] Replaced SFX_Instance sound to " + ((Object)_gunshotSound).name));
								Log.LogInfo((object)("[AK47] Replaced SFX_Instance sound to " + ((Object)_gunshotSound).name));
							}
						}
					}
				}
			}
		}
		catch (Exception ex)
		{
			Debug.Log((object)("[AK47] ReplaceBlowgunInstanceSound error: " + ex));
			Log.LogError((object)("[AK47] ReplaceBlowgunInstanceSound error: " + ex));
		}
	}

	private bool IsHoldingBlowgun()
	{
		try
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return false;
			}
			FieldInfo field = ((object)localCharacter).GetType().GetField("refs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				Log.LogInfo((object)"[AK47] refs field not found");
				return false;
			}
			object value = field.GetValue(localCharacter);
			if (value == null)
			{
				Log.LogInfo((object)"[AK47] refs is null");
				return false;
			}
			FieldInfo field2 = value.GetType().GetField("items", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 == null)
			{
				Log.LogInfo((object)"[AK47] items field not found in refs");
				return false;
			}
			object value2 = field2.GetValue(value);
			if (value2 == null)
			{
				Log.LogInfo((object)"[AK47] items is null");
				return false;
			}
			FieldInfo field3 = value2.GetType().GetField("currentSelectedSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field3 == null)
			{
				Log.LogInfo((object)"[AK47] currentSelectedSlot field not found");
				return false;
			}
			object value3 = field3.GetValue(value2);
			if (value3 == null)
			{
				Log.LogInfo((object)"[AK47] currentSelectedSlot is null");
				return false;
			}
			PropertyInfo property = value3.GetType().GetProperty("HasValue", BindingFlags.Instance | BindingFlags.Public);
			if (property != null && !(bool)property.GetValue(value3))
			{
				Log.LogInfo((object)"[AK47] No slot selected");
				return false;
			}
			PropertyInfo property2 = value3.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public);
			if (property2 == null)
			{
				Log.LogInfo((object)"[AK47] Value property not found");
				return false;
			}
			byte b = (byte)property2.GetValue(value3);
			Log.LogInfo((object)$"[AK47] Selected slot index: {b}");
			Player player = localCharacter.player;
			if ((Object)(object)player == (Object)null)
			{
				Log.LogInfo((object)"[AK47] player is null");
				return false;
			}
			FieldInfo field4 = ((object)player).GetType().GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field4 == null)
			{
				Log.LogInfo((object)"[AK47] itemSlots field not found");
				return false;
			}
			if (!(field4.GetValue(player) is Array array) || array.Length <= b)
			{
				Log.LogInfo((object)"[AK47] itemSlots is null or index out of range");
				return false;
			}
			object value4 = array.GetValue(b);
			if (value4 == null)
			{
				Log.LogInfo((object)"[AK47] slot is null");
				return false;
			}
			Log.LogInfo((object)("[AK47] slot type: " + value4.GetType().Name));
			FieldInfo[] fields = value4.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				Log.LogInfo((object)("[AK47] slot field: " + fieldInfo.Name + " (" + fieldInfo.FieldType.Name + ")"));
			}
			FieldInfo field5 = value4.GetType().GetField("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field5 == null)
			{
				field5 = value4.GetType().GetField("_item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (field5 == null)
			{
				field5 = value4.GetType().GetField("prefab", BindingFlags.Instance | BindingFlags.Public);
			}
			if (field5 == null)
			{
				Log.LogInfo((object)"[AK47] itemField not found in slot");
				return false;
			}
			object? value5 = field5.GetValue(value4);
			Item val = (Item)((value5 is Item) ? value5 : null);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogInfo((object)"[AK47] currentItem is null");
				return false;
			}
			string name = val.GetName();
			Log.LogInfo((object)("[AK47] Current item: " + name));
			if ((name != null && name.Contains("吹箭筒")) || (name != null && name.Contains("Blowgun")) || (name != null && name.Contains("HealingDart")) || (name != null && name.Contains("Dart")))
			{
				return true;
			}
		}
		catch (Exception ex)
		{
			Debug.Log((object)("[AK47] IsHoldingBlowgun error: " + ex));
			Log.LogError((object)("[AK47] IsHoldingBlowgun error: " + ex));
		}
		return false;
	}

	private void TryFire()
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		_lastFireTime = Time.time;
		try
		{
			if (!IsHoldingBlowgun())
			{
				Log.LogInfo((object)"[AK47] TryFire: not holding blowgun");
				return;
			}
			float blowgunCastProgress = GetBlowgunCastProgress();
			Log.LogInfo((object)$"[AK47] TryFire: castProgress={blowgunCastProgress}");
			if (blowgunCastProgress < 0.99f)
			{
				Log.LogInfo((object)"[AK47] TryFire: not fully charged, skipping");
				return;
			}
			Log.LogInfo((object)"[AK47] TryFire: firing!");
			Vector3 position = ((Component)_localCharacter.refs.view).transform.position;
			Vector3 forward = ((Component)Camera.main).transform.forward;
			_ = position + forward * MaxDistance.Value;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(position, forward, ref val, MaxDistance.Value))
			{
				_ = ((RaycastHit)(ref val)).point;
				ManualLogSource log = Log;
				Collider collider = ((RaycastHit)(ref val)).collider;
				log.LogInfo((object)("[AK47] Raycast hit: " + ((collider != null) ? ((Object)collider).name : null)));
				Collider collider2 = ((RaycastHit)(ref val)).collider;
				Character val2 = ((collider2 != null) ? ((Component)collider2).GetComponentInParent<Character>() : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)_localCharacter)
				{
					Log.LogInfo((object)$"[AK47] Hit character: {val2.characterName}, isZombie={val2.isZombie}, isBot={val2.isBot}");
					if (val2.isZombie || val2.isBot)
					{
						HitZombie(val2);
					}
					else
					{
						HitPlayer(val2);
					}
				}
			}
			if ((Object)(object)_gunshotSound != (Object)null && (Object)(object)_localCharacter != (Object)null)
			{
				PlayGunshotSound(((Component)_localCharacter).transform.position);
				Log.LogInfo((object)$"[AK47] Played gunshot sound at: {((Component)_localCharacter).transform.position}");
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] TryFire error: " + ex));
		}
	}

	private float GetBlowgunCastProgress()
	{
		try
		{
			if ((Object)(object)_localCharacter == (Object)null)
			{
				return 0f;
			}
			Item[] array = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
			foreach (Item val in array)
			{
				string name = val.GetName();
				string name2 = ((Object)((Component)val).gameObject).name;
				if ((name == null || !name.Contains("吹箭筒")) && (name == null || !name.Contains("Blowgun")) && (name == null || !name.Contains("HealingDart")) && (name == null || !name.Contains("Dart")) && (name2 == null || !name2.Contains("HealingDart")) && (name2 == null || !name2.Contains("Dart")))
				{
					continue;
				}
				FieldInfo field = ((object)val).GetType().GetField("<itemState>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field != null))
				{
					continue;
				}
				object value = field.GetValue(val);
				if (value != null && value.ToString() == "Held")
				{
					FieldInfo field2 = ((object)val).GetType().GetField("<castProgress>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						return (float)field2.GetValue(val);
					}
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] GetBlowgunCastProgress error: " + ex.Message));
		}
		return 0f;
	}

	public void HitZombie(Character zombie)
	{
		try
		{
			Log.LogInfo((object)("[AK47] HitZombie called for: " + zombie.characterName));
			MushroomZombie component = ((Component)zombie).GetComponent<MushroomZombie>();
			if ((Object)(object)component != (Object)null)
			{
				FieldInfo field = ((object)component).GetType().GetField("survivalTime", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					field = ((object)component).GetType().GetField("lifetime", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (field == null)
				{
					field = ((object)component).GetType().GetField("_survivalTime", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (field == null)
				{
					field = ((object)component).GetType().GetField("_lifetime", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (field != null)
				{
					float num = (float)field.GetValue(component);
					float num2 = num - ZombieTimeReduction.Value;
					field.SetValue(component, num2);
					Log.LogInfo((object)$"[AK47] Zombie survival time: {num} -> {num2}");
					if (num2 <= 0f)
					{
						((MonoBehaviour)this).StartCoroutine(DestroyZombieAfterDelay(zombie, 3f));
					}
					return;
				}
				Log.LogWarning((object)"[AK47] Could not find survival time field in MushroomZombie");
				FieldInfo[] fields = ((object)component).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					if (fieldInfo.FieldType == typeof(float))
					{
						Log.LogInfo((object)("[AK47] Found float field: " + fieldInfo.Name));
					}
				}
			}
			else
			{
				Log.LogWarning((object)"[AK47] No MushroomZombie component found");
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] HitZombie error: " + ex));
		}
	}

	[IteratorStateMachine(typeof(<DestroyZombieAfterDelay>d__129))]
	private IEnumerator DestroyZombieAfterDelay(Character zombie, float delay)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DestroyZombieAfterDelay>d__129(0)
		{
			zombie = zombie,
			delay = delay
		};
	}

	public void HitPlayer(Character player)
	{
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			CharacterRefs refs = player.refs;
			if (refs != null)
			{
				FieldInfo field = ((object)refs).GetType().GetField("emote", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object value = field.GetValue(refs);
					if (value != null)
					{
						MethodInfo method = value.GetType().GetMethod("PlayEmote");
						if (method != null)
						{
							int num = Array.IndexOf(Enum.GetNames(value.GetType().Assembly.GetType(value.GetType().Namespace + ".EmoteType")), "Sleep");
							if (num >= 0)
							{
								method.Invoke(value, new object[1] { num });
								Log.LogInfo((object)("[AK47] HitPlayer: " + player.characterName + " playing Sleep emote"));
							}
						}
					}
				}
			}
			foreach (Bodypart part in player.refs.ragdoll.partList)
			{
				part.AddForce(Vector3.down * 5f, (ForceMode)1);
			}
			Log.LogInfo((object)("[AK47] HitPlayer: " + player.characterName + " ragdolled"));
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[AK47] HitPlayer error: " + ex));
		}
	}
}
[HarmonyPatch]
public class ItemPatch
{
	private static HashSet<GameObject> _processedItems = new HashSet<GameObject>();

	private static bool IsAk47Item(Item item)
	{
		if ((Object)(object)item == (Object)null)
		{
			return false;
		}
		string name = item.GetName();
		string name2 = ((Object)((Component)item).gameObject).name;
		if ((name == null || !name.Contains("吹箭筒")) && (name == null || !name.Contains("Blowgun")) && (name == null || !name.Contains("Blowdart")) && (name == null || !name.Contains("HealingDart")))
		{
			return name2?.Contains("HealingDart") ?? false;
		}
		return true;
	}
}
[HarmonyPatch]
public class BlowgunPatch
{
	private static float _lastCastProgress;

	private static float _lastShotTime;

	private static bool _waitingForReset;

	[HarmonyPatch(typeof(Character), "Update")]
	[HarmonyPostfix]
	public static void CharacterUpdatePostfix(Character __instance)
	{
		//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0631: Unknown result type (might be due to invalid IL or missing references)
		//IL_063d: Unknown result type (might be due to invalid IL or missing references)
		//IL_063f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0662: Unknown result type (might be due to invalid IL or missing references)
		//IL_0664: Unknown result type (might be due to invalid IL or missing references)
		//IL_062a: Unknown result type (might be due to invalid IL or missing references)
		//IL_062f: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Character.localCharacter)
			{
				return;
			}
			FieldInfo field = ((object)__instance).GetType().GetField("refs", BindingFlags.Instance | BindingFlags.Public);
			if (field == null)
			{
				return;
			}
			object value = field.GetValue(__instance);
			if (value == null)
			{
				return;
			}
			FieldInfo field2 = value.GetType().GetField("items", BindingFlags.Instance | BindingFlags.Public);
			if (field2 == null)
			{
				return;
			}
			object value2 = field2.GetValue(value);
			if (value2 == null)
			{
				return;
			}
			Item val = null;
			FieldInfo field3 = value2.GetType().GetField("currentSelectedSlot", BindingFlags.Instance | BindingFlags.Public);
			if (field3 != null)
			{
				object value3 = field3.GetValue(value2);
				if (value3 != null)
				{
					PropertyInfo property = value3.GetType().GetProperty("HasValue", BindingFlags.Instance | BindingFlags.Public);
					PropertyInfo property2 = value3.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public);
					if (property != null && property2 != null && (bool)property.GetValue(value3))
					{
						object value4 = property2.GetValue(value3);
						if (value4 != null)
						{
							byte b = Convert.ToByte(value4);
							Player player = __instance.player;
							if ((Object)(object)player != (Object)null)
							{
								FieldInfo field4 = ((object)player).GetType().GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
								if (field4 != null && field4.GetValue(player) is Array array && b < array.Length)
								{
									object value5 = array.GetValue(b);
									if (value5 != null)
									{
										FieldInfo field5 = value5.GetType().GetField("prefab", BindingFlags.Instance | BindingFlags.Public);
										if (field5 != null)
										{
											object? value6 = field5.GetValue(value5);
											val = (Item)((value6 is Item) ? value6 : null);
										}
									}
								}
							}
						}
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				FieldInfo field6 = value2.GetType().GetField("lastSelectedSlot", BindingFlags.Instance | BindingFlags.Public);
				if (field6 != null)
				{
					object value7 = field6.GetValue(value2);
					if (value7 != null)
					{
						PropertyInfo property3 = value7.GetType().GetProperty("HasValue", BindingFlags.Instance | BindingFlags.Public);
						PropertyInfo property4 = value7.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public);
						if (property3 != null && property4 != null && (bool)property3.GetValue(value7))
						{
							object value8 = property4.GetValue(value7);
							if (value8 != null)
							{
								byte b2 = Convert.ToByte(value8);
								Player player2 = __instance.player;
								if ((Object)(object)player2 != (Object)null)
								{
									FieldInfo field7 = ((object)player2).GetType().GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
									if (field7 != null && field7.GetValue(player2) is Array array2 && b2 < array2.Length)
									{
										object value9 = array2.GetValue(b2);
										if (value9 != null)
										{
											FieldInfo field8 = value9.GetType().GetField("prefab", BindingFlags.Instance | BindingFlags.Public);
											if (field8 != null)
											{
												object? value10 = field8.GetValue(value9);
												val = (Item)((value10 is Item) ? value10 : null);
											}
										}
									}
								}
							}
						}
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				PropertyInfo property5 = value2.GetType().GetProperty("currentItem", BindingFlags.Instance | BindingFlags.Public);
				if (property5 != null)
				{
					object? value11 = property5.GetValue(value2);
					val = (Item)((value11 is Item) ? value11 : null);
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Player player3 = __instance.player;
				if ((Object)(object)player3 != (Object)null)
				{
					FieldInfo field9 = ((object)player3).GetType().GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field9 != null && field9.GetValue(player3) is Array array3)
					{
						for (byte b3 = 0; b3 < array3.Length; b3++)
						{
							object value12 = array3.GetValue(b3);
							if (value12 != null)
							{
								FieldInfo field10 = value12.GetType().GetField("prefab", BindingFlags.Instance | BindingFlags.Public);
								if (field10 != null)
								{
									object? value13 = field10.GetValue(value12);
									Item val2 = (Item)((value13 is Item) ? value13 : null);
									if ((Object)(object)val2 != (Object)null)
									{
										string name = val2.GetName();
										if ((name != null && name.Contains("吹箭筒")) || (name != null && name.Contains("Blowgun")) || (name != null && name.Contains("HealingDart")) || (name != null && name.Contains("Dart")))
										{
											val = val2;
											break;
										}
									}
								}
							}
						}
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Item val3 = null;
			Item[] array4 = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
			foreach (Item val4 in array4)
			{
				string name2 = val4.GetName();
				if ((name2 == null || !name2.Contains("吹箭筒")) && (name2 == null || !name2.Contains("Blowgun")) && (name2 == null || !name2.Contains("HealingDart")) && (name2 == null || !name2.Contains("Dart")))
				{
					continue;
				}
				FieldInfo field11 = ((object)val4).GetType().GetField("<itemState>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field11 != null)
				{
					object value14 = field11.GetValue(val4);
					if (value14 != null && value14.ToString() == "Held")
					{
						val3 = val4;
						break;
					}
				}
			}
			if ((Object)(object)val3 == (Object)null)
			{
				return;
			}
			Type type = ((object)val3).GetType();
			FieldInfo field12 = type.GetField("<castProgress>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field12 != null))
			{
				return;
			}
			float num = (float)field12.GetValue(val3);
			if (_waitingForReset)
			{
				if (num < 0.1f)
				{
					_waitingForReset = false;
					_lastCastProgress = 0f;
					Debug.Log((object)"[AK47] Reset complete!");
					Plugin.Log.LogInfo((object)"[AK47] Reset complete!");
				}
			}
			else if (num >= 0.99f && _lastCastProgress < 0.99f)
			{
				_lastShotTime = Time.time;
				_waitingForReset = true;
				Debug.Log((object)"[AK47] Shot fired!");
				Plugin.Log.LogInfo((object)"[AK47] Shot fired!");
				if ((Object)(object)Plugin._gunshotSound != (Object)null)
				{
					Vector3 position = ((Component)__instance).transform.position;
					if ((Object)(object)__instance.refs?.head != (Object)null)
					{
						position = ((Component)__instance.refs.head).transform.position;
					}
					Plugin.PlayGunshotSound(position);
					Vector3 val5 = position;
					Debug.Log((object)("[AK47] Played gunshot sound at: " + ((object)(Vector3)(ref val5)).ToString()));
					ManualLogSource log = Plugin.Log;
					val5 = position;
					log.LogInfo((object)("[AK47] Played gunshot sound at: " + ((object)(Vector3)(ref val5)).ToString()));
				}
				FieldInfo field13 = type.GetField("OnPrimaryFinishedCast", BindingFlags.Instance | BindingFlags.Public);
				if (field13 != null && field13.GetValue(val3) is Action action)
				{
					Debug.Log((object)"[AK47] Invoking OnPrimaryFinishedCast");
					Plugin.Log.LogInfo((object)"[AK47] Invoking OnPrimaryFinishedCast");
					action();
				}
				field12.SetValue(val3, 0f);
				_lastCastProgress = 0f;
			}
			else
			{
				_lastCastProgress = num;
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("[AK47] CharacterUpdatePostfix error: " + ex.Message));
		}
	}
}
[HarmonyPatch]
public class ChargeBarUIPatch
{
	private static List<GameObject> _scaledObjects = new List<GameObject>();

	[HarmonyPatch(typeof(Slider), "OnEnable")]
	[HarmonyPostfix]
	public static void ScaleChargeBar(Slider __instance)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (_scaledObjects.Contains(((Component)__instance).gameObject))
			{
				return;
			}
			float num = Plugin.ChargeBarScale?.Value ?? 0.5f;
			if (!(num <= 0f) && !(num >= 1f))
			{
				RectTransform component = ((Component)__instance).GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					((Transform)component).localScale = new Vector3(num, num, num);
					_scaledObjects.Add(((Component)__instance).gameObject);
					Plugin.Log.LogInfo((object)$"[AK47] Scaled slider: {((Object)__instance).name} to {num}");
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("[AK47] ScaleChargeBar error: " + ex.Message));
		}
	}
}
[HarmonyPatch]
public class BlowgunInfiniteUsePatch
{
	private static MethodBase TargetMethod()
	{
		MethodInfo[] methods = typeof(Item).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
		foreach (MethodInfo methodInfo in methods)
		{
			if (methodInfo.Name.Contains("Use") || methodInfo.Name.Contains("Fire") || methodInfo.Name.Contains("Shoot"))
			{
				return methodInfo;
			}
		}
		return null;
	}

	private static void Postfix(Item __instance)
	{
		try
		{
			string name = __instance.GetName();
			if ((name == null || !name.Contains("吹箭筒")) && (name == null || !name.Contains("Blowgun")) && (name == null || !name.Contains("HealingDart")) && (name == null || !name.Contains("Dart")))
			{
				return;
			}
			MethodInfo methodInfo = (from m in typeof(Item).GetMethods(BindingFlags.Instance | BindingFlags.Public)
				where m.Name == "GetData"
				select m).ToList().FirstOrDefault((MethodInfo m) => m.IsGenericMethod);
			if (methodInfo != null)
			{
				Type type = typeof(Item).Assembly.GetTypes().FirstOrDefault((Type t) => t.Name == "OptionableIntItemData");
				if (type != null)
				{
					MethodInfo methodInfo2 = methodInfo.MakeGenericMethod(type);
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					object[] array = new object[parameters.Length];
					for (int i = 0; i < parameters.Length; i++)
					{
						if (parameters[i].ParameterType == typeof(DataEntryKey))
						{
							array[i] = (object)(DataEntryKey)2;
						}
						else
						{
							array[i] = null;
						}
					}
					object obj = methodInfo2.Invoke(__instance, array);
					if (obj != null)
					{
						FieldInfo field = obj.GetType().GetField("Value", BindingFlags.Instance | BindingFlags.Public);
						if (field != null)
						{
							field.SetValue(obj, 9999);
						}
					}
				}
			}
			Type type2 = ((object)__instance).GetType();
			float num = Plugin.FireInterval?.Value ?? 0.5f;
			FieldInfo field2 = type2.GetField("usingTimePrimary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 != null)
			{
				field2.SetValue(__instance, num);
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("[AK47] BlowgunInfiniteUsePatch error: " + ex.Message));
		}
	}
}
[HarmonyPatch]
public static class DartImpactPatch
{
	private static MethodBase _targetMethod;

	public static MethodBase TargetMethod()
	{
		if (_targetMethod != null)
		{
			return _targetMethod;
		}
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type[] types = assembly.GetTypes();
					foreach (Type type in types)
					{
						if (!(type == null) && typeof(MonoBehaviour).IsAssignableFrom(type))
						{
							MethodInfo method = type.GetMethod("RPC_DartImpact", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							if (method != null)
							{
								Plugin.Log.LogInfo((object)("[AK47] Found RPC_DartImpact in type: " + type.FullName));
								_targetMethod = method;
								return _targetMethod;
							}
						}
					}
				}
				catch
				{
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("[AK47] DartImpactPatch TargetMethod error: " + ex));
		}
		return null;
	}

	[HarmonyPrefix]
	public static bool DartImpactPrefix(MonoBehaviour __instance, int characterID, Vector3 origin, Vector3 endpoint, PhotonMessageInfo info)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		Plugin.Log.LogInfo((object)$"[AK47] DartImpactPrefix called: characterID={characterID}");
		try
		{
			FieldInfo field = ((object)__instance).GetType().GetField("dartVFX", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object? value = field.GetValue(__instance);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					Object.Instantiate<GameObject>(val, endpoint, Quaternion.identity);
					Plugin.Log.LogInfo((object)$"[AK47] Spawned dart VFX at: {endpoint}");
				}
			}
			if (characterID <= 0)
			{
				Plugin.Log.LogInfo((object)$"[AK47] DartImpactPrefix: characterID={characterID} hit collision, VFX spawned");
				return false;
			}
			PhotonView val2 = PhotonView.Find(characterID);
			if ((Object)(object)val2 != (Object)null)
			{
				Character componentInParent = ((Component)val2).gameObject.GetComponentInParent<Character>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					Plugin.Log.LogInfo((object)$"[AK47] DartImpactPrefix: Found character {componentInParent.characterName}, isZombie={componentInParent.isZombie}, isBot={componentInParent.isBot}");
					if (componentInParent.isZombie || componentInParent.isBot)
					{
						Plugin.Instance.HitZombie(componentInParent);
					}
					else
					{
						Plugin.Instance.HitPlayer(componentInParent);
					}
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("[AK47] DartImpactPrefix error: " + ex));
		}
		return false;
	}
}
[HarmonyPatch]
public static class DisableZombieSleepPatch
{
	[HarmonyPatch(typeof(Character), "Fall")]
	[HarmonyPrefix]
	public static bool FallPrefix(Character __instance)
	{
		if ((Object)(object)__instance == (Object)null)
		{
			return true;
		}
		Plugin.Log.LogInfo((object)$"[AK47] Fall called on: {__instance.characterName}, isBot={__instance.isBot}, isZombie={__instance.isZombie}");
		if (__instance.isBot || __instance.isZombie)
		{
			Plugin.Log.LogInfo((object)("[AK47] Blocked Fall on zombie/bot: " + __instance.characterName));
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(ItemCooking), "Wreck")]
public class BlowgunWreckPatch
{
	private static bool Prefix(ItemCooking __instance)
	{
		try
		{
			Item component = ((Component)__instance).GetComponent<Item>();
			if ((Object)(object)component != (Object)null)
			{
				string name = component.GetName();
				if ((name != null && name.Contains("吹箭筒")) || (name != null && name.Contains("Blowgun")) || (name != null && name.Contains("HealingDart")) || (name != null && name.Contains("Dart")))
				{
					return false;
				}
			}
		}
		catch
		{
		}
		return true;
	}
}
[HarmonyPatch]
public class BlowgunChargeSoundPatch
{
	private static MethodInfo _targetMethod;

	private static float _lastCastProgress;

	private static bool _hasPlayedGunshot;

	private static MethodBase TargetMethod()
	{
		if (_targetMethod == null)
		{
			Type type = typeof(Item).Assembly.GetType("SFX_Instance");
			if (type != null)
			{
				_targetMethod = type.GetMethod("Play", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(Vector3) }, null);
				if (_targetMethod == null)
				{
					_targetMethod = type.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "Play" && m.GetParameters().Length == 1);
				}
			}
		}
		return _targetMethod;
	}

	private static bool Prefix(object __instance)
	{
		try
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return true;
			}
			Player player = localCharacter.player;
			if ((Object)(object)player == (Object)null)
			{
				return true;
			}
			FieldInfo field = ((object)player).GetType().GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return true;
			}
			if (!(field.GetValue(player) is Array array))
			{
				return true;
			}
			bool flag = false;
			foreach (object item in array)
			{
				if (item == null)
				{
					continue;
				}
				FieldInfo field2 = item.GetType().GetField("prefab", BindingFlags.Instance | BindingFlags.Public);
				if (field2 == null)
				{
					continue;
				}
				object? value = field2.GetValue(item);
				Item val = (Item)((value is Item) ? value : null);
				if (!((Object)(object)val == (Object)null))
				{
					string name = val.GetName();
					if ((name != null && name.Contains("吹箭筒")) || (name != null && name.Contains("Blowgun")) || (name != null && name.Contains("HealingDart")) || (name != null && name.Contains("Dart")))
					{
						flag = true;
						break;
					}
				}
			}
			if (flag)
			{
				Item[] array2 = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
				foreach (Item val2 in array2)
				{
					string name2 = val2.GetName();
					string name3 = ((Object)((Component)val2).gameObject).name;
					if ((name2 == null || !name2.Contains("吹箭筒")) && (name2 == null || !name2.Contains("Blowgun")) && (name2 == null || !name2.Contains("HealingDart")) && (name2 == null || !name2.Contains("Dart")) && (name3 == null || !name3.Contains("HealingDart")) && (name3 == null || !name3.Contains("Dart")))
					{
						continue;
					}
					FieldInfo field3 = ((object)val2).GetType().GetField("<itemState>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (!(field3 != null))
					{
						continue;
					}
					object value2 = field3.GetValue(val2);
					if (value2 != null && value2.ToString() == "Held")
					{
						FieldInfo field4 = ((object)val2).GetType().GetField("<castProgress>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field4 != null)
						{
							float num = (float)field4.GetValue(val2);
							bool flag2 = _lastCastProgress >= 0.99f;
							bool flag3 = num >= 0.99f;
							_lastCastProgress = num;
							if (!flag3)
							{
								_hasPlayedGunshot = false;
								return false;
							}
							if (!flag2 && flag3 && !_hasPlayedGunshot)
							{
								_hasPlayedGunshot = true;
								Plugin.Log.LogInfo((object)"[AK47] Blowgun fully charged, allowing TryFire to play sound");
								return false;
							}
							return false;
						}
						break;
					}
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("[AK47] BlowgunChargeSoundPatch error: " + ex.Message));
		}
		return true;
	}
}
[HarmonyPatch(typeof(MushroomZombie), "Update")]
public static class ZombieDeathPatch
{
	[CompilerGenerated]
	private sealed class <DelayedDestroyZombie>d__2 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float delay;

		public GameObject zombieObj;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DelayedDestroyZombie>d__2(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)zombieObj != (Object)null)
				{
					_processedZombies.Remove(zombieObj);
					ZombieSpawner.RemoveZombie(zombieObj);
					if (PhotonNetwork.IsMasterClient)
					{
						PhotonView component = zombieObj.GetComponent<PhotonView>();
						if ((Object)(object)component != (Object)null)
						{
							PhotonNetwork.Destroy(component);
							Plugin.Log.LogInfo((object)"[AK47] Destroyed dead zombie via PhotonView");
						}
						else
						{
							Object.Destroy((Object)(object)zombieObj);
							Plugin.Log.LogInfo((object)"[AK47] Destroyed dead zombie locally");
						}
					}
				}
				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 HashSet<GameObject> _processedZombies = new HashSet<GameObject>();

	[HarmonyPostfix]
	public static void Postfix(MushroomZombie __instance)
	{
		if ((Object)(object)__instance == (Object)null)
		{
			return;
		}
		try
		{
			GameObject gameObject = ((Component)__instance).gameObject;
			if ((Object)(object)gameObject == (Object)null || _processedZombies.Contains(gameObject))
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			bool flag = false;
			if ((Object)(object)component.data != (Object)null && component.data.dead)
			{
				flag = true;
			}
			FieldInfo field = ((object)component).GetType().GetField("data", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value = field.GetValue(component);
				if (value != null)
				{
					FieldInfo field2 = value.GetType().GetField("dead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						flag = (bool)field2.GetValue(value);
					}
				}
			}
			if (flag)
			{
				_processedZombies.Add(gameObject);
				Plugin.Log.LogInfo((object)("[AK47] Zombie died detected: " + ((Object)gameObject).name + ", scheduling cleanup"));
				((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedDestroyZombie(gameObject, 3f));
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("[AK47] ZombieDeathPatch error: " + ex.Message));
		}
	}

	[IteratorStateMachine(typeof(<DelayedDestroyZombie>d__2))]
	private static IEnumerator DelayedDestroyZombie(GameObject zombieObj, float delay)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DelayedDestroyZombie>d__2(0)
		{
			zombieObj = zombieObj,
			delay = delay
		};
	}
}
public static class ZombieSpawner
{
	private struct ZombieTimer
	{
		public GameObject zombie;

		public float deathTime;
	}

	[CompilerGenerated]
	private sealed class <ZombieSpawnCoroutine>d__3 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <ZombieSpawnCoroutine>d__3(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(Plugin.ZombieSpawnDelay.Value);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				Plugin.Log.LogInfo((object)"[AK47] ZombieSpawnCoroutine started, spawning initial zombies...");
				SpawnZombiesAroundPlayers(Plugin.InitialZombieCount.Value);
				break;
			case 2:
				<>1__state = -1;
				if (PhotonNetwork.IsMasterClient)
				{
					SpawnZombiesAroundPlayers(Plugin.ZombieSpawnCount.Value);
				}
				break;
			}
			if (Plugin.ZombieSpawnEnabled.Value)
			{
				<>2__current = (object)new WaitForSeconds(Plugin.ZombieSpawnInterval.Value);
				<>1__state = 2;
				return true;
			}
			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 Coroutine _spawnCoroutine;

	private static HashSet<GameObject> _liveZombies = new HashSet<GameObject>();

	private static List<ZombieTimer> _zombieTimers = new List<ZombieTimer>();

	public static void StartZombieSpawning()
	{
		if (!Plugin.ZombieSpawnEnabled.Value)
		{
			Plugin.Log.LogInfo((object)"[AK47] Zombie spawning is disabled");
			return;
		}
		if (_spawnCoroutine != null)
		{
			((MonoBehaviour)Plugin.Instance).StopCoroutine(_spawnCoroutine);
		}
		_spawnCoroutine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(ZombieSpawnCoroutine());
		Plugin.Log.LogInfo((object)"[AK47] Zombie spawning started");
	}

	public static void StopZombieSpawning()
	{
		if (_spawnCoroutine != null)
		{
			((MonoBehaviour)Plugin.Instance).StopCoroutine(_spawnCoroutine);
			_spawnCoroutine = null;
		}
	}

	[IteratorStateMachine(typeof(<ZombieSpawnCoroutine>d__3))]
	private static IEnumerator ZombieSpawnCoroutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ZombieSpawnCoroutine>d__3(0);
	}

	private static void SpawnZombiesAroundPlayers(int count)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: 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)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		if (!PhotonNetwork.IsMasterClient)
		{
			return;
		}
		try
		{
			int currentZombieCount = GetCurrentZombieCount();
			int value = Plugin.MaxZombies.Value;
			if (currentZombieCount >= value)
			{
				return;
			}
			Vector3 playersCenter = GetPlayersCenter();
			if (playersCenter == Vector3.zero)
			{
				return;
			}
			int num = Mathf.Min(count, value - currentZombieCount);
			for (int i = 0; i < num; i++)
			{
				Vector2 val = Random.insideUnitCircle * Plugin.ZombieSpawnRadius.Value;
				Vector3 position = playersCenter + new Vector3(val.x, 2f, val.y);
				position = FindGroundPosition(position);
				GameObject val2 = null;
				try
				{
					val2 = PhotonNetwork.Instantiate("MushroomZombie", position, Random.rotation, (byte)0, (object[])null);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("[AK47] Failed to spawn zombie: " + ex.Message));
				}
				if ((Object)(object)val2 != (Object)null)
				{
					_liveZombies.Add(val2);
					_zombieTimers.Add(new ZombieTimer
					{
						zombie = val2,
						deathTime = Time.time + Plugin.ZombieMaxLifetime.Value
					});
					Plugin.Log.LogInfo((object)("[AK47] Spawned zombie: " + ((Object)val2).name));
				}
			}
		}
		catch (Exception ex2)
		{
			Plugin.Log.LogError((object)("[AK47] SpawnZombiesAroundPlayers error: " + ex2.Message));
		}
	}

	public static bool ContainsZombie(GameObject zombie)
	{
		return _liveZombies.Contains(zombie);
	}

	public static void RemoveZombie(GameObject zombie)
	{
		_liveZombies.Remove(zombie);
		_zombieTimers.RemoveAll((ZombieTimer t) => (Object)(object)t.zombie == (Object)(object)zombie);
	}

	public static void ClearZombies()
	{
		_liveZombies.Clear();
		_zombieTimers.Clear();
	}

	public static void UpdateZombieTimers()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		if (!PhotonNetwork.IsMasterClient || Time.frameCount % 10 != 0)
		{
			return;
		}
		float time = Time.time;
		Vector3 playersCenter = GetPlayersCenter();
		float num = 100f;
		for (int num2 = _zombieTimers.Count - 1; num2 >= 0; num2--)
		{
			ZombieTimer zombieTimer = _zombieTimers[num2];
			if ((Object)(object)zombieTimer.zombie == (Object)null)
			{
				_zombieTimers.RemoveAt(num2);
			}
			else if (time >= zombieTimer.deathTime)
			{
				if (_liveZombies.Contains(zombieTimer.zombie))
				{
					_liveZombies.Remove(zombieTimer.zombie);
				}
				PhotonNetwork.Destroy(zombieTimer.zombie);
				_zombieTimers.RemoveAt(num2);
			}
			else
			{
				float num3 = Vector3.Distance(zombieTimer.zombie.transform.position, playersCenter);
				if (num3 > num)
				{
					Plugin.Log.LogInfo((object)$"[AK47] Zombie too far from players ({num3:F1}m > {num}m), destroying");
					if (_liveZombies.Contains(zombieTimer.zombie))
					{
						_liveZombies.Remove(zombieTimer.zombie);
					}
					PhotonNetwork.Destroy(zombieTimer.zombie);
					_zombieTimers.RemoveAt(num2);
				}
			}
		}
		_liveZombies.RemoveWhere((GameObject z) => (Object)(object)z == (Object)null);
	}

	private static int GetCurrentZombieCount()
	{
		_liveZombies.RemoveWhere((GameObject z) => (Object)(object)z == (Object)null);
		return _liveZombies.Count;
	}

	private static Vector3 GetPlayersCenter()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid