Decompiled source of ShootZombies v1.3.7

plugins/Thanks.ShootZombies.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
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 System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ShootZombies")]
[assembly: AssemblyDescription("Turns PEAK's blowgun into a configurable zombie-survival weapon mode with selectable gun models, lobby weapon grants, an in-game config panel, and host-synced multiplayer settings.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ShootZombies")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("927916ce-8113-4ce1-a65e-d4bd77e780b4")]
[assembly: AssemblyFileVersion("1.3.7.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ShootZombies
{
	public sealed class AkHeldLegacyVisualMarker : MonoBehaviour
	{
	}
	public sealed class AkInPlaceMarker : MonoBehaviour
	{
		public bool hasBaseRotation;

		public bool hasBaseTransform;

		public bool hasOriginalVisual;

		public Vector3 baseLocalPosition = Vector3.zero;

		public Quaternion baseLocalRotation = Quaternion.identity;

		public Vector3 baseLocalScale = Vector3.one;

		public Mesh originalMesh;

		public Material[] originalMaterials;
	}
	internal static class AkLightweightAssetLoader
	{
		private struct ObjVertexKey : IEquatable<ObjVertexKey>
		{
			public int PositionIndex;

			public int UvIndex;

			public int NormalIndex;

			public bool Equals(ObjVertexKey other)
			{
				if (PositionIndex == other.PositionIndex && UvIndex == other.UvIndex)
				{
					return NormalIndex == other.NormalIndex;
				}
				return false;
			}

			public override bool Equals(object obj)
			{
				if (!(obj is ObjVertexKey))
				{
					return false;
				}
				return Equals((ObjVertexKey)obj);
			}

			public override int GetHashCode()
			{
				return ((17 * 31 + PositionIndex) * 31 + UvIndex) * 31 + NormalIndex;
			}
		}

		private struct ObjFaceVertex
		{
			public int PositionIndex;

			public int UvIndex;

			public int NormalIndex;
		}

		private const string ResourceFolderName = "AK_Resources";

		private const string CanonicalModelFileName = "ak_model.obj";

		private const string CanonicalTextureFileName = "ak_texture.png";

		private const string CanonicalIconFileName = "ak_icon.png";

		private static readonly string[] ModelFileNames = new string[3] { "ak_model.obj", "-3728671120793114700_Cube.obj", "Cube.obj" };

		private static readonly string[] TextureFileNames = new string[3] { "ak_texture.png", "AK-47_type_II.png", "ak47.png" };

		private static readonly string[] IconFileNames = new string[3] { "ak_icon.png", "AK-47_type_II_icon.png", "ak47_icon.png" };

		private static readonly Vector3 MeshLocalPosition = new Vector3(0f, 0f, 0.11863899f);

		private static readonly Quaternion MeshLocalRotation = new Quaternion(1.1009293E-08f, -0.70710677f, -0.7071068f, -2.2351747E-08f);

		private static readonly Vector3 MeshLocalScale = new Vector3(0.3060086f, 0.18934934f, 0.18934931f);

		private static readonly Vector3 SpawnLocalPosition = new Vector3(0.002f, 0.036f, 0.5118f);

		private static readonly Quaternion SpawnLocalRotation = Quaternion.identity;

		private static readonly Vector3 SpawnLocalScale = new Vector3(0.7339988f, 0.7339988f, 0.7339988f);

		public static bool TryLoad(out GameObject prefab, out string diagnostic)
		{
			prefab = null;
			diagnostic = string.Empty;
			if (!TryResolveResourcePaths(out var modelPath, out var texturePath, out diagnostic))
			{
				return false;
			}
			if (!TryLoadObjMesh(modelPath, out var mesh, out var summary))
			{
				diagnostic = "OBJ load failed: " + modelPath + " (" + summary + ")";
				return false;
			}
			string summary2;
			Material val = CreateMaterial(LoadTexture(texturePath, out summary2), texturePath);
			if ((Object)(object)val == (Object)null)
			{
				diagnostic = "Material creation failed for texture: " + texturePath;
				return false;
			}
			prefab = BuildPrefab(mesh, val);
			if ((Object)(object)prefab == (Object)null)
			{
				diagnostic = "Prefab build failed";
				return false;
			}
			diagnostic = "model=" + Path.GetFileName(modelPath) + ", texture=" + Path.GetFileName(texturePath) + ", " + summary + ", " + summary2;
			return true;
		}

		public static bool TryLoadIconTexture(out Texture2D texture, out string diagnostic)
		{
			texture = null;
			diagnostic = string.Empty;
			List<string> list = GetSearchDirectories().Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList();
			foreach (string item in list)
			{
				string text = ResolveFirstExistingPath(item, IconFileNames);
				if (!string.IsNullOrWhiteSpace(text))
				{
					texture = LoadTexture(text, out var summary);
					if ((Object)(object)texture != (Object)null)
					{
						diagnostic = "icon=" + Path.GetFileName(text) + ", " + summary;
						return true;
					}
					diagnostic = "icon decode failed: " + text + ", " + summary;
					return false;
				}
			}
			diagnostic = "searched=" + string.Join(" | ", list);
			return false;
		}

		private static bool TryResolveResourcePaths(out string modelPath, out string texturePath, out string diagnostic)
		{
			modelPath = string.Empty;
			texturePath = string.Empty;
			List<string> list = GetSearchDirectories().Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList();
			foreach (string item in list)
			{
				string text = ResolveFirstExistingPath(item, ModelFileNames);
				string text2 = ResolveFirstExistingPath(item, TextureFileNames);
				if (!string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(text2))
				{
					modelPath = text;
					texturePath = text2;
					diagnostic = "resolved at " + item;
					return true;
				}
			}
			diagnostic = "searched=" + string.Join(" | ", list);
			return false;
		}

		private static IEnumerable<string> GetSearchDirectories()
		{
			HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (string searchRoot in GetSearchRoots())
			{
				if (string.IsNullOrWhiteSpace(searchRoot))
				{
					continue;
				}
				string fullPath = GetFullPath(searchRoot);
				if (string.IsNullOrWhiteSpace(fullPath) || !Directory.Exists(fullPath) || !seen.Add(fullPath))
				{
					continue;
				}
				yield return fullPath;
				string path = Path.Combine(fullPath, "AK_Resources");
				if (Directory.Exists(path))
				{
					string fullPath2 = GetFullPath(path);
					if (!string.IsNullOrWhiteSpace(fullPath2) && seen.Add(fullPath2))
					{
						yield return fullPath2;
					}
				}
			}
		}

		private static IEnumerable<string> GetSearchRoots()
		{
			string location = Assembly.GetExecutingAssembly().Location;
			string text = (string.IsNullOrWhiteSpace(location) ? string.Empty : (Path.GetDirectoryName(location) ?? string.Empty));
			string text2 = Paths.PluginPath ?? string.Empty;
			string text3 = (string.IsNullOrWhiteSpace(text2) ? string.Empty : (Directory.GetParent(text2)?.FullName ?? string.Empty));
			if (!string.IsNullOrWhiteSpace(text))
			{
				yield return text;
			}
			if (!string.IsNullOrWhiteSpace(text2))
			{
				yield return text2;
			}
			if (!string.IsNullOrWhiteSpace(text3))
			{
				yield return text3;
			}
			yield return Path.Combine(Environment.CurrentDirectory ?? string.Empty, "AK_Resources");
		}

		private static string GetFullPath(string path)
		{
			try
			{
				return Path.GetFullPath(path);
			}
			catch
			{
				return string.Empty;
			}
		}

		private static string ResolveFirstExistingPath(string directory, IEnumerable<string> fileNames)
		{
			if (string.IsNullOrWhiteSpace(directory) || !Directory.Exists(directory))
			{
				return string.Empty;
			}
			foreach (string fileName in fileNames)
			{
				string text = Path.Combine(directory, fileName);
				if (File.Exists(text))
				{
					return text;
				}
			}
			return string.Empty;
		}

		private static bool TryLoadObjMesh(string modelPath, out Mesh mesh, out string summary)
		{
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_00b8: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			mesh = null;
			summary = string.Empty;
			List<Vector3> list = new List<Vector3>(4096);
			List<Vector2> list2 = new List<Vector2>(4096);
			List<Vector3> list3 = new List<Vector3>(4096);
			List<Vector3> list4 = new List<Vector3>(4096);
			List<Vector2> list5 = new List<Vector2>(4096);
			List<Vector3> list6 = new List<Vector3>(4096);
			List<int> list7 = new List<int>(12288);
			Dictionary<ObjVertexKey, int> cache = new Dictionary<ObjVertexKey, int>();
			bool flag = true;
			try
			{
				foreach (string item in File.ReadLines(modelPath))
				{
					if (string.IsNullOrWhiteSpace(item) || item[0] == '#')
					{
						continue;
					}
					if (item.StartsWith("v ", StringComparison.Ordinal))
					{
						if (TryParseVector3(item, out var vector))
						{
							list.Add(vector);
						}
					}
					else if (item.StartsWith("vt ", StringComparison.Ordinal))
					{
						if (TryParseVector2(item, out var vector2))
						{
							list2.Add(vector2);
						}
					}
					else if (item.StartsWith("vn ", StringComparison.Ordinal))
					{
						if (TryParseVector3(item, out var vector3))
						{
							list3.Add(vector3);
						}
					}
					else
					{
						if (!item.StartsWith("f ", StringComparison.Ordinal))
						{
							continue;
						}
						string[] array = item.Substring(2).Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
						if (array.Length < 3)
						{
							continue;
						}
						List<ObjFaceVertex> list8 = new List<ObjFaceVertex>(array.Length);
						string[] array2 = array;
						for (int i = 0; i < array2.Length; i++)
						{
							if (TryParseFaceVertex(array2[i], list.Count, list2.Count, list3.Count, out var vertex))
							{
								list8.Add(vertex);
								if (vertex.NormalIndex < 0)
								{
									flag = false;
								}
							}
						}
						if (list8.Count >= 3)
						{
							for (int j = 1; j < list8.Count - 1; j++)
							{
								AddTriangleVertex(list8[0], list, list2, list3, list4, list5, list6, list7, cache);
								AddTriangleVertex(list8[j], list, list2, list3, list4, list5, list6, list7, cache);
								AddTriangleVertex(list8[j + 1], list, list2, list3, list4, list5, list6, list7, cache);
							}
						}
					}
				}
				if (list4.Count == 0 || list7.Count == 0)
				{
					summary = "no mesh data";
					return false;
				}
				mesh = new Mesh();
				((Object)mesh).name = "AK_RuntimeMesh";
				if (list4.Count > 65535)
				{
					mesh.indexFormat = (IndexFormat)1;
				}
				mesh.SetVertices(list4);
				if (list5.Count == list4.Count)
				{
					mesh.SetUVs(0, list5);
				}
				mesh.subMeshCount = 1;
				mesh.SetTriangles(list7, 0, true);
				if (flag && list6.Count == list4.Count)
				{
					mesh.SetNormals(list6);
				}
				else
				{
					mesh.RecalculateNormals();
				}
				mesh.RecalculateBounds();
				TryRecalculateTangents(mesh);
				summary = "verts=" + list4.Count + ", tris=" + list7.Count / 3;
				return true;
			}
			catch (Exception ex)
			{
				mesh = null;
				summary = ex.GetType().Name + ": " + ex.Message;
				return false;
			}
		}

		private static bool TryParseVector3(string line, out Vector3 vector)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			vector = Vector3.zero;
			string[] array = line.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 4)
			{
				return false;
			}
			if (float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				vector = new Vector3(result, result2, result3);
				return true;
			}
			return false;
		}

		private static bool TryParseVector2(string line, out Vector2 vector)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			vector = Vector2.zero;
			string[] array = line.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 3)
			{
				return false;
			}
			if (float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
			{
				vector = new Vector2(result, result2);
				return true;
			}
			return false;
		}

		private static bool TryParseFaceVertex(string token, int positionCount, int uvCount, int normalCount, out ObjFaceVertex vertex)
		{
			vertex = default(ObjFaceVertex);
			if (string.IsNullOrWhiteSpace(token))
			{
				return false;
			}
			string[] array = token.Split(new char[1] { '/' });
			if (array.Length == 0)
			{
				return false;
			}
			vertex.PositionIndex = ResolveObjIndex(ParseObjIndex(array[0]), positionCount);
			vertex.UvIndex = ((array.Length >= 2 && !string.IsNullOrWhiteSpace(array[1])) ? ResolveObjIndex(ParseObjIndex(array[1]), uvCount) : (-1));
			vertex.NormalIndex = ((array.Length >= 3 && !string.IsNullOrWhiteSpace(array[2])) ? ResolveObjIndex(ParseObjIndex(array[2]), normalCount) : (-1));
			return vertex.PositionIndex >= 0;
		}

		private static int ParseObjIndex(string value)
		{
			int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result);
			return result;
		}

		private static int ResolveObjIndex(int rawIndex, int count)
		{
			if (rawIndex > 0)
			{
				return rawIndex - 1;
			}
			if (rawIndex < 0)
			{
				return count + rawIndex;
			}
			return -1;
		}

		private static void AddTriangleVertex(ObjFaceVertex faceVertex, List<Vector3> positions, List<Vector2> uvs, List<Vector3> normals, List<Vector3> outVertices, List<Vector2> outUvs, List<Vector3> outNormals, List<int> outTriangles, Dictionary<ObjVertexKey, int> cache)
		{
			//IL_0058: 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_0089: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			ObjVertexKey key = new ObjVertexKey
			{
				PositionIndex = faceVertex.PositionIndex,
				UvIndex = faceVertex.UvIndex,
				NormalIndex = faceVertex.NormalIndex
			};
			if (!cache.TryGetValue(key, out var value))
			{
				value = (cache[key] = outVertices.Count);
				outVertices.Add(positions[faceVertex.PositionIndex]);
				outUvs.Add((faceVertex.UvIndex >= 0 && faceVertex.UvIndex < uvs.Count) ? uvs[faceVertex.UvIndex] : Vector2.zero);
				outNormals.Add((faceVertex.NormalIndex >= 0 && faceVertex.NormalIndex < normals.Count) ? normals[faceVertex.NormalIndex] : Vector3.zero);
			}
			outTriangles.Add(value);
		}

		private static void TryRecalculateTangents(Mesh mesh)
		{
			if ((Object)(object)mesh == (Object)null)
			{
				return;
			}
			try
			{
				typeof(Mesh).GetMethod("RecalculateTangents", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null)?.Invoke(mesh, null);
			}
			catch
			{
			}
		}

		private static Texture2D LoadTexture(string texturePath, out string summary)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			summary = "texture=missing";
			if (string.IsNullOrWhiteSpace(texturePath) || !File.Exists(texturePath))
			{
				return null;
			}
			try
			{
				byte[] data = File.ReadAllBytes(texturePath);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				((Object)val).name = Path.GetFileNameWithoutExtension(texturePath);
				if (!TryLoadPngIntoTexture(val, data))
				{
					Object.DestroyImmediate((Object)(object)val);
					summary = "texture=decode-failed";
					return null;
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)1;
				((Texture)val).anisoLevel = 2;
				summary = "texture=" + ((Texture)val).width + "x" + ((Texture)val).height;
				return val;
			}
			catch (Exception ex)
			{
				summary = "texture-error=" + ex.GetType().Name;
				return null;
			}
		}

		private static bool TryLoadPngIntoTexture(Texture2D texture, byte[] data)
		{
			if ((Object)(object)texture == (Object)null || data == null || data.Length == 0)
			{
				return false;
			}
			try
			{
				MethodInfo method = typeof(Texture2D).GetMethod("LoadImage", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(byte[]) }, null);
				if (method != null)
				{
					if (!(method.Invoke(texture, new object[1] { data }) is bool result))
					{
						return true;
					}
					return result;
				}
			}
			catch
			{
			}
			try
			{
				MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: false)?.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
				{
					typeof(Texture2D),
					typeof(byte[]),
					typeof(bool)
				}, null);
				if (methodInfo != null)
				{
					if (!(methodInfo.Invoke(null, new object[3] { texture, data, false }) is bool result2))
					{
						return true;
					}
					return result2;
				}
			}
			catch
			{
			}
			return false;
		}

		private static Material CreateMaterial(Texture2D texture, string texturePath)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Legacy Shaders/Diffuse");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val);
			((Object)val2).name = "M_AK_Runtime";
			if (val2.HasProperty("_BaseMap"))
			{
				val2.SetTexture("_BaseMap", (Texture)(object)texture);
			}
			if (val2.HasProperty("_MainTex"))
			{
				val2.SetTexture("_MainTex", (Texture)(object)texture);
			}
			if (val2.HasProperty("_BaseColor"))
			{
				val2.SetColor("_BaseColor", Color.white);
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", Color.white);
			}
			if (val2.HasProperty("_Smoothness"))
			{
				val2.SetFloat("_Smoothness", 0.12f);
			}
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", 0.12f);
			}
			if (val2.HasProperty("_Cull"))
			{
				val2.SetInt("_Cull", 2);
			}
			val2.enableInstancing = true;
			Plugin.LogDiagnosticOnce("ak-light-mat:" + Path.GetFileName(texturePath ?? string.Empty), "Created lightweight AK material with shader=" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "null") + ", texture=" + (((Object)(object)texture != (Object)null) ? (((Texture)texture).width + "x" + ((Texture)texture).height) : "none"));
			return val2;
		}

		private static GameObject BuildPrefab(Mesh mesh, Material material)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mesh == (Object)null || (Object)(object)material == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("AK");
			GameObject val2 = new GameObject("Mesh");
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = MeshLocalPosition;
			val2.transform.localRotation = MeshLocalRotation;
			val2.transform.localScale = MeshLocalScale;
			MeshFilter val3 = val2.AddComponent<MeshFilter>();
			MeshRenderer val4 = val2.AddComponent<MeshRenderer>();
			val3.sharedMesh = mesh;
			((Renderer)val4).sharedMaterials = (Material[])(object)new Material[1] { material };
			((Renderer)val4).enabled = false;
			((Renderer)val4).forceRenderingOff = true;
			((Renderer)val4).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)val4).receiveShadows = true;
			GameObject val5 = new GameObject("SpawnPos");
			val5.transform.SetParent(val.transform, false);
			val5.transform.localPosition = SpawnLocalPosition;
			val5.transform.localRotation = SpawnLocalRotation;
			val5.transform.localScale = SpawnLocalScale;
			Object.DontDestroyOnLoad((Object)(object)val);
			return val;
		}
	}
	public sealed class AkLocalVisualMarker : MonoBehaviour
	{
	}
	public sealed class AkMuzzleMarker : MonoBehaviour
	{
	}
	public sealed class AkSimpleVisualMarker : MonoBehaviour
	{
	}
	internal static class AkUiPatchHelpers
	{
		private const BindingFlags ReflectionFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly FieldInfo InventoryPrefabField = typeof(InventoryItemUI).GetField("_itemPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo InventoryItemDataField = typeof(InventoryItemUI).GetField("_itemData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo ItemDataField = typeof(Item).GetField("data", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo ItemDataProperty = typeof(Item).GetProperty("data", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo SlotItemProperty = typeof(ItemSlot).GetProperty("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo SlotItemField = typeof(ItemSlot).GetField("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo SliceItemSlotField = typeof(BackpackWheelSlice).GetField("itemSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly Dictionary<Type, PropertyInfo> InventoryItemDataItemPropertyCache = new Dictionary<Type, PropertyInfo>();

		private static readonly Dictionary<Type, FieldInfo> InventoryItemDataItemFieldCache = new Dictionary<Type, FieldInfo>();

		private static readonly Dictionary<int, int> InventoryUiSourceKeyCache = new Dictionary<int, int>();

		private static readonly Dictionary<int, int> SliceSourceKeyCache = new Dictionary<int, int>();

		private static readonly Rect FullUvRect = new Rect(0f, 0f, 1f, 1f);

		private static readonly HashSet<InventoryItemUI> TrackedInventoryUis = new HashSet<InventoryItemUI>();

		private static readonly HashSet<BackpackWheelSlice> TrackedSlices = new HashSet<BackpackWheelSlice>();

		private static readonly HashSet<BackpackWheel> TrackedWheels = new HashSet<BackpackWheel>();

		private static readonly List<InventoryItemUI> StaleInventoryUis = new List<InventoryItemUI>();

		private static readonly List<BackpackWheelSlice> StaleSlices = new List<BackpackWheelSlice>();

		private static readonly List<BackpackWheel> StaleWheels = new List<BackpackWheel>();

		internal static void ApplyAkIcon(RawImage image, Item item)
		{
			if (Plugin.IsWeaponFeatureEnabled() && !((Object)(object)image == (Object)null) && ItemPatch.IsBlowgunLike(item))
			{
				ApplyAkIconForce(image);
			}
		}

		internal static void ApplyAkIconForce(RawImage image)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)image == (Object)null)
			{
				return;
			}
			Texture2D akIconTexture = Plugin.GetAkIconTexture();
			if (!((Object)(object)akIconTexture == (Object)null))
			{
				Graphic val = (Graphic)image;
				if (!((Object)(object)image.texture == (Object)(object)akIconTexture) || !((Object)(object)val.material == (Object)null) || !(val.color == Color.white) || !(image.uvRect == FullUvRect) || !((Behaviour)image).enabled)
				{
					image.texture = (Texture)akIconTexture;
					val.color = Color.white;
					val.material = null;
					image.uvRect = FullUvRect;
					((Behaviour)image).enabled = true;
				}
			}
		}

		internal static void ApplyAkText(TMP_Text label)
		{
			if (!((Object)(object)label == (Object)null) && !string.Equals(label.text, ItemPatch.DisplayName, StringComparison.Ordinal))
			{
				label.text = ItemPatch.DisplayName;
			}
		}

		internal static void EnsureAkDisplayAndVisual(Item item)
		{
			if (Plugin.IsWeaponFeatureEnabled() && !((Object)(object)item == (Object)null) && ItemPatch.IsBlowgunLike(item))
			{
				ItemPatch.ApplyAkDisplay(item);
			}
		}

		internal static void ApplyAkToInventoryUi(InventoryItemUI ui, Item knownItem = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			if ((Object)ui == (Object)null)
			{
				return;
			}
			TrackInventoryUi(ui);
			Item val = (((Object)(object)knownItem != (Object)null) ? knownItem : ResolveItemFromInventoryUi(ui));
			int instanceID = ((Object)ui).GetInstanceID();
			if (!Plugin.IsWeaponFeatureEnabled())
			{
				return;
			}
			int itemSourceKey = GetItemSourceKey(val);
			if (itemSourceKey != 0 && InventoryUiSourceKeyCache.TryGetValue(instanceID, out var value) && value == itemSourceKey && IsInventoryUiAlreadyShowingAk(ui))
			{
				return;
			}
			if ((Object)(object)val != (Object)null && ItemPatch.IsBlowgunLike(val))
			{
				EnsureAkDisplayAndVisual(val);
				ApplyAkIconForce(ui.icon);
				ApplyAkText((TMP_Text)ui.nameText);
				InventoryUiSourceKeyCache[instanceID] = itemSourceKey;
				return;
			}
			InventoryUiSourceKeyCache[instanceID] = itemSourceKey;
			if ((Object)(object)val != (Object)null)
			{
				RestoreInventoryUi(ui, val);
				return;
			}
			if (itemSourceKey == 0 && IsInventoryUiAlreadyShowingAk(ui))
			{
				ClearInventoryUi(ui);
				return;
			}
			TextMeshProUGUI nameText = ui.nameText;
			string value2 = ((((Object)(object)nameText != (Object)null) ? ((TMP_Text)nameText).text : null) ?? string.Empty).ToLowerInvariant();
			RawImage icon = ui.icon;
			Texture val2 = (((Object)(object)icon != (Object)null) ? icon.texture : null);
			string text = (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : string.Empty).ToLowerInvariant();
			if (ItemPatch.ContainsWeaponKeyword(value2) || text.Contains("dart") || text.Contains("blowgun") || ItemPatch.ContainsWeaponKeyword(text))
			{
				ApplyAkIconForce(ui.icon);
				ApplyAkText((TMP_Text)ui.nameText);
			}
		}

		internal static Item ResolveItemFromInventoryUi(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)ui == (Object)null)
			{
				return null;
			}
			try
			{
				object obj = InventoryPrefabField?.GetValue(ui);
				Item val = (Item)((obj is Item) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				object obj2 = InventoryItemDataField?.GetValue(ui);
				if (obj2 != null)
				{
					Item val2 = ResolveItemFromItemData(obj2);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		internal static Item ResolveItemFromSlot(ItemSlot slot)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (slot == null || slot.IsEmpty())
			{
				return null;
			}
			try
			{
				object obj = SlotItemProperty?.GetValue(slot);
				Item val = (Item)((obj is Item) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				object obj2 = SlotItemField?.GetValue(slot);
				Item val2 = (Item)((obj2 is Item) ? obj2 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			catch
			{
			}
			return slot.prefab;
		}

		internal static void ApplyAkToSliceImage(BackpackWheelSlice slice, Item knownItem = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)slice == (Object)null)
			{
				return;
			}
			TrackSlice(slice);
			Item val = (((Object)(object)knownItem != (Object)null) ? knownItem : ResolveItemFromSlice(slice));
			int instanceID = ((Object)slice).GetInstanceID();
			if (!Plugin.IsWeaponFeatureEnabled())
			{
				return;
			}
			int itemSourceKey = GetItemSourceKey(val);
			if (itemSourceKey == 0 || !SliceSourceKeyCache.TryGetValue(instanceID, out var value) || value != itemSourceKey || !IsSliceAlreadyShowingAk(slice))
			{
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					EnsureAkDisplayAndVisual(val);
					ApplyAkIconForce(slice.image);
				}
				else
				{
					RestoreSliceImage(slice, val);
				}
				SliceSourceKeyCache[instanceID] = itemSourceKey;
			}
		}

		internal static void ApplyAkToBackpackWheel(BackpackWheel wheel, Item knownItem = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)wheel == (Object)null)
			{
				return;
			}
			TrackWheel(wheel);
			Item val = knownItem;
			if ((Object)(object)val == (Object)null)
			{
				Character localCharacter = Character.localCharacter;
				object obj;
				if (localCharacter == null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = localCharacter.data;
					obj = ((data != null) ? data.currentItem : null);
				}
				val = (Item)obj;
			}
			Character localCharacter2 = Character.localCharacter;
			if (Plugin.IsWeaponFeatureEnabled())
			{
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val) && ItemPatch.IsLocallyHeldByPlayer(val, localCharacter2))
				{
					ItemPatch.ApplyAkDisplayIfNeeded(val);
					ApplyAkIcon(wheel.currentlyHeldItem, val);
				}
				else
				{
					RestoreBackpackWheel(wheel, ((Object)(object)val != (Object)null && ItemPatch.IsBlowgunLike(val)) ? null : val);
				}
			}
		}

		internal static bool RefreshTrackedUi()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			CleanupStaleTrackedUi();
			bool result = false;
			foreach (InventoryItemUI trackedInventoryUi in TrackedInventoryUis)
			{
				if (!((Object)trackedInventoryUi == (Object)null))
				{
					ApplyAkToInventoryUi(trackedInventoryUi);
					result = true;
				}
			}
			foreach (BackpackWheelSlice trackedSlice in TrackedSlices)
			{
				if (!((Object)trackedSlice == (Object)null))
				{
					ApplyAkToSliceImage(trackedSlice);
					result = true;
				}
			}
			foreach (BackpackWheel trackedWheel in TrackedWheels)
			{
				if (!((Object)trackedWheel == (Object)null))
				{
					ApplyAkToBackpackWheel(trackedWheel);
					result = true;
				}
			}
			return result;
		}

		internal static void ClearInventoryUiCache(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)ui == (Object)null))
			{
				InventoryUiSourceKeyCache.Remove(((Object)ui).GetInstanceID());
			}
		}

		internal static void ClearRuntimeCaches()
		{
			InventoryUiSourceKeyCache.Clear();
			SliceSourceKeyCache.Clear();
			TrackedInventoryUis.Clear();
			TrackedSlices.Clear();
			TrackedWheels.Clear();
			StaleInventoryUis.Clear();
			StaleSlices.Clear();
			StaleWheels.Clear();
		}

		private static Item ResolveItemFromItemData(object itemData)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if (itemData == null)
			{
				return null;
			}
			Type type = itemData.GetType();
			if (!InventoryItemDataItemPropertyCache.TryGetValue(type, out var value))
			{
				value = type.GetProperty("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				InventoryItemDataItemPropertyCache[type] = value;
				InventoryItemDataItemFieldCache[type] = type.GetField("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			try
			{
				object obj = value?.GetValue(itemData) ?? InventoryItemDataItemFieldCache[type]?.GetValue(itemData);
				return (Item)((obj is Item) ? obj : null);
			}
			catch
			{
				return null;
			}
		}

		private static int GetItemSourceKey(Item item)
		{
			if (!((Object)(object)item == (Object)null))
			{
				return ((Object)item).GetInstanceID();
			}
			return 0;
		}

		internal static bool IsInventoryUiAlreadyShowingAk(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)ui == (Object)null)
			{
				return false;
			}
			TextMeshProUGUI nameText = ui.nameText;
			if (!string.Equals((nameText != null) ? ((TMP_Text)nameText).text : null, ItemPatch.DisplayName, StringComparison.Ordinal))
			{
				return false;
			}
			Texture2D akIconTexture = Plugin.GetAkIconTexture();
			RawImage icon = ui.icon;
			if ((Object)(object)akIconTexture != (Object)null && !((Object)(object)icon == (Object)null))
			{
				return (Object)(object)icon.texture == (Object)(object)akIconTexture;
			}
			return false;
		}

		private static bool IsSliceAlreadyShowingAk(BackpackWheelSlice slice)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)slice == (Object)null)
			{
				return false;
			}
			Texture2D akIconTexture = Plugin.GetAkIconTexture();
			RawImage image = slice.image;
			if ((Object)(object)akIconTexture != (Object)null && !((Object)(object)image == (Object)null))
			{
				return (Object)(object)image.texture == (Object)(object)akIconTexture;
			}
			return false;
		}

		private static void RestoreInventoryUi(InventoryItemUI ui, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)ui == (Object)null) && !((Object)(object)item == (Object)null))
			{
				Texture val = ResolveDefaultItemIcon(item);
				if (!((Object)(object)ui.icon == (Object)null))
				{
					ui.icon.texture = val;
					((Graphic)ui.icon).color = ResolveInventoryIconColor(ui, Color.white);
					((Graphic)ui.icon).material = null;
					ui.icon.uvRect = FullUvRect;
					((Behaviour)ui.icon).enabled = (Object)(object)val != (Object)null;
				}
				if (!((Object)(object)ui.nameText == (Object)null))
				{
					((TMP_Text)ui.nameText).text = ResolveDefaultItemName(item);
				}
			}
		}

		private static void ClearInventoryUi(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)ui == (Object)null))
			{
				if (!((Object)(object)ui.icon == (Object)null))
				{
					ui.icon.texture = null;
					((Behaviour)ui.icon).enabled = false;
				}
				if (!((Object)(object)ui.nameText == (Object)null))
				{
					((TMP_Text)ui.nameText).text = string.Empty;
				}
			}
		}

		private static void RestoreSliceImage(BackpackWheelSlice slice, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)slice == (Object)null) && !((Object)(object)slice.image == (Object)null))
			{
				Texture val = ResolveDefaultItemIcon(item);
				slice.image.texture = val;
				((Graphic)slice.image).color = ResolveSliceIconColor(slice, Color.white);
				((Graphic)slice.image).material = null;
				slice.image.uvRect = FullUvRect;
				((Behaviour)slice.image).enabled = (Object)(object)val != (Object)null;
			}
		}

		private static void RestoreBackpackWheel(BackpackWheel wheel, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)wheel == (Object)null))
			{
				RawImage currentlyHeldItem = wheel.currentlyHeldItem;
				if (!((Object)(object)currentlyHeldItem == (Object)null))
				{
					Texture val = (currentlyHeldItem.texture = ResolveDefaultItemIcon(item));
					((Graphic)currentlyHeldItem).color = ResolveItemIconColor(item, Color.white);
					((Graphic)currentlyHeldItem).material = null;
					currentlyHeldItem.uvRect = FullUvRect;
					((Behaviour)currentlyHeldItem).enabled = (Object)(object)val != (Object)null;
				}
			}
		}

		private static Texture ResolveDefaultItemIcon(Item item)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if ((Object)(object)item == (Object)null || item.UIData == null)
			{
				return null;
			}
			try
			{
				return (Texture)item.UIData.GetIcon();
			}
			catch
			{
				return (Texture)item.UIData.icon;
			}
		}

		private static Color ResolveInventoryIconColor(InventoryItemUI ui, Color fallback)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)ui == (Object)null)
			{
				return fallback;
			}
			try
			{
				Color color;
				return TryGetCookColor(InventoryItemDataField?.GetValue(ui), out color) ? color : fallback;
			}
			catch
			{
				return fallback;
			}
		}

		private static Color ResolveSliceIconColor(BackpackWheelSlice slice, Color fallback)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			ItemSlot val = ResolveItemSlotFromSlice(slice);
			if (val == null || !TryGetCookColor(val.data, out var color))
			{
				return fallback;
			}
			return color;
		}

		private static Color ResolveItemIconColor(Item item, Color fallback)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)item == (Object)null)
			{
				return fallback;
			}
			try
			{
				Color color;
				return TryGetCookColor(ItemDataField?.GetValue(item) ?? ItemDataProperty?.GetValue(item), out color) ? color : fallback;
			}
			catch
			{
				return fallback;
			}
		}

		private static bool TryGetCookColor(object itemData, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			color = Color.white;
			ItemInstanceData val = (ItemInstanceData)((itemData is ItemInstanceData) ? itemData : null);
			IntItemData val2 = default(IntItemData);
			if (val != null && val.TryGetDataEntry<IntItemData>((DataEntryKey)1, ref val2) && val2 != null && val2.Value > 0)
			{
				color = ItemCooking.GetCookColor(val2.Value);
				return true;
			}
			return false;
		}

		private static string ResolveDefaultItemName(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return string.Empty;
			}
			try
			{
				string itemName = item.GetItemName((ItemInstanceData)null);
				if (!string.IsNullOrWhiteSpace(itemName))
				{
					return itemName;
				}
			}
			catch
			{
			}
			return item.UIData?.itemName ?? string.Empty;
		}

		internal static Item ResolveItemFromSlice(BackpackWheelSlice slice)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)slice == (Object)null)
			{
				return null;
			}
			try
			{
				PropertyInfo[] properties = ((object)slice).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (PropertyInfo propertyInfo in properties)
				{
					if (!(propertyInfo == null) && propertyInfo.GetIndexParameters().Length == 0)
					{
						object value = null;
						try
						{
							value = propertyInfo.GetValue(slice);
						}
						catch
						{
						}
						Item val = ExtractItem(value);
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
				FieldInfo[] fields = ((object)slice).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					object value2 = null;
					try
					{
						value2 = fieldInfo.GetValue(slice);
					}
					catch
					{
					}
					Item val2 = ExtractItem(value2);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static ItemSlot ResolveItemSlotFromSlice(BackpackWheelSlice slice)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)slice == (Object)null || SliceItemSlotField == null)
			{
				return null;
			}
			try
			{
				object? value = SliceItemSlotField.GetValue(slice);
				return (ItemSlot)((value is ItemSlot) ? value : null);
			}
			catch
			{
				return null;
			}
		}

		private static void TrackInventoryUi(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)ui == (Object)null) && !TrackedInventoryUis.Contains(ui))
			{
				TrackedInventoryUis.Add(ui);
			}
		}

		private static void TrackSlice(BackpackWheelSlice slice)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)slice == (Object)null) && !TrackedSlices.Contains(slice))
			{
				TrackedSlices.Add(slice);
			}
		}

		private static void TrackWheel(BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)wheel == (Object)null) && !TrackedWheels.Contains(wheel))
			{
				TrackedWheels.Add(wheel);
			}
		}

		private static void CleanupStaleTrackedUi()
		{
			RemoveDestroyedTrackedObjects<InventoryItemUI>(TrackedInventoryUis, StaleInventoryUis);
			RemoveDestroyedTrackedObjects<BackpackWheelSlice>(TrackedSlices, StaleSlices);
			RemoveDestroyedTrackedObjects<BackpackWheel>(TrackedWheels, StaleWheels);
		}

		private static void RemoveDestroyedTrackedObjects<T>(HashSet<T> source, List<T> staleBuffer) where T : Object
		{
			if (source.Count == 0)
			{
				return;
			}
			staleBuffer.Clear();
			foreach (T item in source)
			{
				if ((Object)(object)item == (Object)null)
				{
					staleBuffer.Add(item);
				}
			}
			for (int i = 0; i < staleBuffer.Count; i++)
			{
				source.Remove(staleBuffer[i]);
			}
			staleBuffer.Clear();
		}

		private static Item ExtractItem(object value)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			Item val = (Item)((value is Item) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			ItemSlot val2 = (ItemSlot)((value is ItemSlot) ? value : null);
			if (val2 != null)
			{
				return ResolveItemFromSlot(val2);
			}
			if (value == null)
			{
				return null;
			}
			Type type = value.GetType();
			if (!(type.FullName ?? string.Empty).StartsWith("System.ValueTuple", StringComparison.Ordinal))
			{
				return null;
			}
			try
			{
				FieldInfo field = type.GetField("Item1");
				FieldInfo? field2 = type.GetField("Item2");
				object obj = field?.GetValue(value);
				object obj2 = field2?.GetValue(value);
				if (obj is BackpackReference backpackRef)
				{
					if (obj2 is byte slotIndex)
					{
						return ResolveFromBackpackTuple(backpackRef, slotIndex);
					}
					if (obj2 is int num)
					{
						return ResolveFromBackpackTuple(backpackRef, (byte)Mathf.Clamp(num, 0, 255));
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static Item ResolveFromBackpackTuple(BackpackReference backpackRef, byte slotIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((object)backpackRef == null)
				{
					return null;
				}
				object data = ((BackpackReference)(ref backpackRef)).GetData();
				if (data == null)
				{
					return null;
				}
				if (!((data.GetType().GetProperty("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(data) ?? data.GetType().GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(data)) is ItemSlot[] array) || slotIndex >= array.Length)
				{
					return null;
				}
				return ResolveItemFromSlot(array[slotIndex]);
			}
			catch
			{
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(BackpackWheel), "UpdateCookedAmount")]
	public static class BackpackWheelCookColorPatch
	{
		[HarmonyPostfix]
		public static void UpdateCookedAmountPostfix(BackpackWheel __instance, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (!Plugin.IsWeaponFeatureEnabled())
				{
					return;
				}
				object obj;
				if (!((Object)(object)item != (Object)null))
				{
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)localCharacter == (Object)null)
					{
						obj = null;
					}
					else
					{
						CharacterData data = localCharacter.data;
						obj = (((Object)(object)data != (Object)null) ? data.currentItem : null);
					}
				}
				else
				{
					obj = item;
				}
				Item val = (Item)obj;
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					AkUiPatchHelpers.ApplyAkIconForce(__instance.currentlyHeldItem);
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheel), "InitWheel")]
	public static class BackpackWheelPatch
	{
		[HarmonyPostfix]
		public static void InitWheelPostfix(BackpackWheel __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Plugin.IsWeaponFeatureEnabled())
				{
					AkUiPatchHelpers.ApplyAkToBackpackWheel(__instance);
					BackpackWheelSlice[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<BackpackWheelSlice>(true);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						AkUiPatchHelpers.ApplyAkToSliceImage(componentsInChildren[i]);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] BackpackWheelPatch failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "SetItemIcon")]
	public static class BackpackWheelSetItemIconPatch
	{
		[HarmonyPostfix]
		public static void SetItemIconPostfix(BackpackWheelSlice __instance, Item iconHolder, ItemInstanceData itemInstanceData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Plugin.IsWeaponFeatureEnabled())
				{
					Item val = (((Object)(object)iconHolder != (Object)null) ? iconHolder : AkUiPatchHelpers.ResolveItemFromSlice(__instance));
					if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
					{
						AkUiPatchHelpers.ApplyAkToSliceImage(__instance, val);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[ShootZombies] BackpackWheelSetItemIconPatch failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "SharedInit")]
	public static class BackpackWheelSharedInitPatch
	{
		[HarmonyPostfix]
		public static void SharedInitPostfix(BackpackWheelSlice __instance, BackpackReference bpRef, BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Plugin.IsWeaponFeatureEnabled())
				{
					AkUiPatchHelpers.ApplyAkToSliceImage(__instance);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[ShootZombies] BackpackWheelSharedInitPatch failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "UpdateCookedAmount")]
	public static class BackpackWheelSliceCookColorPatch
	{
		[HarmonyPostfix]
		public static void UpdateCookedAmountPostfix(BackpackWheelSlice __instance, Item item, ItemInstanceData itemInstanceData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Plugin.IsWeaponFeatureEnabled())
				{
					Item val = (((Object)(object)item != (Object)null) ? item : AkUiPatchHelpers.ResolveItemFromSlice(__instance));
					if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
					{
						AkUiPatchHelpers.ApplyAkIconForce(__instance.image);
					}
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "InitItemSlot")]
	public static class BackpackWheelSlicePatch
	{
		[HarmonyPostfix]
		public static void InitItemSlotPostfix(BackpackWheelSlice __instance, (BackpackReference, byte) slot, BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Plugin.IsWeaponFeatureEnabled())
				{
					ItemSlot val = ((BackpackReference)(ref slot.Item1)).GetData().itemSlots[slot.Item2];
					if (val != null && !val.IsEmpty() && ItemPatch.IsBlowgunLike(val.prefab))
					{
						Item val2 = AkUiPatchHelpers.ResolveItemFromSlot(val);
						Item val3 = (((Object)(object)val2 != (Object)null) ? val2 : val.prefab);
						ItemPatch.ApplyAkDisplayIfNeeded(val3);
						ItemPatch.ApplyAkDisplayIfNeeded(val.prefab);
						AkUiPatchHelpers.ApplyAkToSliceImage(__instance, val3);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] BackpackWheelSlicePatch failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "InitStashSlot")]
	public static class BackpackWheelStashSlicePatch
	{
		[HarmonyPostfix]
		public static void InitStashSlotPostfix(BackpackWheelSlice __instance, BackpackReference bpRef, BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (!Plugin.IsWeaponFeatureEnabled())
				{
					return;
				}
				Item val = AkUiPatchHelpers.ResolveItemFromSlice(__instance);
				if ((Object)(object)val == (Object)null)
				{
					Character localCharacter = Character.localCharacter;
					object obj;
					if ((Object)(object)localCharacter == (Object)null)
					{
						obj = null;
					}
					else
					{
						CharacterData data = localCharacter.data;
						obj = (((Object)(object)data != (Object)null) ? data.currentItem : null);
					}
					val = (Item)obj;
				}
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					AkUiPatchHelpers.ApplyAkToSliceImage(__instance, val);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] BackpackWheelStashSlicePatch failed: " + ex));
			}
		}
	}
	[HarmonyPatch]
	public class BlowgunChargeSoundPatch
	{
		private static MethodInfo _targetMethod;

		private static FieldInfo _castProgressField;

		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
			{
				if (!Plugin.IsWeaponFeatureEnabled())
				{
					return true;
				}
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter == (Object)null)
				{
					return true;
				}
				if ((Object)(object)localCharacter.player == (Object)null)
				{
					return true;
				}
				CharacterData data = localCharacter.data;
				Item val = (((Object)(object)data != (Object)null) ? data.currentItem : null);
				if ((Object)(object)val == (Object)null || !ItemPatch.IsBlowgunLike(val))
				{
					return true;
				}
				if (_castProgressField == null)
				{
					_castProgressField = ((object)val).GetType().GetField("<castProgress>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (_castProgressField == null)
				{
					return true;
				}
				float num = (float)_castProgressField.GetValue(val);
				bool flag = _lastCastProgress >= 0.99f;
				bool flag2 = num >= 0.99f;
				_lastCastProgress = num;
				if (!flag2)
				{
					_hasPlayedGunshot = false;
					return false;
				}
				if (!flag && flag2 && !_hasPlayedGunshot)
				{
					_hasPlayedGunshot = true;
					return false;
				}
				return false;
			}
			catch (Exception)
			{
			}
			return true;
		}
	}
	[HarmonyPatch]
	public class BlowgunInfiniteUsePatch
	{
		private const int BlowgunItemId = 70;

		private static Type _actionRaycastDartType;

		private static Type _actionConsumeType;

		private static Type _actionConsumeAndSpawnType;

		private static bool _itemDataAccessorsResolved;

		private static MethodInfo _getDataGenericMethod;

		private static Type _optionableIntItemDataType;

		private static FieldInfo _optionableIntHasDataField;

		private static FieldInfo _optionableIntValueField;

		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
			{
				if (Plugin.IsWeaponFeatureEnabled() && IsBlowgunItem(__instance))
				{
					SetBlowgunUseCount(__instance, 9999);
					NormalizeEnabledBlowgunRuntimeState(__instance);
					Type type = ((object)__instance).GetType();
					float num = Plugin.FireInterval?.Value ?? 0.4f;
					FieldInfo field = type.GetField("usingTimePrimary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null)
					{
						field.SetValue(__instance, num);
					}
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void RestoreVanillaSingleUseOnAllBlowguns()
		{
			try
			{
				Item[] array = Resources.FindObjectsOfTypeAll<Item>();
				for (int i = 0; i < array.Length; i++)
				{
					RestoreVanillaSingleUse(array[i]);
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void EnsureInfiniteUse(Item item)
		{
			try
			{
				if (Plugin.IsWeaponFeatureEnabled() && IsBlowgunItem(item))
				{
					SetBlowgunUseCount(item, 9999);
					NormalizeEnabledBlowgunRuntimeState(item);
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void RestoreVanillaSingleUse(Item item)
		{
			try
			{
				if (IsBlowgunItem(item))
				{
					SetBlowgunUseCount(item, 1);
					NormalizeRaycastDartComponents(item);
					NormalizeRaycastDartComponents(item.isSecretlyOtherItemPrefab);
					RestoreRaycastDartAction(item);
					RestoreRaycastDartAction(item.isSecretlyOtherItemPrefab);
				}
			}
			catch (Exception)
			{
			}
		}

		internal static bool IsBlowgunItem(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			try
			{
				if (item.itemID == 70)
				{
					return true;
				}
				if ((Object)(object)item.isSecretlyOtherItemPrefab != (Object)null && item.isSecretlyOtherItemPrefab.itemID == 70)
				{
					return true;
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		internal static void NormalizeEnabledBlowgunRuntimeState(Item item)
		{
			try
			{
				if (Plugin.IsWeaponFeatureEnabled() && IsBlowgunItem(item))
				{
					NormalizeRaycastDartComponents(item);
					NormalizeRaycastDartComponents(item.isSecretlyOtherItemPrefab);
					DisableConsumableActions(item);
				}
			}
			catch
			{
			}
		}

		internal static void NormalizeDartRpcComponents(Item item)
		{
			try
			{
				if (!((Object)(object)item == (Object)null) && ItemPatch.IsBlowgunLike(item))
				{
					NormalizeRaycastDartComponents(item);
					NormalizeRaycastDartComponents(item.isSecretlyOtherItemPrefab);
				}
			}
			catch
			{
			}
		}

		private static void NormalizeRaycastDartComponents(Item item)
		{
			try
			{
				if ((Object)(object)item == (Object)null)
				{
					return;
				}
				if (_actionRaycastDartType == null)
				{
					_actionRaycastDartType = typeof(Item).Assembly.GetType("Action_RaycastDart");
				}
				if (_actionRaycastDartType == null)
				{
					return;
				}
				Component[] componentsInChildren = ((Component)item).GetComponentsInChildren(_actionRaycastDartType, true);
				if (componentsInChildren == null || componentsInChildren.Length <= 1)
				{
					return;
				}
				for (int i = 1; i < componentsInChildren.Length; i++)
				{
					if ((Object)(object)componentsInChildren[i] != (Object)null)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
					}
				}
			}
			catch
			{
			}
		}

		private static void DisableConsumableActions(Item item)
		{
			try
			{
				if (!((Object)(object)item == (Object)null))
				{
					if (_actionConsumeType == null)
					{
						_actionConsumeType = typeof(Item).Assembly.GetType("Action_Consume");
					}
					if (_actionConsumeAndSpawnType == null)
					{
						_actionConsumeAndSpawnType = typeof(Item).Assembly.GetType("Action_ConsumeAndSpawn");
					}
					DestroyActionsByType(item, _actionConsumeType);
					DestroyActionsByType(item, _actionConsumeAndSpawnType);
				}
			}
			catch
			{
			}
		}

		private static void DestroyActionsByType(Item item, Type actionType)
		{
			if ((Object)(object)item == (Object)null || actionType == null)
			{
				return;
			}
			Component[] componentsInChildren = ((Component)item).GetComponentsInChildren(actionType, true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		private static void RestoreRaycastDartAction(Item item)
		{
			try
			{
				if ((Object)(object)item == (Object)null)
				{
					return;
				}
				if (_actionRaycastDartType == null)
				{
					_actionRaycastDartType = typeof(Item).Assembly.GetType("Action_RaycastDart");
				}
				if (!(_actionRaycastDartType == null))
				{
					Component val = ((Component)item).GetComponentInChildren(_actionRaycastDartType, true);
					if ((Object)(object)val == (Object)null)
					{
						val = ((Component)item).GetComponent(_actionRaycastDartType);
					}
					Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.enabled = true;
					}
				}
			}
			catch
			{
			}
		}

		private static void SetBlowgunUseCount(Item item, int value)
		{
			if ((Object)(object)item == (Object)null || !TryResolveItemDataAccessors())
			{
				return;
			}
			MethodInfo methodInfo = _getDataGenericMethod.MakeGenericMethod(_optionableIntItemDataType);
			ParameterInfo[] parameters = methodInfo.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;
				}
			}
			object obj = methodInfo.Invoke(item, array);
			if (obj != null)
			{
				_optionableIntHasDataField?.SetValue(obj, true);
				_optionableIntValueField?.SetValue(obj, value);
			}
		}

		private static bool TryResolveItemDataAccessors()
		{
			if (_itemDataAccessorsResolved)
			{
				if (_getDataGenericMethod != null && _optionableIntItemDataType != null)
				{
					return _optionableIntValueField != null;
				}
				return false;
			}
			_itemDataAccessorsResolved = true;
			MethodInfo[] methods = typeof(Item).GetMethods(BindingFlags.Instance | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == "GetData" && methodInfo.IsGenericMethod)
				{
					_getDataGenericMethod = methodInfo;
					break;
				}
			}
			Type[] types = typeof(Item).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.Name == "OptionableIntItemData")
				{
					_optionableIntItemDataType = type;
					break;
				}
			}
			if (_optionableIntItemDataType != null)
			{
				_optionableIntHasDataField = _optionableIntItemDataType.GetField("HasData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_optionableIntValueField = _optionableIntItemDataType.GetField("Value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (_getDataGenericMethod != null && _optionableIntItemDataType != null)
			{
				return _optionableIntValueField != null;
			}
			return false;
		}
	}
	[HarmonyPatch]
	public static class BlowgunItemRuntimeNormalizePatch
	{
		private static readonly HashSet<string> TargetMethodNames = new HashSet<string>(StringComparer.Ordinal) { "Awake", "OnEnable", "Start", "OnInstanceDataSet", "SetState" };

		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(Item).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (TargetMethodNames.Contains(methodInfo.Name))
				{
					yield return methodInfo;
				}
			}
		}

		private static void Postfix(Item __instance)
		{
			BlowgunInfiniteUsePatch.NormalizeDartRpcComponents(__instance);
			if (!Plugin.IsWeaponFeatureEnabled())
			{
				BlowgunInfiniteUsePatch.RestoreVanillaSingleUse(__instance);
				return;
			}
			BlowgunInfiniteUsePatch.EnsureInfiniteUse(__instance);
			Plugin.TryProtectWeaponItemRuntime(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemCooking), "Wreck")]
	public class BlowgunWreckPatch
	{
		private static bool Prefix(ItemCooking __instance)
		{
			try
			{
				if (!Plugin.IsWeaponFeatureEnabled())
				{
					return true;
				}
				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 static class DartImpactPatch
	{
		private static MethodBase _targetMethod;

		public static MethodBase TargetMethod()
		{
			if (_targetMethod != null)
			{
				return _targetMethod;
			}
			try
			{
				MethodInfo methodInfo = typeof(Item).Assembly.GetType("Action_RaycastDart")?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
				{
					if (!string.Equals(m.Name, "RPC_DartImpact", StringComparison.Ordinal))
					{
						return false;
					}
					ParameterInfo[] parameters = m.GetParameters();
					if (parameters.Length != 3 && parameters.Length != 4)
					{
						return false;
					}
					return parameters[0].ParameterType == typeof(int) && parameters[1].ParameterType == typeof(Vector3) && parameters[2].ParameterType == typeof(Vector3);
				});
				if (methodInfo != null)
				{
					_targetMethod = methodInfo;
					return _targetMethod;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[DartImpactPatch] TargetMethod error: " + ex));
			}
			Plugin.Log.LogWarning((object)"[DartImpactPatch] TargetMethod returning null - RPC_DartImpact method not found");
			return null;
		}

		[HarmonyPrefix]
		public static bool DartImpactPrefix(MonoBehaviour __instance, int characterID, Vector3 origin, Vector3 endpoint)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Item componentInParent = ((Component)__instance).GetComponentInParent<Item>();
				if (!Plugin.IsWeaponFeatureEnabled() || (Object)(object)componentInParent == (Object)null || !ItemPatch.IsBlowgunLike(componentInParent))
				{
					return true;
				}
				if (characterID > 0)
				{
					PhotonView val = PhotonView.Find(characterID);
					if ((Object)(object)val != (Object)null)
					{
						Character componentInParent2 = ((Component)val).gameObject.GetComponentInParent<Character>();
						if ((Object)(object)componentInParent2 != (Object)null && (componentInParent2.isZombie || componentInParent2.isBot))
						{
							Plugin.HandleZombieDartImpactVisual((Component)__instance, endpoint);
							Plugin.Instance?.HitZombie(componentInParent2, origin);
							return false;
						}
						if ((Object)(object)componentInParent2 != (Object)null && !componentInParent2.isZombie && !componentInParent2.isBot)
						{
							return false;
						}
					}
				}
				Plugin.HandleZombieDartImpactVisual((Component)__instance, endpoint);
				return false;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[DartImpactPatch] Error: " + ex));
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class LocalDartImpactPatch
	{
		private static MethodBase _targetMethod;

		public static MethodBase TargetMethod()
		{
			if (_targetMethod != null)
			{
				return _targetMethod;
			}
			try
			{
				MethodInfo methodInfo = typeof(Item).Assembly.GetType("Action_RaycastDart")?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => string.Equals(m.Name, "DartImpact", StringComparison.Ordinal) && m.GetParameters().Length == 3 && m.GetParameters()[0].ParameterType == typeof(Character) && m.GetParameters()[1].ParameterType == typeof(Vector3) && m.GetParameters()[2].ParameterType == typeof(Vector3));
				if (methodInfo != null)
				{
					_targetMethod = methodInfo;
					return _targetMethod;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[LocalDartImpactPatch] TargetMethod error: " + ex));
			}
			Plugin.Log.LogWarning((object)"[LocalDartImpactPatch] TargetMethod returning null - DartImpact method not found");
			return null;
		}

		[HarmonyPrefix]
		public static bool DartImpactPrefix(MonoBehaviour __instance, Character hitCharacter, Vector3 origin, Vector3 endpoint)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			try
			{
				Item componentInParent = ((Component)__instance).GetComponentInParent<Item>();
				if (!Plugin.IsWeaponFeatureEnabled() || (Object)(object)componentInParent == (Object)null || !ItemPatch.IsBlowgunLike(componentInParent))
				{
					return true;
				}
				if ((Object)(object)hitCharacter == (Object)null)
				{
					Plugin.HandleZombieDartImpactVisual((Component)__instance, endpoint);
					return false;
				}
				if (hitCharacter.isZombie || hitCharacter.isBot)
				{
					Plugin.HandleZombieDartImpactVisual((Component)__instance, endpoint);
					Plugin.Instance?.HitZombie(hitCharacter, origin);
					return false;
				}
				Plugin.HandleZombieDartImpactVisual((Component)__instance, endpoint);
				return false;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[LocalDartImpactPatch] Error: " + ex));
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class DisableZombieSleepPatch
	{
		private const float DefaultTargetSearchInterval = 10f;

		private const float DefaultSamePlayerBiteCooldown = 5f;

		private const float DefaultPostBiteRecoveryTime = 3f;

		private const int LungeRecoveryState = 5;

		private const float PostBiteRecoverySyncThreshold = 0.45999998f;

		internal const float PostBiteRecoveryFallWindow = 0.45f;

		private const float CloseRangeLungeDistanceScale = 0.35f;

		private const float CloseRangeLungeDistanceMin = 2.75f;

		private const float CloseRangeLungeDistanceMax = 4.25f;

		private const float MinimumChaseBeforeLunge = 0.65f;

		private const float MaximumLungeVerticalDelta = 2.25f;

		private static readonly MethodInfo CharacterFallMethod = AccessTools.Method(typeof(Character), "Fall", new Type[2]
		{
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo StartChasingMethod = AccessTools.Method(typeof(MushroomZombie), "StartChasing", Type.EmptyTypes, (Type[])null);

		private static readonly MethodInfo StartLungingMethod = AccessTools.Method(typeof(MushroomZombie), "StartLunging", Type.EmptyTypes, (Type[])null);

		private static readonly MethodInfo CanSeeTargetMethod = AccessTools.Method(typeof(MushroomZombie), "CanSeeTarget", new Type[1] { typeof(Character) }, (Type[])null);

		private static readonly FieldInfo LungeRecoveryTimerField = AccessTools.Field(typeof(MushroomZombie), "timeSpentRecoveringFromLunge");

		private static readonly FieldInfo TimeSpentChasingField = AccessTools.Field(typeof(MushroomZombie), "timeSpentChasing");

		private static readonly Dictionary<int, float> PostBiteRecoveryUntilByZombieViewId = new Dictionary<int, float>();

		private static bool UseVanillaBehavior()
		{
			return Plugin.IsVanillaZombieBehaviorDifficultyRuntime();
		}

		private static float GetTargetSearchInterval()
		{
			return Plugin.GetZombieTargetSearchIntervalRuntime();
		}

		private static float GetSamePlayerBiteCooldown()
		{
			return Plugin.GetZombieSamePlayerBiteCooldownRuntime();
		}

		private static float GetPostBiteRecoveryTime()
		{
			return Plugin.GetZombieBiteRecoveryTimeRuntime();
		}

		private static int GetZombieViewId(MushroomZombie zombie)
		{
			if ((Object)(object)zombie == (Object)null || (Object)(object)((MonoBehaviourPun)zombie).photonView == (Object)null)
			{
				return -1;
			}
			return ((MonoBehaviourPun)zombie).photonView.ViewID;
		}

		private static void ResetLungeRecoveryTimer(MushroomZombie zombie)
		{
			if ((Object)(object)zombie != (Object)null && LungeRecoveryTimerField != null)
			{
				LungeRecoveryTimerField.SetValue(zombie, 0f);
			}
		}

		private static void ClearPostBiteRecoveryOverride(MushroomZombie zombie)
		{
			int zombieViewId = GetZombieViewId(zombie);
			if (zombieViewId >= 0)
			{
				PostBiteRecoveryUntilByZombieViewId.Remove(zombieViewId);
			}
			ResetLungeRecoveryTimer(zombie);
		}

		private static void SetPostBiteRecoveryOverride(MushroomZombie zombie, float duration)
		{
			int zombieViewId = GetZombieViewId(zombie);
			if (zombieViewId >= 0)
			{
				ResetLungeRecoveryTimer(zombie);
				if (duration <= 0f)
				{
					PostBiteRecoveryUntilByZombieViewId.Remove(zombieViewId);
				}
				else
				{
					PostBiteRecoveryUntilByZombieViewId[zombieViewId] = Time.time + duration;
				}
			}
		}

		private static bool TryGetPostBiteRecoveryOverride(MushroomZombie zombie, out float recoverAtTime)
		{
			recoverAtTime = 0f;
			int zombieViewId = GetZombieViewId(zombie);
			if (zombieViewId >= 0)
			{
				return PostBiteRecoveryUntilByZombieViewId.TryGetValue(zombieViewId, out recoverAtTime);
			}
			return false;
		}

		private static float GetCloseRangeLungeDistance(MushroomZombie zombie)
		{
			if ((Object)(object)zombie == (Object)null)
			{
				return 2.75f;
			}
			return Mathf.Clamp(zombie.zombieLungeDistance * 0.35f, 2.75f, 4.25f);
		}

		private static float GetTimeSpentChasing(MushroomZombie zombie)
		{
			if ((Object)(object)zombie == (Object)null || TimeSpentChasingField == null)
			{
				return 0f;
			}
			object value = TimeSpentChasingField.GetValue(zombie);
			if (value is float)
			{
				return (float)value;
			}
			return 0f;
		}

		private static bool CanSeeTarget(MushroomZombie zombie, Character target)
		{
			if ((Object)(object)zombie == (Object)null || (Object)(object)target == (Object)null || CanSeeTargetMethod == null)
			{
				return false;
			}
			object obj = CanSeeTargetMethod.Invoke(zombie, new object[1] { target });
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		internal static void ResetRuntimeState()
		{
			PostBiteRecoveryUntilByZombieViewId.Clear();
		}

		[HarmonyPatch(typeof(MushroomZombie), "Start")]
		[HarmonyPostfix]
		private static void MushroomZombieStartPostfix(MushroomZombie __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				ZombieSpawner.InitializeSpawnedZombieRuntime(((Component)__instance).gameObject);
			}
		}

		[HarmonyPatch(typeof(MushroomZombie), "TryLookForTarget")]
		[HarmonyPrefix]
		private static bool TryLookForTargetPrefix(MushroomZombie __instance)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)((MonoBehaviourPun)__instance).photonView == (Object)null || !((MonoBehaviourPun)__instance).photonView.IsMine)
			{
				return true;
			}
			float targetSearchInterval = GetTargetSearchInterval();
			if (__instance.sinceLookForTarget < targetSearchInterval)
			{
				return false;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				__instance.sinceLookForTarget = 0f;
				return false;
			}
			Character val = null;
			float num = float.MaxValue;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)component) && !allCharacter.isBot && !allCharacter.isZombie && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.data.dead && !allCharacter.data.fullyPassedOut)
				{
					float num2 = Vector3.Distance(allCharacter.Center, component.Center);
					if ((Object)(object)val == (Object)null || num2 < num)
					{
						val = allCharacter;
						num = num2;
					}
				}
			}
			int num3 = (((Object)(object)val == (Object)null) ? (-1) : ((MonoBehaviourPun)val).photonView.ViewID);
			((MonoBehaviourPun)__instance).photonView.RPC("RPCA_SetCurrentTarget", (RpcTarget)0, new object[2] { num3, 0f });
			__instance.sinceLookForTarget = 0f;
			return false;
		}

		[HarmonyPatch(typeof(MushroomZombie), "TryLunge")]
		[HarmonyPrefix]
		private static bool TryLungePrefix(MushroomZombie __instance)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (UseVanillaBehavior())
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null || StartLungingMethod == null)
			{
				return true;
			}
			Character currentTarget = __instance.currentTarget;
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || (Object)(object)currentTarget == (Object)null)
			{
				return false;
			}
			if ((int)__instance.currentState != 3 || !component.data.isGrounded || !component.input.sprintIsPressed || !CanSeeTarget(__instance, currentTarget))
			{
				return false;
			}
			if (GetTimeSpentChasing(__instance) < Mathf.Max(__instance.chaseTimeBeforeSprint, 0.65f))
			{
				return false;
			}
			Vector3 center = component.Center;
			Vector3 center2 = currentTarget.Center;
			center.y = 0f;
			center2.y = 0f;
			float num = Vector3.Distance(center, center2);
			float num2 = Mathf.Abs(currentTarget.Center.y - component.Center.y);
			if (num > GetCloseRangeLungeDistance(__instance) || num2 > 2.25f)
			{
				return false;
			}
			StartLungingMethod.Invoke(__instance, null);
			return false;
		}

		[HarmonyPatch(typeof(MushroomZombie), "OnBitCharacter")]
		[HarmonyPostfix]
		private static void OnBitCharacterPostfix(MushroomZombie __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((MonoBehaviourPun)__instance).photonView == (Object)null))
			{
				Character component = ((Component)__instance).GetComponent<Character>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)((MonoBehaviourPun)component).photonView == (Object)null))
				{
					float postBiteRecoveryTime = GetPostBiteRecoveryTime();
					SetPostBiteRecoveryOverride(__instance, postBiteRecoveryTime);
					float num = Mathf.Min(0.45f, postBiteRecoveryTime);
					component.data.fallSeconds = num;
					((MonoBehaviourPun)component).photonView.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { num });
					((MonoBehaviourPun)__instance).photonView.RPC("RPC_SyncState", (RpcTarget)0, new object[4]
					{
						5,
						false,
						num,
						component.data.passedOut
					});
				}
			}
		}

		[HarmonyPatch(typeof(MushroomZombie), "RPC_SyncState")]
		[HarmonyPostfix]
		private static void RpcSyncStatePostfix(MushroomZombie __instance, int state, bool isSprinting, float fallSeconds, bool passedOut)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if (state == 5)
			{
				if (fallSeconds <= 0.45999998f)
				{
					SetPostBiteRecoveryOverride(__instance, GetPostBiteRecoveryTime());
				}
				else
				{
					ClearPostBiteRecoveryOverride(__instance);
				}
			}
			else
			{
				ClearPostBiteRecoveryOverride(__instance);
			}
		}

		[HarmonyPatch(typeof(MushroomZombie), "DoLungeRecovery")]
		[HarmonyPrefix]
		private static bool DoLungeRecoveryPrefix(MushroomZombie __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!TryGetPostBiteRecoveryOverride(__instance, out var recoverAtTime))
			{
				return true;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				ClearPostBiteRecoveryOverride(__instance);
				return true;
			}
			if (component.data.fallSeconds > 0f || component.data.passedOut || component.data.fullyPassedOut)
			{
				return false;
			}
			if (Time.time < recoverAtTime)
			{
				return false;
			}
			ClearPostBiteRecoveryOverride(__instance);
			if (StartChasingMethod == null)
			{
				return true;
			}
			StartChasingMethod.Invoke(__instance, null);
			return false;
		}

		[HarmonyPatch(typeof(MushroomZombieBiteCollider), "OnTriggerEnter")]
		[HarmonyPrefix]
		private static bool BiteColliderPrefix(MushroomZombieBiteCollider __instance, Collider other)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			if (UseVanillaBehavior())
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.parentZombie == (Object)null)
			{
				return false;
			}
			float samePlayerBiteCooldown = GetSamePlayerBiteCooldown();
			Character val = default(Character);
			if (Time.time - __instance.lastBitLocalCharacter < samePlayerBiteCooldown || !CharacterRagdoll.TryGetCharacterFromCollider(other, ref val) || !val.IsLocal)
			{
				return false;
			}
			__instance.lastBitLocalCharacter = Time.time;
			if (val.data.isSkeleton)
			{
				val.refs.afflictions.AddStatus((STATUSTYPE)0, __instance.parentZombie.biteInitialInjury / 8f * 2f, false, true, true);
			}
			else
			{
				val.refs.afflictions.AddStatus((STATUSTYPE)0, __instance.parentZombie.biteInitialInjury, false, true, true);
			}
			val.refs.afflictions.AddStatus((STATUSTYPE)10, __instance.parentZombie.biteInitialSpores, false, true, true);
			Affliction_ZombieBite val2 = new Affliction_ZombieBite(__instance.parentZombie.totalBiteSporesTime, __instance.parentZombie.biteDelayBeforeSpores, __instance.parentZombie.biteSporesPerSecond);
			val.refs.afflictions.AddAffliction((Affliction)(object)val2, false);
			CharacterFallMethod?.Invoke(val, new object[2]
			{
				__instance.parentZombie.biteStunTime,
				0f
			});
			__instance.parentZombie.OnBitCharacter(val);
			return false;
		}
	}
	[HarmonyPatch(typeof(UI_UseItemProgress), "UpdateFillAmount")]
	public static class HideUseItemProgressPatch
	{
		private static bool Prefix(UI_UseItemProgress __instance, ref bool __result)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			try
			{
				if (!Plugin.IsWeaponFeatureEnabled())
				{
					return true;
				}
				Character localCharacter = Character.localCharacter;
				object obj;
				if ((Object)(object)localCharacter == (Object)null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = localCharacter.data;
					obj = (((Object)(object)data != (Object)null) ? data.currentItem : null);
				}
				if (BlowgunInfiniteUsePatch.IsBlowgunItem((Item)obj))
				{
					if ((Object)(object)__instance.fill != (Object)null)
					{
						__instance.fill.fillAmount = 0f;
					}
					__result = false;
					return false;
				}
			}
			catch
			{
			}
			return true;
		}

		internal static void RestoreVanillaUseProgressOnAllUi()
		{
			try
			{
				UI_UseItemProgress[] array = Object.FindObjectsByType<UI_UseItemProgress>((FindObjectsSortMode)0);
				for (int i = 0; i < array.Length; i++)
				{
					RestoreVanillaUseProgressUi(array[i]);
				}
			}
			catch
			{
			}
		}

		private static void RestoreVanillaUseProgressUi(UI_UseItemProgress ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)ui == (Object)null)
			{
				return;
			}
			try
			{
				Character localCharacter = Character.localCharacter;
				object obj;
				if (localCharacter == null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = localCharacter.data;
					obj = ((data != null) ? data.currentItem : null);
				}
				Item val = (Item)obj;
				float num = (((Object)(object)val != (Object)null) ? val.progress : 0f);
				bool flag = num > 0f;
				if ((Object)(object)ui.fill != (Object)null)
				{
					ui.fill.fillAmount = (flag ? num : 0f);
					((Behaviour)ui.fill).enabled = true;
				}
				if ((Object)(object)ui.empty != (Object)null)
				{
					((Behaviour)ui.empty).enabled = true;
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(InventoryItemUI), "UpdateCookedAmount")]
	public static class InventoryItemUiCookColorPatch
	{
		[HarmonyPostfix]
		public static void UpdateCookedAmountPostfix(InventoryItemUI __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Plugin.IsWeaponFeatureEnabled())
				{
					AkUiPatchHelpers.ApplyAkToInventoryUi(__instance);
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(InventoryItemUI), "UpdateNameText")]
	public static class InventoryItemUiNamePatch
	{
		[HarmonyPostfix]
		public static void UpdateNameTextPostfix(InventoryItemUI __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Plugin.IsWeaponFeatureEnabled())
				{
					AkUiPatchHelpers.ApplyAkToInventoryUi(__instance);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[ShootZombies] InventoryItemUiNamePatch failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(InventoryItemUI), "SetItem")]
	public static class InventoryItemUiPatch
	{
		private readonly struct SetItemState : IEquatable<SetItemState>
		{
			private readonly int _prefabInstanceId;

			private readonly int _prefabItemId;

			private readonly int _resolvedItemInstanceId;

			private readonly int _itemDataIdentity;

			private readonly string _displayName;

			private readonly bool _isBlowgunLike;

			public SetItemState(ItemSlot slot, Item resolvedItem, bool isBlowgunLike)
			{
				Item val = slot?.prefab;
				_prefabInstanceId = (((Object)(object)val != (Object)null) ? ((Object)val).GetInstanceID() : 0);
				_prefabItemId = (((Object)(object)val != (Object)null) ? val.itemID : 0);
				_resolvedItemInstanceId = (((Object)(object)resolvedItem != (Object)null) ? ((Object)resolvedItem).GetInstanceID() : 0);
				_itemDataIdentity = ((slot?.data != null) ? RuntimeHelpers.GetHashCode(slot.data) : 0);
				_displayName = ItemPatch.DisplayName ?? string.Empty;
				_isBlowgunLike = isBlowgunLike;
			}

			public bool Equals(SetItemState other)
			{
				if (_prefabInstanceId == other._prefabInstanceId && _prefabItemId == other._prefabItemId && _resolvedItemInstanceId == other._resolvedItemInstanceId && _itemDataIdentity == other._itemDataIdentity && string.Equals(_displayName, other._displayName, StringComparison.Ordinal))
				{
					return _isBlowgunLike == other._isBlowgunLike;
				}
				return false;
			}
		}

		private static readonly Dictionary<int, SetItemState> LastStateByUiId = new Dictionary<int, SetItemState>();

		[HarmonyPostfix]
		public static void SetItemPostfix(InventoryItemUI __instance, ItemSlot slot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			if (!Plugin.IsWeaponFeatureEnabled())
			{
				LastStateByUiId.Remove(instanceID);
				AkUiPatchHelpers.ClearInventoryUiCache(__instance);
				return;
			}
			if (slot == null || slot.IsEmpty())
			{
				LastStateByUiId.Remove(instanceID);
				AkUiPatchHelpers.ClearInventoryUiCache(__instance);
				return;
			}
			try
			{
				Item val = AkUiPatchHelpers.ResolveItemFromSlot(slot);
				Item val2 = (((Object)(object)val != (Object)null) ? val : slot.prefab);
				bool flag = ItemPatch.IsBlowgunLike(val2);
				SetItemState setItemState = new SetItemState(slot, val2, flag);
				if (LastStateByUiId.TryGetValue(instanceID, out var value) && value.Equals(setItemState) && (!flag || AkUiPatchHelpers.IsInventoryUiAlreadyShowingAk(__instance)))
				{
					return;
				}
				LastStateByUiId[instanceID] = setItemState;
				if (flag)
				{
					ItemPatch.ApplyAkDisplayIfNeeded(val2);
					if ((Object)(object)slot.prefab != (Object)null)
					{
						ItemPatch.ApplyAkDisplayIfNeeded(slot.prefab);
					}
					AkUiPatchHelpers.ApplyAkToInventoryUi(__instance, val2);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] InventoryItemUiPatch failed: " + ex));
			}
		}

		internal static void ClearCaches()
		{
			LastStateByUiId.Clear();
		}
	}
	[HarmonyPatch]
	public static class ItemPatch
	{
		private struct SourceVisualCandidate
		{
			public Mesh Mesh;

			public Material[] Materials;

			public Transform Transform;

			public int VertexCount;

			public int Score;

			public string Path;

			public string MeshName;
		}

		private const string LocalVisualName = "AK_VisualRoot";

		private const string VisualCloneName = "AK_LocalVisualClone";

		private const string SimpleVisualName = "AK47Model";

		private const string MuzzleMarkerName = "AK_MuzzleMarker";

		private const string WorldColliderName = "AK_WorldCollider";

		private const string HeldLegacyVisualName = "AK47_HeldLegacyModel";

		private const string InPlaceVisualRootName = "AK_InPlaceVisualRoot";

		private const string HeldDebugSphereName = "AK_HeldDebugSphere";

		private static readonly Quaternion HeldLegacyRotationOffset = Quaternion.identity;

		private static readonly Vector3 HeldLegacyPositionOffset = new Vector3(-0.01f, 0.01f, 0f);

		private static readonly Quaternion InPlaceYawOffset = Quaternion.Euler(0f, 0f, 0f);

		private static readonly string[] SelectableWeaponKeywords = new string[4] { "ak47", "mpx", "hk416", "hk417" };

		private const float RuntimeVisualBaseScaleMultiplier = 1.275f;

		private static readonly string[] ItemKeywords = new string[5] { "healingdart", "blowgun", "dart", "吹箭筒", "ak47" };

		private static readonly string[] ExcludedVisualKeywords = new string[9] { "hand", "arm", "finger", "collider", "trigger", "vfx", "effect", "spawn", "holiday" };

		private static readonly Dictionary<int, Renderer[]> HiddenRendererCache = new Dictionary<int, Renderer[]>();

		private static readonly HashSet<int> InPlaceSwappedItemIds = new HashSet<int>();

		private static readonly Dictionary<int, int> PendingSetStateValueByItemId = new Dictionary<int, int>();

		private static readonly Dictionary<int, Character> PendingSetStateHolderByItemId = new Dictionary<int, Character>();

		private const bool UseDebugAnchorSphereVisual = false;

		private static Mesh _debugCubeMesh;

		private static Material[] _debugCubeMaterials;

		private static Mesh _debugSphereMesh;

		private static Material[] _debugSphereMaterials;

		private static Material[] _meshOnlyTestMaterials;

		private static Material[] _cachedDirectAkSharedMaterials;

		private static int _cachedDirectAkSharedMaterialsHash;

		private static string _cachedCombinedWeaponSelection = string.Empty;

		private const bool PreferInPlaceMeshSwap = true;

		private const bool PreferLegacyHeldVisualForLocalPlayer = false;

		private const bool EnableHeldDebugSphereVisual = false;

		private static readonly string[] MainRendererFieldNames = new string[6] { "<mainRenderer>k__BackingField", "mainRenderer", "_mainRenderer", "<MainRenderer>k__BackingField", "MainRenderer", "_MainRenderer" };

		private static readonly string[] MainRendererPropertyNames = new string[2] { "mainRenderer", "MainRenderer" };

		private static readonly string[] AddtlRendererFieldNames = new string[6] { "<addtlRenderers>k__BackingField", "addtlRenderers", "_addtlRenderers", "<AddtlRenderers>k__BackingField", "AddtlRenderers", "_AddtlRenderers" };

		internal static string DisplayName => Plugin.GetCurrentWeaponDisplayName();

		private static Quaternion GetDirectAkRotationOverride()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Plugin.GetDirectAkRotationOverride();
		}

		private static float GetDirectAkScaleMultiplier(string selection = null)
		{
			return Plugin.GetEffectiveWeaponModelScale(string.IsNullOrWhiteSpace(selection) ? Plugin.GetCurrentWeaponSelection() : selection);
		}

		private static Vector3 GetDirectAkPositionOverride(string selection = null)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return Plugin.GetDirectAkPositionOverride(string.IsNullOrWhiteSpace(selection) ? Plugin.GetCurrentWeaponSelection() : selection);
		}

		private static string DescribeItemForDiagnostics(Item item)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected I4, but got Unknown
			if ((Object)(object)item == (Object)null)
			{
				return "item=null";
			}
			string text = ((((Object)((Component)item).gameObject).name ?? string.Empty) + "/" + (((Object)((Component)item).transform).name ?? string.Empty)).Trim(new char[1] { '/' });
			string text2 = (((Object)(object)item.holderCharacter != (Object)null) ? ((Object)item.holderCharacter).name : null) ?? "null";
			string text3 = item.UIData?.itemName ?? "null";
			return $"name={text}, itemID={item.itemID}, state={(int)item.itemState}, holder={text2}, uiName={text3}";
		}

		private stati