Decompiled source of PeakShotgun v1.0.25

plugins/PeakShotgun.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using PEAKLib.Items;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Arman Ossi Loko")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 Fake Game Developers")]
[assembly: AssemblyDescription("A shotgun built from PEAK's blowgun. Blasts flip zombies harder than a coconut and dose them with drowsy.")]
[assembly: AssemblyFileVersion("1.0.25.0")]
[assembly: AssemblyInformationalVersion("1.0.25+88c4ea6fbe8f6e39c2f5688776d748f97a856b66")]
[assembly: AssemblyProduct("PeakShotgun")]
[assembly: AssemblyTitle("PeakShotgun")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.25.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Peak.Shotgun
{
	public class Action_Ammo : ItemAction
	{
		public bool consumeOnFullyUsed;

		internal bool TrySpendOne()
		{
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			if (!((ItemActionBase)this).item.HasData((DataEntryKey)2))
			{
				EnsureHostMagazine();
			}
			OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (!data.HasData)
			{
				EnsureHostMagazine();
				data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			}
			if (!data.HasData || data.Value <= 0)
			{
				BroadcastUses(0);
				return false;
			}
			OptionableIntItemData obj = data;
			obj.Value--;
			BroadcastUses(data.Value);
			if (data.Value == 0 && consumeOnFullyUsed && Object.op_Implicit((Object)(object)((ItemActionBase)this).character) && ((ItemActionBase)this).character.IsLocal && (Object)(object)((ItemActionBase)this).character.data.currentItem == (Object)(object)((ItemActionBase)this).item)
			{
				((MonoBehaviour)((ItemActionBase)this).item).StartCoroutine(((ItemActionBase)this).item.ConsumeDelayed(false));
			}
			return true;
		}

		internal void EnsureHostMagazine()
		{
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				return;
			}
			int shotCount = Plugin.ShotCount;
			((ItemActionBase)this).item.totalUses = shotCount;
			OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (!data.HasData || data.Value < 0)
			{
				data.HasData = true;
				data.Value = shotCount;
				((ItemActionBase)this).item.SetUseRemainingPercentage(1f);
				if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)((ItemActionBase)this).item).photonView != (Object)null)
				{
					((MonoBehaviourPun)((ItemActionBase)this).item).photonView.RPC("ApplyUsesRPC", (RpcTarget)0, new object[2] { data.Value, shotCount });
				}
			}
		}

		internal bool TryRefillToCapacity()
		{
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			int shotCount = Plugin.ShotCount;
			((ItemActionBase)this).item.totalUses = shotCount;
			if (!((ItemActionBase)this).item.HasData((DataEntryKey)2))
			{
				EnsureHostMagazine();
			}
			OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (!data.HasData)
			{
				EnsureHostMagazine();
				data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			}
			if (data.HasData && data.Value >= shotCount)
			{
				if (data.Value > shotCount)
				{
					data.Value = shotCount;
					BroadcastUses(shotCount);
				}
				return false;
			}
			data.HasData = true;
			data.Value = shotCount;
			BroadcastUses(shotCount);
			return true;
		}

		private void BroadcastUses(int remaining)
		{
			int num = Mathf.Max(((ItemActionBase)this).item.totalUses, Plugin.ShotCount);
			((ItemActionBase)this).item.totalUses = num;
			if (!PhotonNetwork.InRoom)
			{
				ApplyUses(remaining, num);
				return;
			}
			((MonoBehaviourPun)((ItemActionBase)this).item).photonView.RPC("ApplyUsesRPC", (RpcTarget)0, new object[2] { remaining, num });
		}

		[PunRPC]
		public void ApplyUsesRPC(int remaining, int capacity, PhotonMessageInfo info)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.InRoom || (info.Sender != null && info.Sender.IsMasterClient))
			{
				ApplyUses(remaining, capacity);
			}
		}

		private void ApplyUses(int remaining, int capacity)
		{
			((ItemActionBase)this).item.totalUses = Mathf.Max(1, capacity);
			OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			data.HasData = true;
			data.Value = Mathf.Max(0, remaining);
			if (((ItemActionBase)this).item.totalUses > 0)
			{
				((ItemActionBase)this).item.SetUseRemainingPercentage((float)data.Value / (float)((ItemActionBase)this).item.totalUses);
			}
			SyncHolderSlotUses(data.Value);
			ShotgunAmmoUI.Refresh();
		}

		private void SyncHolderSlotUses(int remaining)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			Character val = (((Object)(object)((ItemActionBase)this).character != (Object)null) ? ((ItemActionBase)this).character : ((ItemActionBase)this).item.holderCharacter);
			if ((Object)(object)val == (Object)null || (Object)(object)val.player == (Object)null || ((ItemActionBase)this).item.data == null)
			{
				return;
			}
			ItemSlot val2 = FindSlotHolding(val.player, ((ItemActionBase)this).item.data.guid);
			if (((val2 != null) ? val2.data : null) != null)
			{
				OptionableIntItemData val3 = default(OptionableIntItemData);
				if (val2.data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val3))
				{
					val3.HasData = true;
					val3.Value = remaining;
					return;
				}
				OptionableIntItemData val4 = new OptionableIntItemData
				{
					HasData = true,
					Value = remaining
				};
				val2.data.RegisterEntry<OptionableIntItemData>((DataEntryKey)2, val4);
			}
		}

		private static ItemSlot? FindSlotHolding(Player player, Guid guid)
		{
			ItemSlot[] itemSlots = player.itemSlots;
			foreach (ItemSlot val in itemSlots)
			{
				if (((val != null) ? val.data : null) != null && val.data.guid == guid)
				{
					return val;
				}
			}
			ItemSlot tempFullSlot = player.tempFullSlot;
			if (((tempFullSlot != null) ? tempFullSlot.data : null) == null || !(tempFullSlot.data.guid == guid))
			{
				return null;
			}
			return tempFullSlot;
		}
	}
	public class Action_Gun : ItemAction
	{
		private readonly struct PendingHit
		{
			public readonly int TargetId;

			public readonly Action Apply;

			public PendingHit(int targetId, Action apply)
			{
				TargetId = targetId;
				Apply = apply;
			}
		}

		public float maxDistance = 40f;

		public float pelletRadius = 0.2f;

		public float fireRate = 0.85f;

		public float spread = 0.07f;

		public int pelletCount = 8;

		[SerializeReference]
		public Affliction[] afflictionsOnHit = Array.Empty<Affliction>();

		public Transform? spawnTransform;

		public SFX_Instance? shotSFX;

		public SFX_Instance? emptyClickSFX;

		public Action? OnShoot;

		private const float PendingShotRetry = 1.5f;

		private const float HostFireRateTolerance = 0.9f;

		private const float AuthorizedShotLifetime = 10f;

		private static int nextShotId;

		private float lastShootTime = float.NegativeInfinity;

		private int pendingShotId;

		private float pendingShotSentTime;

		private Vector3 pendingForward;

		private readonly Dictionary<int, (int shotId, bool accepted)> lastShotBySender = new Dictionary<int, (int, bool)>();

		private double lastAcceptedShotTime = double.NegativeInfinity;

		private readonly Dictionary<long, float> authorizedShots = new Dictionary<long, float>();

		private readonly Dictionary<long, HashSet<int>> consumedTargets = new Dictionary<long, HashSet<int>>();

		private readonly Dictionary<long, List<PendingHit>> pendingHits = new Dictionary<long, List<PendingHit>>();

		public override void RunAction()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (pendingShotId != 0)
			{
				if (Time.time >= pendingShotSentTime + 1.5f)
				{
					pendingForward = ((Component)MainCamera.instance).transform.forward;
					SendShotRequest();
				}
			}
			else if (!(Time.time <= lastShootTime + fireRate) && !((Object)(object)spawnTransform == (Object)null))
			{
				if (!HasAmmo())
				{
					lastShootTime = Time.time;
					PlayEmptyClick();
					return;
				}
				lastShootTime = Time.time;
				pendingShotId = ++nextShotId;
				pendingForward = ((Component)MainCamera.instance).transform.forward;
				SendShotRequest();
			}
		}

		private void SendShotRequest()
		{
			pendingShotSentTime = Time.time;
			if (!PhotonNetwork.InRoom)
			{
				HandleShotRequest(pendingShotId, null, Time.timeAsDouble);
				return;
			}
			((MonoBehaviourPun)this).photonView.RPC("RPC_RequestShot", (RpcTarget)2, new object[1] { pendingShotId });
		}

		[PunRPC]
		public void RPC_RequestShot(int shotId, PhotonMessageInfo info)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.IsMasterClient)
			{
				HandleShotRequest(shotId, info.Sender, ((PhotonMessageInfo)(ref info)).SentServerTime);
			}
		}

		private void HandleShotRequest(int shotId, Player? sender, double sentTime)
		{
			int num = ((sender != null) ? sender.ActorNumber : 0);
			if (lastShotBySender.TryGetValue(num, out (int, bool) value))
			{
				if (shotId < value.Item1)
				{
					return;
				}
				if (shotId == value.Item1)
				{
					SendShotResult(num, shotId, value.Item2);
					return;
				}
			}
			double num2 = sentTime - lastAcceptedShotTime;
			bool flag = num2 >= (double)(fireRate * 0.9f) || num2 < -60.0;
			Action_Ammo component = ((Component)this).GetComponent<Action_Ammo>();
			bool flag2 = IsHeldBy(sender) && flag && (Object)(object)component != (Object)null && component.TrySpendOne();
			if (flag2)
			{
				lastAcceptedShotTime = sentTime;
			}
			lastShotBySender[num] = (shotId, flag2);
			SendShotResult(num, shotId, flag2);
		}

		private bool IsHeldBy(Player? sender)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			Character holderCharacter = ((ItemActionBase)this).item.holderCharacter;
			if ((int)((ItemActionBase)this).item.itemState != 1 || (Object)(object)holderCharacter == (Object)null)
			{
				return false;
			}
			if (sender != null)
			{
				if ((Object)(object)((MonoBehaviourPun)holderCharacter).photonView != (Object)null)
				{
					return ((MonoBehaviourPun)holderCharacter).photonView.Owner == sender;
				}
				return false;
			}
			return true;
		}

		private void SendShotResult(int shooterActor, int shotId, bool accepted)
		{
			if (!PhotonNetwork.InRoom)
			{
				OnShotResult(shotId, accepted);
				return;
			}
			if (accepted)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_ShotResult", (RpcTarget)0, new object[3] { shooterActor, shotId, true });
				return;
			}
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Player val = ((currentRoom != null) ? currentRoom.GetPlayer(shooterActor, false) : null);
			if (val != null)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_ShotResult", val, new object[3] { shooterActor, shotId, false });
			}
		}

		[PunRPC]
		public void RPC_ShotResult(int shooterActor, int shotId, bool accepted, PhotonMessageInfo info)
		{
			//IL_0000: 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)
			if (info.Sender != null && info.Sender.IsMasterClient)
			{
				if (accepted)
				{
					RecordAuthorizedShot(shooterActor, shotId);
				}
				if (PhotonNetwork.LocalPlayer != null && shooterActor == PhotonNetwork.LocalPlayer.ActorNumber)
				{
					OnShotResult(shotId, accepted);
				}
			}
		}

		private void OnShotResult(int shotId, bool accepted)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (shotId == pendingShotId)
			{
				pendingShotId = 0;
				if (accepted)
				{
					Fire(shotId, pendingForward);
				}
			}
		}

		private static long ShotKey(int shooterActor, int shotId)
		{
			return ((long)shooterActor << 32) | (uint)shotId;
		}

		private void RecordAuthorizedShot(int shooterActor, int shotId)
		{
			float time = Time.time;
			List<long> list = new List<long>();
			foreach (KeyValuePair<long, float> authorizedShot in authorizedShots)
			{
				if (time - authorizedShot.Value > 10f)
				{
					list.Add(authorizedShot.Key);
				}
			}
			foreach (long item in list)
			{
				authorizedShots.Remove(item);
				consumedTargets.Remove(item);
				pendingHits.Remove(item);
			}
			long key = ShotKey(shooterActor, shotId);
			authorizedShots[key] = time;
			FlushPendingHits(key);
		}

		internal bool TryConsumeShot(Player? sender, int shotId, int targetId)
		{
			if (!PhotonNetwork.InRoom)
			{
				return true;
			}
			if (sender == null)
			{
				return false;
			}
			long key = ShotKey(sender.ActorNumber, shotId);
			if (!authorizedShots.ContainsKey(key))
			{
				return false;
			}
			return ConsumeTarget(key, targetId);
		}

		internal bool TryConsumeOrDeferHit(Player? sender, int shotId, int targetId, Action apply)
		{
			if (!PhotonNetwork.InRoom)
			{
				return true;
			}
			if (sender == null)
			{
				return false;
			}
			long key = ShotKey(sender.ActorNumber, shotId);
			if (!authorizedShots.ContainsKey(key))
			{
				if (!pendingHits.TryGetValue(key, out List<PendingHit> value))
				{
					value = new List<PendingHit>();
					pendingHits[key] = value;
				}
				value.Add(new PendingHit(targetId, apply));
				return false;
			}
			return ConsumeTarget(key, targetId);
		}

		private bool ConsumeTarget(long key, int targetId)
		{
			if (!consumedTargets.TryGetValue(key, out HashSet<int> value))
			{
				value = new HashSet<int>();
				consumedTargets[key] = value;
			}
			return value.Add(targetId);
		}

		private void FlushPendingHits(long key)
		{
			if (!pendingHits.TryGetValue(key, out List<PendingHit> value))
			{
				return;
			}
			pendingHits.Remove(key);
			foreach (PendingHit item in value)
			{
				if (ConsumeTarget(key, item.TargetId))
				{
					item.Apply();
				}
			}
		}

		private void PlayEmptyClick()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			Vector3 val = (((Object)(object)spawnTransform != (Object)null) ? spawnTransform.position : ((Component)this).transform.position);
			if (PhotonNetwork.InRoom)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_EmptyClick", (RpcTarget)0, new object[1] { val });
			}
			else
			{
				PlayEmptyClickAt(val);
			}
		}

		[PunRPC]
		private void RPC_EmptyClick(Vector3 origin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayEmptyClickAt(origin);
		}

		private void PlayEmptyClickAt(Vector3 origin)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			SFX_Instance? obj = emptyClickSFX ?? shotSFX;
			if (obj != null)
			{
				obj.Play(origin);
			}
		}

		private bool HasAmmo()
		{
			if (!((ItemActionBase)this).item.HasData((DataEntryKey)2))
			{
				return ((ItemActionBase)this).item.totalUses <= 0;
			}
			OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (!data.HasData)
			{
				return ((ItemActionBase)this).item.totalUses <= 0;
			}
			if (data.Value >= 0)
			{
				return data.Value > 0;
			}
			return true;
		}

		private void Fire(int shotId, Vector3 forward)
		{
			//IL_0041: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)spawnTransform == (Object)null) && !((Object)(object)((ItemActionBase)this).character == (Object)null) && ((ItemActionBase)this).character.IsLocal)
			{
				OnShoot?.Invoke();
				Vector3 position = spawnTransform.position;
				Vector3 val = Vector3.Cross(Vector3.up, forward);
				if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
				{
					val = Vector3.right;
				}
				((Vector3)(ref val)).Normalize();
				Vector3 val2 = Vector3.Cross(forward, val);
				if (Plugin.Recoil > 0f)
				{
					((ItemActionBase)this).character.AddForce(-forward * (Plugin.Recoil / Time.fixedDeltaTime), 1f, 1f);
				}
				HashSet<int> struck = new HashSet<int>();
				float[] array = new float[pelletCount * 4];
				bool flag = false;
				for (int i = 0; i < pelletCount; i++)
				{
					Vector2 val3 = PelletOffset(i, pelletCount, spread);
					Vector3 val4 = forward + val * val3.x + val2 * val3.y;
					Vector3 normalized = ((Vector3)(ref val4)).normalized;
					flag |= TryPellet(shotId, position, normalized, struck, out var end, out var impact);
					ShotgunVFX.PackPellet(array, i, end, impact);
				}
				if (flag)
				{
					ShotgunHitMarker.Show(defeat: false);
				}
				((MonoBehaviourPun)this).photonView.RPC("RPC_ShotgunBlastFX", (RpcTarget)0, new object[3] { position, forward, array });
			}
		}

		private bool TryPellet(int shotId, Vector3 origin, Vector3 direction, HashSet<int> struck, out Vector3 end, out bool impact)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_00ac: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			float distance = maxDistance;
			end = origin + direction * maxDistance;
			impact = false;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(origin, direction, ref val, maxDistance, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1))
			{
				distance = ((RaycastHit)(ref val)).distance;
				end = ((RaycastHit)(ref val)).point;
				impact = true;
			}
			RaycastHit[] array = Physics.SphereCastAll(origin, pelletRadius, direction, distance, LayerMask.op_Implicit(HelperFunctions.CharacterAndDefaultMask) | ShotTargetRegistry.ExtraLayerMask, (QueryTriggerInteraction)2);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			RaycastHit[] array2 = array;
			for (int num = 0; num < array2.Length; num++)
			{
				RaycastHit val2 = array2[num];
				if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val2)).collider))
				{
					int instanceID = ((Object)((Component)((RaycastHit)(ref val2)).collider).transform.root).GetInstanceID();
					if (!struck.Contains(instanceID) && ShotgunCombat.TryHit(((RaycastHit)(ref val2)).collider, ((ItemActionBase)this).character, this, shotId, ((RaycastHit)(ref val2)).point, direction))
					{
						struck.Add(instanceID);
						end = ((((RaycastHit)(ref val2)).distance > 0f) ? ((RaycastHit)(ref val2)).point : (origin + direction * pelletRadius));
						impact = true;
						return true;
					}
				}
			}
			return false;
		}

		[PunRPC]
		public void RPC_GunImpact(Player? hitPlayer, Vector3 endpoint, Vector3 direction, int shotId, PhotonMessageInfo info)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (hitPlayer == null || !hitPlayer.IsLocal)
			{
				return;
			}
			Character local = Character.localCharacter;
			if (!((Object)(object)local == (Object)null))
			{
				int viewID = ((MonoBehaviourPun)local).photonView.ViewID;
				if (TryConsumeOrDeferHit(info.Sender, shotId, viewID, delegate
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					ApplyGunImpact(local, direction, endpoint);
				}))
				{
					ApplyGunImpact(local, direction, endpoint);
				}
			}
		}

		private void ApplyGunImpact(Character local, Vector3 direction, Vector3 endpoint)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (ShootableRules.Scouts.Enabled)
			{
				((Component)local).GetComponent<GunCharacterLaunch>().Blast(direction, endpoint);
				Affliction[] array = afflictionsOnHit;
				foreach (Affliction val in array)
				{
					local.refs.afflictions.AddAffliction(val, false);
				}
			}
		}

		[PunRPC]
		public void RPC_HostShootTarget(int viewId, int kind, int shotId, int extra, PhotonMessageInfo info)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.IsMasterClient && TryConsumeShot(info.Sender, shotId, viewId))
			{
				PhotonView val = PhotonView.Find(viewId);
				if ((Object)(object)val != (Object)null)
				{
					ShotgunCombat.HostApply(val, (ShotTargetKind)kind, this, extra, info.Sender);
				}
			}
		}

		[PunRPC]
		public void RPC_ShotDefeat(int targetViewId, PhotonMessageInfo info)
		{
			//IL_0000: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			if (info.Sender == null)
			{
				return;
			}
			if (!info.Sender.IsMasterClient)
			{
				PhotonView val = PhotonView.Find(targetViewId);
				if ((Object)(object)val == (Object)null || val.Owner != info.Sender)
				{
					return;
				}
			}
			ShotgunHitMarker.Show(defeat: true);
		}

		[PunRPC]
		public void RPC_ApplyWorldDefeat(int viewId, int kind, int extra, PhotonMessageInfo info)
		{
			//IL_0000: 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)
			if (info.Sender != null && info.Sender.IsMasterClient)
			{
				ShotgunCombat.ClientApplyDefeat(PhotonView.Find(viewId), (ShotTargetKind)kind, extra);
			}
		}

		[PunRPC]
		public void RPC_ShotEffect(int viewId, int kind, int extra, Vector3 push, int variant, PhotonMessageInfo info)
		{
			//IL_0000: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			if (info.Sender != null && info.Sender.IsMasterClient)
			{
				ShotgunCombat.ApplyEffect(PhotonView.Find(viewId), (ShotTargetKind)kind, extra, push, variant);
			}
		}

		[PunRPC]
		private void RPC_ShotgunBlastFX(Vector3 origin, Vector3 forward, float[] pellets)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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)
			SFX_Instance? obj = shotSFX;
			if (obj != null)
			{
				obj.Play(origin);
			}
			ShotgunVFX vfx = ((Component)this).GetComponent<ShotgunVFX>();
			if ((Object)(object)vfx != (Object)null)
			{
				vfx.Play(origin, forward);
				Plugin.Guard("Pellet tracers and impacts", delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					vfx.Pellets(origin, pellets);
				});
			}
			GamefeelHandler.instance.AddPerlinShakeProximity(origin + forward * 3f, 12f, 0.2f, 15f, 10f);
		}

		private static Vector2 PelletOffset(int index, int count, float radius)
		{
			//IL_0041: 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_0004: Unknown result type (might be due to invalid IL or missing references)
			if (index <= 0)
			{
				return Vector2.zero;
			}
			float num = (float)index * 137.5f * (MathF.PI / 180f);
			float num2 = radius * (0.4f + 0.6f * ((float)index / (float)Mathf.Max(1, count - 1)));
			return new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * num2;
		}
	}
	public class AmmoPileInteract : MonoBehaviour
	{
		private Item item;

		private void Awake()
		{
			item = ((Component)this).GetComponent<Item>();
		}

		internal static bool IsAmmoPile(Item? candidate)
		{
			if ((Object)(object)candidate != (Object)null)
			{
				return (Object)(object)((Component)candidate).GetComponent<AmmoPileInteract>() != (Object)null;
			}
			return false;
		}

		internal static bool CanRefillFrom(Character? interactor, out Item? shotgun)
		{
			shotgun = null;
			if ((Object)(object)interactor?.data == (Object)null)
			{
				return false;
			}
			Item currentItem = interactor.data.currentItem;
			if ((Object)(object)currentItem == (Object)null || (Object)(object)((Component)currentItem).GetComponent<Action_Gun>() == (Object)null || (Object)(object)((Component)currentItem).GetComponent<Action_Ammo>() == (Object)null)
			{
				return false;
			}
			shotgun = currentItem;
			if (!ShotgunAmmoUI.TryGetRemaining(currentItem, null, out var remaining))
			{
				return true;
			}
			return remaining < Plugin.ShotCount;
		}

		internal void RequestRefill(Character interactor)
		{
			if (CanRefillFrom(interactor, out Item _))
			{
				if (!PhotonNetwork.InRoom)
				{
					HostTryRefill(interactor);
				}
				else if (!((Object)(object)((MonoBehaviourPun)item).photonView == (Object)null))
				{
					((MonoBehaviourPun)item).photonView.RPC("RequestRefillRPC", (RpcTarget)2, new object[1] { ((MonoBehaviourPun)interactor).photonView.ViewID });
				}
			}
		}

		[PunRPC]
		public void RequestRefillRPC(int characterViewId, PhotonMessageInfo info)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)
			{
				PhotonView val = PhotonView.Find(characterViewId);
				Character val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Character>() : null);
				if (!((Object)(object)val2 == (Object)null) && (!PhotonNetwork.InRoom || (info.Sender != null && !((Object)(object)((MonoBehaviourPun)val2).photonView == (Object)null) && info.Sender == ((MonoBehaviourPun)val2).photonView.Owner)))
				{
					HostTryRefill(val2);
				}
			}
		}

		private void HostTryRefill(Character interactor)
		{
			if (!CanRefillFrom(interactor, out Item shotgun) || (Object)(object)shotgun == (Object)null)
			{
				return;
			}
			Action_Ammo component = ((Component)shotgun).GetComponent<Action_Ammo>();
			if (!((Object)(object)component == (Object)null) && component.TryRefillToCapacity())
			{
				ManualLogSource log = Plugin.Log;
				PhotonView photonView = ((MonoBehaviourPun)interactor).photonView;
				object obj;
				if (photonView == null)
				{
					obj = null;
				}
				else
				{
					Player owner = photonView.Owner;
					obj = ((owner != null) ? owner.NickName : null);
				}
				if (obj == null)
				{
					obj = "scout";
				}
				log.LogInfo((object)$"Ammo pile refilled {obj}'s shotgun to {Plugin.ShotCount}.");
			}
		}
	}
	internal static class AmmoPileModelSwap
	{
		private const string ObjResource = "Peak.Shotgun.models.ammo_pile.obj";

		private const string AlbedoResource = "Peak.Shotgun.models.ammo_pile_albedo.png";

		private const string ItemShader = "W/Peak_Standard";

		internal static void Apply(GameObject pileObject, ItemDatabase database)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = LoadEmbeddedMesh();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Custom ammo pile mesh could not be loaded; keeping the clone look.");
				return;
			}
			Texture2D albedo = LoadEmbeddedTexture("Peak.Shotgun.models.ammo_pile_albedo.png", "AmmoPileAlbedo");
			Material val2 = FindItemMaterial(database);
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = FindAnyMaterial(pileObject);
			}
			HideVanillaRenderers(pileObject);
			GameObject val3 = new GameObject("AmmoPileVisual");
			val3.transform.SetParent(pileObject.transform, false);
			val3.transform.localPosition = Vector3.zero;
			val3.transform.localRotation = Quaternion.Euler(-90f, 0f, 0f);
			val3.transform.localScale = Vector3.one * 0.425f;
			MeshFilter val4 = val3.AddComponent<MeshFilter>();
			val4.sharedMesh = val;
			MeshRenderer val5 = val3.AddComponent<MeshRenderer>();
			((Renderer)val5).sharedMaterial = BuildMaterial(val2, albedo);
			RefitCollider(pileObject, val3, val);
			Item component = pileObject.GetComponent<Item>();
			if ((Object)(object)component != (Object)null)
			{
				component.mainRenderer = (Renderer)(object)val5;
				component.addtlRenderers = Array.Empty<Renderer>();
			}
			ManualLogSource log = Plugin.Log;
			object arg = 0.425f;
			Material sharedMaterial = ((Renderer)val5).sharedMaterial;
			object arg2;
			if (sharedMaterial == null)
			{
				arg2 = null;
			}
			else
			{
				Shader shader = sharedMaterial.shader;
				arg2 = ((shader != null) ? ((Object)shader).name : null);
			}
			log.LogInfo((object)$"Applied ammo pile mesh (scale={arg:0.###}, shader={arg2}).");
		}

		private static Material? FindItemMaterial(ItemDatabase database)
		{
			foreach (Item @object in ((DatabaseAsset<ItemDatabase, Item>)(object)database).Objects)
			{
				if ((Object)(object)@object == (Object)null)
				{
					continue;
				}
				Renderer[] componentsInChildren = ((Component)@object).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					Material[] sharedMaterials = val.sharedMaterials;
					foreach (Material val2 in sharedMaterials)
					{
						if ((Object)(object)val2 != (Object)null && (Object)(object)val2.shader != (Object)null && ((Object)val2.shader).name == "W/Peak_Standard")
						{
							return val2;
						}
					}
				}
			}
			return null;
		}

		private static Material? FindAnyMaterial(GameObject root)
		{
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material sharedMaterial = val.sharedMaterial;
				if ((Object)(object)((sharedMaterial != null) ? sharedMaterial.shader : null) != (Object)null)
				{
					return val.sharedMaterial;
				}
			}
			return null;
		}

		private static Material BuildMaterial(Material? peakMaterial, Texture2D? albedo)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			Material val;
			if ((Object)(object)peakMaterial != (Object)null)
			{
				val = new Material(peakMaterial.shader);
				val.CopyPropertiesFromMaterial(peakMaterial);
				ClearTextures(val);
			}
			else
			{
				val = new Material(Shader.Find("Hidden/InternalErrorShader"));
			}
			((Object)val).name = "AmmoPileCustom";
			if ((Object)(object)albedo != (Object)null)
			{
				string[] array = new string[10] { "_MainTex", "_BaseMap", "_BaseColorMap", "_UnlitColorMap", "_Albedo", "_Diffuse", "_Texture", "_MainTexture", "_BaseColorTexture", "_BaseTexture" };
				string[] array2 = array;
				foreach (string text in array2)
				{
					if (val.HasProperty(text))
					{
						val.SetTexture(text, (Texture)(object)albedo);
					}
				}
				try
				{
					val.mainTexture = (Texture)(object)albedo;
				}
				catch
				{
				}
				if (val.HasProperty("_BaseTexAmount"))
				{
					val.SetFloat("_BaseTexAmount", 1f);
				}
				string[] array3 = new string[3] { "_Color", "_BaseColor", "_UnlitColor" };
				foreach (string text2 in array3)
				{
					if (val.HasProperty(text2))
					{
						val.SetColor(text2, Color.white);
					}
				}
			}
			if (val.HasProperty("_Cull"))
			{
				val.SetFloat("_Cull", 0f);
			}
			return val;
		}

		private static void ClearTextures(Material material)
		{
			List<string> list = new List<string>();
			material.GetTexturePropertyNames(list);
			foreach (string item in list)
			{
				if (material.HasProperty(item))
				{
					material.SetTexture(item, (Texture)null);
				}
			}
		}

		private static void HideVanillaRenderers(GameObject root)
		{
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is ParticleSystemRenderer))
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
			MeshFilter[] componentsInChildren2 = root.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val2 in componentsInChildren2)
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
		}

		private static void RefitCollider(GameObject root, GameObject visual, Mesh mesh)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			Item component = root.GetComponent<Item>();
			bool flag = (Object)(object)component != (Object)null && Item.ALL_ITEMS.Contains(component);
			Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (flag && Item.COLLIDER_TO_ITEM.TryGetValue(val, out var value) && (Object)(object)value == (Object)(object)component)
				{
					Item.COLLIDER_TO_ITEM.Remove(val);
				}
				Object.DestroyImmediate((Object)(object)val);
			}
			BoxCollider val2 = visual.AddComponent<BoxCollider>();
			((Collider)val2).isTrigger = false;
			Bounds bounds = mesh.bounds;
			val2.center = ((Bounds)(ref bounds)).center;
			bounds = mesh.bounds;
			val2.size = ((Bounds)(ref bounds)).size;
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			component.colliders = root.GetComponentsInChildren<Collider>(true);
			if (flag)
			{
				Collider[] colliders = component.colliders;
				foreach (Collider key in colliders)
				{
					Item.COLLIDER_TO_ITEM[key] = component;
				}
			}
		}

		private static Mesh? LoadEmbeddedMesh()
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Peak.Shotgun.models.ammo_pile.obj");
			if (stream == null)
			{
				Plugin.Log.LogWarning((object)"Embedded mesh resource 'Peak.Shotgun.models.ammo_pile.obj' was not found.");
				return null;
			}
			return ObjMeshLoader.Load(stream, "AmmoPileMesh");
		}

		private static Texture2D? LoadEmbeddedTexture(string resourceName, string textureName)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				Plugin.Log.LogWarning((object)("Embedded texture '" + resourceName + "' was not found."));
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray()))
			{
				Plugin.Log.LogWarning((object)("Embedded texture '" + resourceName + "' could not be decoded."));
				return null;
			}
			((Object)val).name = textureName;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).anisoLevel = 4;
			return val;
		}
	}
	[HarmonyPatch(typeof(Item), "IsInteractible")]
	internal static class AmmoPileIsInteractiblePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance, Character interactor, ref bool __result)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			if (!AmmoPileInteract.IsAmmoPile(__instance))
			{
				return true;
			}
			if (__instance.blockInteraction || (int)__instance.itemState == 1 || (int)__instance.itemState == 2)
			{
				__result = false;
				return false;
			}
			__result = AmmoPileInteract.CanRefillFrom(interactor, out Item _);
			return false;
		}
	}
	[HarmonyPatch(typeof(Item), "GetInteractionText")]
	internal static class AmmoPileInteractionTextPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance, ref string __result)
		{
			if (!AmmoPileInteract.IsAmmoPile(__instance))
			{
				return true;
			}
			__result = ShotgunText.Refill;
			return false;
		}
	}
	[HarmonyPatch(typeof(Item), "Interact")]
	internal static class AmmoPileInteractPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance, Character interactor)
		{
			AmmoPileInteract component = ((Component)__instance).GetComponent<AmmoPileInteract>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			component.RequestRefill(interactor);
			return false;
		}
	}
	internal static class CampfireAmmoSpawner
	{
		private static readonly HashSet<int> SpawnedKeys = new HashSet<int>();

		internal static void ClearRunState()
		{
			SpawnedKeys.Clear();
		}

		internal static void TrySpawnAtRoot(GameObject? campfireRoot)
		{
			if (!((Object)(object)campfireRoot == (Object)null))
			{
				Campfire componentInChildren = campfireRoot.GetComponentInChildren<Campfire>(true);
				if ((Object)(object)componentInChildren == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Campfire ammo: SpawnCampfireItems root had no Campfire component.");
				}
				else
				{
					TrySpawnAround(componentInChildren);
				}
			}
		}

		internal static IEnumerator WhenMapIsReady()
		{
			if (!Plugin.SpawnAmmoPilesAtCampfire)
			{
				yield break;
			}
			WaitForSecondsRealtime wait = new WaitForSecondsRealtime(0.5f);
			for (int i = 0; i < 60; i++)
			{
				yield return wait;
				if (!Plugin.SpawnAmmoPilesAtCampfire)
				{
					break;
				}
				if (!((Object)(object)Plugin.AmmoPilePrefab == (Object)null) && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && !LoadingScreenHandler.loading && MapHandler.ExistsAndInitialized)
				{
					Campfire val = null;
					try
					{
						val = MapHandler.CurrentCampfire;
					}
					catch (Exception)
					{
					}
					if (!((Object)(object)val == (Object)null))
					{
						TrySpawnAround(val);
						break;
					}
				}
			}
		}

		internal static void TrySpawnAround(Campfire campfire)
		{
			if (Plugin.SpawnAmmoPilesAtCampfire && !((Object)(object)campfire == (Object)null) && (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) && !IsPortableOrWings(campfire))
			{
				int num = CampfireKey(campfire);
				if (SpawnedKeys.Add(num))
				{
					_ = ((Behaviour)campfire).isActiveAndEnabled;
					((MonoBehaviour)campfire).StartCoroutine(SpawnWhenReady(campfire, num));
				}
			}
		}

		private static IEnumerator SpawnWhenReady(Campfire campfire, int key)
		{
			WaitForSecondsRealtime wait = new WaitForSecondsRealtime(0.25f);
			for (int i = 0; i < 40; i++)
			{
				if (!Plugin.SpawnAmmoPilesAtCampfire || (Object)(object)campfire == (Object)null)
				{
					SpawnedKeys.Remove(key);
					yield break;
				}
				if ((Object)(object)Plugin.AmmoPilePrefab == (Object)null || (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient))
				{
					yield return wait;
					continue;
				}
				if (PhotonNetwork.InRoom && (PhotonNetwork.CurrentRoom == null || LoadingScreenHandler.loading))
				{
					yield return wait;
					continue;
				}
				if (!((Behaviour)campfire).isActiveAndEnabled)
				{
					yield return wait;
					continue;
				}
				SpawnPiles(campfire, Plugin.AmmoPilesPerCampfire);
				yield break;
			}
			SpawnedKeys.Remove(key);
			Plugin.Log.LogWarning((object)$"Timed out waiting to spawn campfire ammo piles ({campfire?.advanceToSegment}).");
		}

		private static void SpawnPiles(Campfire campfire, int count)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			GameObject ammoPilePrefab = Plugin.AmmoPilePrefab;
			if ((Object)(object)ammoPilePrefab == (Object)null || count < 1)
			{
				return;
			}
			Vector3 position = ((Component)campfire).transform.position;
			int num = 0;
			for (int i = 0; i < count; i++)
			{
				float num2 = 360f / (float)Mathf.Max(count, 1) * (float)i + 35f;
				Vector3 val = Quaternion.Euler(0f, num2, 0f) * (Vector3.forward * 2.4f);
				Vector3 val2 = GroundPoint(position + val);
				Quaternion val3 = Quaternion.Euler(0f, num2 + 180f, 0f);
				try
				{
					if (PhotonNetwork.InRoom)
					{
						PhotonNetwork.InstantiateItemRoom(((Object)ammoPilePrefab).name, val2, val3, false);
					}
					else
					{
						Object.Instantiate<GameObject>(ammoPilePrefab, val2, val3).SetActive(true);
					}
					num++;
					Plugin.Log.LogInfo((object)$"Ammo pile spawn point {val2} (campfire {position}, segment {campfire.advanceToSegment}).");
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Could not spawn an ammo pile at a campfire: " + ex.Message));
				}
			}
			if (num > 0)
			{
				Plugin.Log.LogInfo((object)$"Spawned {num} ammo pile(s) at campfire ({campfire.advanceToSegment}).");
			}
		}

		private static Vector3 GroundPoint(Vector3 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0046: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = point + Vector3.up * 30f;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, Vector3.down, ref val2, 80f, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val2)).point + Vector3.up * 0.08f;
			}
			if (Physics.Raycast(val, Vector3.down, ref val2, 80f, -5, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val2)).point + Vector3.up * 0.08f;
			}
			return point;
		}

		private static int CampfireKey(Campfire campfire)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected I4, but got Unknown
			PhotonView component = ((Component)campfire).GetComponent<PhotonView>();
			if (!((Object)(object)component != (Object)null) || component.ViewID <= 0)
			{
				return (campfire.advanceToSegment * 1000003) ^ ((Object)campfire).GetInstanceID();
			}
			return component.ViewID;
		}

		private static bool IsPortableOrWings(Campfire campfire)
		{
			if (campfire.nameOverride == "NAME_PORTABLE STOVE")
			{
				return true;
			}
			Transform parent = ((Component)campfire).transform.parent;
			if ((Object)(object)parent != (Object)null)
			{
				return ((Object)((Component)parent).gameObject).name.ToLowerInvariant().Contains("wings");
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(MapHandler), "SpawnCampfireItems")]
	internal static class SpawnCampfireItemsAmmoPatch
	{
		[HarmonyPostfix]
		private static void Postfix(GameObject campfireRoot)
		{
			CampfireAmmoSpawner.TrySpawnAtRoot(campfireRoot);
		}
	}
	internal static class GameCompat
	{
		internal const string ZombieTypeName = "MushroomZombie";

		internal const string SyncMobStateRpc = "RPC_SyncMobState";

		private const BindingFlags AnyInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		internal static void PatchAll(Harmony harmony)
		{
			int num = 0;
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				if (!type.IsDefined(typeof(HarmonyPatch), inherit: true))
				{
					continue;
				}
				try
				{
					List<MethodInfo> list3 = harmony.CreateClassProcessor(type).Patch();
					if (list3 != null && list3.Count > 0)
					{
						num++;
					}
					else
					{
						list.Add(type.Name);
					}
				}
				catch (Exception e)
				{
					list2.Add(type.Name);
					Plugin.Log.LogWarning((object)("Patch " + type.Name + " was not applied, so that feature is off: " + Unwrap(e).Message));
				}
			}
			string text = $"Harmony patches: {num} applied";
			if (list.Count > 0)
			{
				text += string.Format(", {0} skipped ({1})", list.Count, string.Join(", ", list));
			}
			if (list2.Count > 0)
			{
				text += string.Format(", {0} failed ({1}). A PEAK update may have changed the game", list2.Count, string.Join(", ", list2));
				Plugin.Log.LogWarning((object)(text + "."));
			}
			else
			{
				Plugin.Log.LogInfo((object)(text + "."));
			}
		}

		internal static void CheckNamedMembers()
		{
			List<string> list = new List<string>();
			Type type = FindType("MushroomZombie");
			if (type == null)
			{
				list.Add("MushroomZombie (zombie knockdown)");
			}
			else if (type.GetMethod("RPC_PlaySFX", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null)
			{
				list.Add("MushroomZombie.RPC_PlaySFX (knocked-down zombie silence)");
			}
			Type typeFromHandle = typeof(Mob);
			if (!(typeFromHandle.GetProperty("mobState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null))
			{
				Type nestedType = typeFromHandle.GetNestedType("MobState", BindingFlags.Public | BindingFlags.NonPublic);
				if ((object)nestedType != null && Enum.IsDefined(nestedType, "Dead"))
				{
					goto IL_0090;
				}
			}
			list.Add("Mob.mobState / MobState.Dead (killing beetles and scorpions offline or as owner)");
			goto IL_0090;
			IL_0090:
			if (typeFromHandle.GetMethod("RPC_SyncMobState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null)
			{
				list.Add("Mob.RPC_SyncMobState (killing beetles and scorpions owned by others)");
			}
			if (AccessTools.Method(typeof(CharacterItems), "GetItemHoldRotation", (Type[])null, (Type[])null) == null)
			{
				list.Add("CharacterItems.GetItemHoldRotation (shotgun draw can settle centred with crossed arms)");
			}
			if (AccessTools.Field(typeof(ItemCooking), "disableCooking") == null)
			{
				list.Add("ItemCooking.disableCooking (ammo piles could be cooked)");
			}
			if (list.Count > 0)
			{
				Plugin.Log.LogWarning((object)("These PEAK names were not found; a game update may have changed them: " + string.Join("; ", list) + "."));
			}
		}

		internal static bool IsGameMismatch(Exception e)
		{
			Exception ex = Unwrap(e);
			if (ex is MissingMemberException || ex is TypeLoadException || ex is BadImageFormatException)
			{
				return true;
			}
			return false;
		}

		internal static Type? FindType(string name)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type type = assembly.GetType(name);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		private static Exception Unwrap(Exception e)
		{
			while (true)
			{
				bool flag = ((e is TargetInvocationException || e is TypeInitializationException || e is HarmonyException) ? true : false);
				if (!flag || e.InnerException == null)
				{
					break;
				}
				e = e.InnerException;
			}
			return e;
		}
	}
	public class GunCharacterLaunch : MonoBehaviourPunCallbacks
	{
		private static readonly Type? ZombieType = GameCompat.FindType("MushroomZombie");

		private const float BlastRagdollSeconds = 3f;

		private const float ShoveAcceleration = 36f;

		private const float ShoveSeconds = 0.3f;

		private const float ZombieDrowsyDamage = 0.5f;

		private int shotgunHits;

		private bool heldDown;

		private float shoveTime;

		private Vector3 shoveDirection;

		internal bool Silenced { get; private set; }

		public static bool IsZombie(Character character)
		{
			if (ZombieType != null)
			{
				return (Object)(object)((Component)character).GetComponent(ZombieType) != (Object)null;
			}
			return false;
		}

		[PunRPC]
		public void RPC_ShotgunBlast(Vector3 direction, Vector3 point, int gunViewId, int shotId, PhotonMessageInfo info)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			Character component = ((Component)this).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine || !IsZombie(component) || !ShootableRules.Zombies.Enabled)
			{
				return;
			}
			PhotonView val = PhotonView.Find(gunViewId);
			Action_Gun gun = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Action_Gun>() : null);
			if (!((Object)(object)gun == (Object)null))
			{
				int viewID = ((MonoBehaviourPun)component).photonView.ViewID;
				Player shooter = info.Sender;
				if (gun.TryConsumeOrDeferHit(shooter, shotId, viewID, delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					Blast(direction, point, gun, shooter);
				}))
				{
					Blast(direction, point, gun, shooter);
				}
			}
		}

		public void Blast(Vector3 direction, Vector3 point, Action_Gun? gun = null, Player? shooter = null)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			Character component = ((Component)this).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine || component.data.dead)
			{
				return;
			}
			Vector3 val = ((Vector3)(ref direction)).normalized + Vector3.up * 0.45f;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			component.Fall(3f, 0f);
			shoveDirection = normalized;
			shoveTime = 0.3f;
			if (!IsZombie(component))
			{
				return;
			}
			shotgunHits++;
			if (shotgunHits >= ShootableRules.Zombies.HitsToDefeat)
			{
				if (!heldDown)
				{
					ShotgunHitMarker.ConfirmDefeat(gun, shooter, ((MonoBehaviourPun)component).photonView.ViewID);
				}
				KnockDown(component);
			}
			else
			{
				BroadcastShotState();
				component.refs.afflictions.AddAffliction((Affliction)new Affliction_AdjustStatus((STATUSTYPE)6, 0.5f, 1f), false);
			}
		}

		private void FixedUpdate()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!(shoveTime <= 0f))
			{
				Character component = ((Component)this).GetComponent<Character>();
				if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine)
				{
					shoveTime = 0f;
					return;
				}
				float fixedDeltaTime = Time.fixedDeltaTime;
				float num = Mathf.Min(shoveTime, fixedDeltaTime) / fixedDeltaTime;
				shoveTime -= fixedDeltaTime;
				component.AddForce(shoveDirection * (36f * num), 1f, 1f);
			}
		}

		private void LateUpdate()
		{
			if (!heldDown)
			{
				return;
			}
			Character component = ((Component)this).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null) && ((MonoBehaviourPun)component).photonView.IsMine)
			{
				if (component.data.dead)
				{
					heldDown = false;
					BroadcastShotState();
				}
				else
				{
					HoldDown(component);
				}
			}
		}

		private void KnockDown(Character character)
		{
			heldDown = true;
			character.PassOutInstantly();
			HoldDown(character);
			Silence();
			BroadcastShotState();
		}

		private void BroadcastShotState()
		{
			if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)this).photonView != (Object)null)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_ZombieShotState", (RpcTarget)1, new object[2] { shotgunHits, heldDown });
			}
		}

		[PunRPC]
		public void RPC_ZombieShotState(int hits, bool down, PhotonMessageInfo info)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (info.Sender != null && info.Sender == ((MonoBehaviourPun)this).photonView.Owner)
			{
				shotgunHits = hits;
				heldDown = down;
				if (down)
				{
					Silence();
				}
			}
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine && (shotgunHits > 0 || heldDown))
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_ZombieShotState", newPlayer, new object[2] { shotgunHits, heldDown });
			}
		}

		private void Silence()
		{
			if (!Silenced)
			{
				Silenced = true;
				AudioSource[] componentsInChildren = ((Component)this).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val in componentsInChildren)
				{
					val.Stop();
					val.mute = true;
				}
			}
		}

		private static void HoldDown(Character character)
		{
			character.refs.afflictions.SetStatus((STATUSTYPE)6, 1f, false);
			character.data.passedOut = true;
			character.data.fullyPassedOut = true;
			if (character.data.fallSeconds < 1f)
			{
				character.data.fallSeconds = 5f;
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class GunPatch
	{
		[HarmonyPostfix]
		private static void AddLaunch(Character __instance)
		{
			((Component)__instance).gameObject.AddComponent<GunCharacterLaunch>();
		}
	}
	internal sealed class HostConfigSync : MonoBehaviour, IInRoomCallbacks, IMatchmakingCallbacks
	{
		internal const string RoomShotsKey = "PeakShotgun_Shots";

		internal const string RoomShootablesKey = "PeakShotgun_Shootables";

		internal const string RoomHitsToDefeatKey = "PeakShotgun_HitsToDefeat";

		internal const string RoomWorldDownKey = "PeakShotgun_WorldDown";

		private static int? hostShots;

		private static ShootTargets? hostShootables;

		private static HitsToDefeatSettings? hostHitsToDefeat;

		internal static int ShotCount
		{
			get
			{
				if (hostShots.HasValue)
				{
					return Mathf.Max(1, hostShots.Value);
				}
				return Plugin.LocalConfiguredShots;
			}
		}

		internal static ShootTargets Shootables => hostShootables ?? ShootableRules.LocalShootables;

		internal static HitsToDefeatSettings HitsToDefeat => hostHitsToDefeat ?? HitsToDefeatSettings.Local;

		private void OnEnable()
		{
			PhotonNetwork.AddCallbackTarget((object)this);
		}

		private void OnDisable()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		internal static void SyncFromLocalRole(string reason)
		{
			if (!PhotonNetwork.InRoom)
			{
				hostShots = Plugin.LocalConfiguredShots;
				hostShootables = null;
				hostHitsToDefeat = null;
				ShotgunCombat.ClearWorldHitCounts();
				Plugin.ApplyShotCountConfig();
				Plugin.Log.LogInfo((object)$"Shots (offline/local) = {ShotCount} ({reason}).");
			}
			else if (PhotonNetwork.IsMasterClient)
			{
				PublishHostSettings(reason);
			}
			else if (!TryApplyRoomSettings())
			{
				Plugin.Log.LogInfo((object)("Waiting for host shotgun room settings (" + reason + ")."));
			}
		}

		private static void PublishHostSettings(string reason)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_0088: Expected O, but got Unknown
			int localConfiguredShots = Plugin.LocalConfiguredShots;
			ShootTargets localShootables = ShootableRules.LocalShootables;
			HitsToDefeatSettings local = HitsToDefeatSettings.Local;
			hostShots = localConfiguredShots;
			hostShootables = localShootables;
			hostHitsToDefeat = local;
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Hashtable val = new Hashtable();
			((Dictionary<object, object>)val).Add((object)"PeakShotgun_Shots", (object)localConfiguredShots);
			((Dictionary<object, object>)val).Add((object)"PeakShotgun_Shootables", (object)(int)localShootables);
			((Dictionary<object, object>)val).Add((object)"PeakShotgun_HitsToDefeat", (object)local.ToPacked());
			((Dictionary<object, object>)val).Add((object)"PeakShotgun_WorldDown", (object)ShotgunCombat.PackWorldDefeats());
			currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			Plugin.ApplyShotCountConfig();
			Plugin.Log.LogInfo((object)$"Host published Shots = {localConfiguredShots}, Shootables = {localShootables}, HitsToDefeat = {local} ({reason}).");
		}

		private static bool TryApplyRoomSettings()
		{
			Room currentRoom = PhotonNetwork.CurrentRoom;
			if (((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null) == null)
			{
				return false;
			}
			Hashtable customProperties = ((RoomInfo)currentRoom).CustomProperties;
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_Shootables", out object value) && value is int num && hostShootables != (ShootTargets?)num)
			{
				hostShootables = (ShootTargets)num;
				Plugin.Log.LogInfo((object)$"Client applied host Shootables = {hostShootables}.");
			}
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_HitsToDefeat", out object value2) && value2 is byte[] packed)
			{
				HitsToDefeatSettings hitsToDefeatSettings = HitsToDefeatSettings.FromPacked(packed);
				if (!hostHitsToDefeat.HasValue || !hostHitsToDefeat.Value.Equals(hitsToDefeatSettings))
				{
					hostHitsToDefeat = hitsToDefeatSettings;
					Plugin.Log.LogInfo((object)$"Client applied host HitsToDefeat = {hitsToDefeatSettings}.");
				}
			}
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_WorldDown", out object value3) && value3 is int[] packed2)
			{
				ShotgunCombat.ApplyPackedWorldDefeats(packed2);
			}
			if (!((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_Shots", out object value4) || !(value4 is int num2))
			{
				return false;
			}
			int num3 = Mathf.Max(1, num2);
			if (hostShots == num3)
			{
				return true;
			}
			hostShots = num3;
			Plugin.ApplyShotCountConfig();
			Plugin.Log.LogInfo((object)$"Client applied host Shots = {num3}.");
			return true;
		}

		internal static void PublishWorldDefeats()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0030: Expected O, but got Unknown
			if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"PeakShotgun_WorldDown", (object)ShotgunCombat.PackWorldDefeats());
				currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			}
		}

		private static void ClearHostSettings()
		{
			hostShots = null;
			hostShootables = null;
			hostHitsToDefeat = null;
			ShotgunCombat.ClearWorldHitCounts();
		}

		public void OnJoinedRoom()
		{
			SyncFromLocalRole("joined room");
		}

		public void OnLeftRoom()
		{
			ClearHostSettings();
		}

		public void OnMasterClientSwitched(Player newMasterClient)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				PublishHostSettings("became host");
				ShotgunLootLedger.OnBecameHost();
			}
		}

		public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			if (propertiesThatChanged != null)
			{
				ShotgunLootLedger.OnRoomPropertiesUpdate(propertiesThatChanged);
				if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_Shots") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_Shootables") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_HitsToDefeat") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_WorldDown"))
				{
					TryApplyRoomSettings();
				}
			}
		}

		public void OnPlayerEnteredRoom(Player newPlayer)
		{
		}

		public void OnPlayerLeftRoom(Player otherPlayer)
		{
		}

		public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
		}

		public void OnFriendListUpdate(List<FriendInfo> friendList)
		{
		}

		public void OnCreatedRoom()
		{
		}

		public void OnCreateRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRandomFailed(short returnCode, string message)
		{
		}
	}
	[HarmonyPatch(typeof(Luggage), "OffsetSpawn")]
	internal static class LuggageShotgunOffsetPatch
	{
		internal static Vector3 LuggageRestPosition => new Vector3(Plugin.RestPosX, Plugin.RestPosY, Plugin.RestPosZ);

		[HarmonyPostfix]
		private static void SitFlatOnFloor(Luggage __instance, Item item)
		{
			//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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)item == (Object)null || !item.offsetLuggageSpawn || __instance is RespawnChest || (Object)(object)((Component)item).GetComponent<ShotgunInstanceSetup>() == (Object)null)
			{
				return;
			}
			Transform val = item.transform.Find("ShotgunVisual");
			MeshFilter val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshFilter>() : null);
			Mesh val3 = (((Object)(object)val2 != (Object)null) ? val2.sharedMesh : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val3 == (Object)null)
			{
				return;
			}
			Vector3 up = ((Component)__instance).transform.up;
			Renderer mainRenderer = item.mainRenderer;
			Vector3 val4;
			if (!((Object)(object)mainRenderer != (Object)null))
			{
				val4 = item.transform.position - ((Component)__instance).transform.rotation * item.offsetLuggagePosition;
			}
			else
			{
				Bounds bounds = mainRenderer.bounds;
				val4 = ((Bounds)(ref bounds)).center - ((Component)__instance).transform.rotation * item.offsetLuggagePosition;
			}
			Vector3 val5 = val4;
			float num = Vector3.Dot(val5, up);
			Transform transform = item.transform;
			transform.position -= ((Component)__instance).transform.rotation * item.offsetLuggagePosition;
			Quaternion val6 = Plugin.LuggageVisualRotation(item.transform, up);
			Vector3 val7 = (val.localPosition = LuggageRestPosition);
			val.localRotation = val6;
			float num2 = MinMeshAlongUp(val, val3, up);
			float num3 = num - num2 + Plugin.LuggageLiftExtra;
			Transform transform2 = item.transform;
			transform2.position += up * num3;
			Rigidbody component = ((Component)item).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				if (!component.isKinematic)
				{
					component.angularVelocity = Vector3.zero;
					component.linearVelocity = Vector3.zero;
				}
				component.useGravity = false;
				component.isKinematic = true;
				component.constraints = (RigidbodyConstraints)126;
			}
			GetOrAddRest(item).Arm(val7, val6);
			ShotgunLootLedger.SavePose(__instance, val7, val6);
			item.ForceSyncForFrames(10);
			Plugin.Log.LogInfo((object)$"Luggage seat yaw={Plugin.LuggageYaw:0.#}° Δ={num3:0.###} (spawn-spot, liftExtra={Plugin.LuggageLiftExtra:0.###}).");
		}

		internal static ShotgunLuggageRest GetOrAddRest(Item item)
		{
			return ((Component)item).GetComponent<ShotgunLuggageRest>() ?? ((Component)item).gameObject.AddComponent<ShotgunLuggageRest>();
		}

		private static float MinMeshAlongUp(Transform visual, Mesh mesh, Vector3 up)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] vertices = mesh.vertices;
			Matrix4x4 localToWorldMatrix = visual.localToWorldMatrix;
			float num = float.PositiveInfinity;
			for (int i = 0; i < vertices.Length; i++)
			{
				Vector3 val = ((Matrix4x4)(ref localToWorldMatrix)).MultiplyPoint3x4(vertices[i]);
				num = Mathf.Min(num, Vector3.Dot(val, up));
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(Spawner), "InitializePhysics")]
	internal static class LuggageShotgunSyncPatch
	{
		private const float RestoreSlack = 0.5f;

		[HarmonyPostfix]
		private static void SyncLuggageRest(Spawner __instance, Item newItem)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			Luggage val = (Luggage)(object)((__instance is Luggage) ? __instance : null);
			if (val == null || val is RespawnChest || (Object)(object)newItem == (Object)null || !newItem.offsetLuggageSpawn || (Object)(object)((Component)newItem).GetComponent<ShotgunInstanceSetup>() == (Object)null)
			{
				return;
			}
			ShotgunLuggageRest orAddRest = LuggageShotgunOffsetPatch.GetOrAddRest(newItem);
			if (!orAddRest.Armed)
			{
				if (!IsInside(val, newItem))
				{
					return;
				}
				Vector3 position;
				Quaternion rotation;
				bool flag = ShotgunLootLedger.TryGetPose(val, out position, out rotation);
				if (!flag)
				{
					position = LuggageShotgunOffsetPatch.LuggageRestPosition;
					rotation = Plugin.LuggageVisualRotation(newItem.transform, ((Component)val).transform.up);
				}
				orAddRest.Arm(position, rotation);
				ShotgunLootLedger.NoteRestored(val, RootsLuggagePatch.LuggageBiomeKey((Spawner)(object)val, ((Spawner)val).spawnPool));
				Plugin.Log.LogInfo((object)("Restored luggage seat for a saved shotgun in '" + ((Object)val).name + "' (" + (flag ? "saved pose" : "current config") + ")."));
			}
			orAddRest.Broadcast();
		}

		private static bool IsInside(Luggage luggage, Item item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Bounds totalBounds = HelperFunctions.GetTotalBounds((IEnumerable<Renderer>)luggage.meshRenderers);
			((Bounds)(ref totalBounds)).Expand(0.5f);
			return ((Bounds)(ref totalBounds)).Contains(item.transform.position);
		}
	}
	internal static class ObjMeshLoader
	{
		internal static Mesh? Load(Stream stream, string meshName)
		{
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Expected O, but got Unknown
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<Vector3> list3 = new List<Vector3>();
			List<Vector3> list4 = new List<Vector3>();
			List<Vector2> list5 = new List<Vector2>();
			List<Vector3> outNormals = new List<Vector3>();
			List<int> list6 = new List<int>();
			Dictionary<(int, int, int), int> vertexKey = new Dictionary<(int, int, int), int>();
			using StreamReader streamReader = new StreamReader(stream);
			string text;
			while ((text = streamReader.ReadLine()) != null)
			{
				if (text.Length == 0 || text[0] == '#')
				{
					continue;
				}
				string[] array = text.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
				if (array.Length == 0)
				{
					continue;
				}
				switch (array[0])
				{
				case "v":
					if (array.Length >= 4)
					{
						list.Add(new Vector3(0f - Parse(array[1]), Parse(array[2]), Parse(array[3])));
					}
					break;
				case "vt":
					if (array.Length >= 3)
					{
						list2.Add(new Vector2(Parse(array[1]), Parse(array[2])));
					}
					break;
				case "vn":
					if (array.Length >= 4)
					{
						list3.Add(new Vector3(0f - Parse(array[1]), Parse(array[2]), Parse(array[3])));
					}
					break;
				case "f":
					if (array.Length >= 4)
					{
						int item = AddFaceVertex(array[1], list, list2, list3, list4, list5, outNormals, vertexKey);
						int item2 = AddFaceVertex(array[2], list, list2, list3, list4, list5, outNormals, vertexKey);
						for (int i = 3; i < array.Length; i++)
						{
							int num = AddFaceVertex(array[i], list, list2, list3, list4, list5, outNormals, vertexKey);
							list6.Add(item);
							list6.Add(num);
							list6.Add(item2);
							item2 = num;
						}
					}
					break;
				}
			}
			if (list4.Count == 0 || list6.Count == 0)
			{
				return null;
			}
			Vector3 val = list4[0];
			Vector3 val2 = list4[0];
			for (int j = 1; j < list4.Count; j++)
			{
				Vector3 val3 = list4[j];
				val = Vector3.Min(val, val3);
				val2 = Vector3.Max(val2, val3);
			}
			Vector3 val4 = (val + val2) * 0.5f;
			float num2 = 0f;
			for (int k = 0; k < list4.Count; k++)
			{
				Vector3 val5 = (list4[k] -= val4);
				num2 = Mathf.Max(new float[4]
				{
					num2,
					Mathf.Abs(val5.x),
					Mathf.Abs(val5.y),
					Mathf.Abs(val5.z)
				});
			}
			if (num2 > 0.0001f)
			{
				float num3 = 1f / num2;
				for (int l = 0; l < list4.Count; l++)
				{
					List<Vector3> list7 = list4;
					int index = l;
					list7[index] *= num3;
				}
			}
			Mesh val7 = new Mesh
			{
				name = meshName
			};
			if (list4.Count > 65535)
			{
				val7.indexFormat = (IndexFormat)1;
			}
			val7.SetVertices(list4);
			if (list5.Count == list4.Count)
			{
				val7.SetUVs(0, list5);
			}
			val7.SetTriangles(list6, 0);
			val7.RecalculateNormals();
			val7.RecalculateBounds();
			val7.RecalculateTangents();
			return val7;
		}

		private static int AddFaceVertex(string token, List<Vector3> positions, List<Vector2> uvs, List<Vector3> normals, List<Vector3> outPositions, List<Vector2> outUvs, List<Vector3> outNormals, Dictionary<(int, int, int), int> vertexKey)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			string[] array = token.Split('/');
			int num = ParseIndex(array[0], positions.Count);
			int num2 = ((array.Length > 1 && array[1].Length > 0) ? ParseIndex(array[1], uvs.Count) : (-1));
			int num3 = ((array.Length > 2 && array[2].Length > 0) ? ParseIndex(array[2], normals.Count) : (-1));
			(int, int, int) key = (num, num2, num3);
			if (vertexKey.TryGetValue(key, out var value))
			{
				return value;
			}
			int count = outPositions.Count;
			outPositions.Add(positions[num]);
			outUvs.Add((num2 >= 0) ? uvs[num2] : Vector2.zero);
			outNormals.Add((num3 >= 0) ? normals[num3] : Vector3.up);
			vertexKey[key] = count;
			return count;
		}

		private static int ParseIndex(string raw, int count)
		{
			int num = int.Parse(raw, CultureInfo.InvariantCulture);
			if (num >= 0)
			{
				return num - 1;
			}
			return count + num;
		}

		private static float Parse(string raw)
		{
			return float.Parse(raw, CultureInfo.InvariantCulture);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("PeakShotgun", "PeakShotgun", "1.0.25")]
	public class Plugin : BaseUnityPlugin
	{
		private static ConfigEntry<int>? shots;

		private static ConfigEntry<bool>? recoilEnabled;

		private static ConfigEntry<float>? recoil;

		private static ConfigEntry<int>? carryWeight;

		internal const int DefaultCarryWeight = 4;

		internal const int MaxCarryWeight = 20;

		private static ConfigEntry<bool>? debugMode;

		private static ConfigEntry<bool>? canSpawnOnAnyBiome;

		private static ConfigEntry<bool>? giveShotgunOnSpawn;

		private static ConfigEntry<bool>? spawnAmmoPilesAtCampfire;

		private static ConfigEntry<int>? ammoPilesPerCampfire;

		internal const float AmmoPileScale = 0.425f;

		internal const int GuaranteedLuggageShotguns = 2;

		internal const int MaxShotgunsPerBiome = 4;

		internal static readonly SpawnPool AllLuggagePools = (SpawnPool)1963064320;

		private static ConfigEntry<bool>? hitMarkers;

		private static ConfigEntry<bool>? tracers;

		private static ConfigEntry<bool>? impactEffects;

		private static ConfigEntry<float>? poseRight;

		private static ConfigEntry<float>? poseUp;

		private static ConfigEntry<float>? poseForward;

		private static ConfigEntry<float>? poseLeftHandIn;

		private static ConfigEntry<float>? poseLeftHandUp;

		private static ConfigEntry<float>? poseRightWristDown;

		private static ConfigEntry<float>? poseToeIn;

		private static ConfigEntry<float>? poseMuzzleUp;

		private DateTime lastConfigWriteUtc;

		private float nextConfigCheck;

		internal static readonly Quaternion HeldBaseRotation = Quaternion.Inverse(Quaternion.LookRotation(Vector3.left, Vector3.forward));

		private bool reportedMissingBlowgun;

		private static readonly HashSet<string> reportedGuardFailures = new HashSet<string>();

		private Coroutine? shoreSpawnRoutine;

		private Coroutine? campfireAmmoRoutine;

		private bool buildingShotgun;

		private bool buildingAmmoPile;

		public const string Id = "PeakShotgun";

		internal static ManualLogSource Log { get; private set; } = null;

		internal static Plugin Instance { get; private set; } = null;

		internal static GameObject? ShotgunPrefab { get; private set; }

		internal static GameObject? AmmoPilePrefab { get; private set; }

		internal static int LocalConfiguredShots => Mathf.Max(1, shots?.Value ?? 6);

		internal static int ShotCount => HostConfigSync.ShotCount;

		internal static float ModelScale { get; private set; } = 0.015f;

		internal static float Recoil
		{
			get
			{
				ConfigEntry<bool>? obj = recoilEnabled;
				if (obj != null && !obj.Value)
				{
					return 0f;
				}
				return recoil?.Value ?? 5f;
			}
		}

		internal static int CarryWeight => Mathf.Clamp(carryWeight?.Value ?? 4, 0, 20);

		internal static bool DebugMode => debugMode?.Value ?? false;

		internal static bool CanSpawnOnAnyBiome
		{
			get
			{
				ConfigEntry<bool>? obj = canSpawnOnAnyBiome;
				if (obj != null && !obj.Value)
				{
					return !ShootableRules.IsZombiesOnly;
				}
				return true;
			}
		}

		internal static bool GiveShotgunOnSpawn => giveShotgunOnSpawn?.Value ?? false;

		internal static bool SpawnAmmoPilesAtCampfire => spawnAmmoPilesAtCampfire?.Value ?? true;

		internal static int AmmoPilesPerCampfire => Mathf.Clamp(ammoPilesPerCampfire?.Value ?? 1, 1, 8);

		internal static SpawnPool ShotgunLuggagePools
		{
			get
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (!CanSpawnOnAnyBiome)
				{
					return (SpawnPool)67108864;
				}
				return AllLuggagePools;
			}
		}

		internal static bool HitMarkers => hitMarkers?.Value ?? true;

		internal static bool Tracers => tracers?.Value ?? true;

		internal static bool ImpactEffects => impactEffects?.Value ?? true;

		internal static float LeftHandIn => poseLeftHandIn?.Value ?? 0.01f;

		internal static float LeftHandUp => poseLeftHandUp?.Value ?? 0.04f;

		internal static float RightWristDown => poseRightWristDown?.Value ?? 45f;

		internal static Vector3 HeldDefaultPos => new Vector3(poseRight?.Value ?? 0.55f, poseUp?.Value ?? (-0.65f), poseForward?.Value ?? 1.6f);

		internal static float HeldToeIn => poseToeIn?.Value ?? (-6f);

		internal static float HeldMuzzleUp => poseMuzzleUp?.Value ?? 0f;

		internal static int PoseVersion { get; private set; }

		internal static float ModelRotX { get; private set; }

		internal static float ModelRotY { get; private set; }

		internal static float ModelRotZ { get; private set; }

		internal static float RestPosX { get; private set; }

		internal static float RestPosY { get; private set; }

		internal static float RestPosZ { get; private set; }

		internal static float RestRotX { get; private set; }

		internal static float RestRotY { get; private set; }

		internal static float RestRotZ { get; private set; }

		internal static float LuggageYaw { get; private set; }

		internal static float RestMeshLift { get; private set; }

		internal static float LuggageLiftExtra { get; private set; }

		internal static Vector3 GripMeshPoint { get; private set; }

		internal static Vector3 ForendMeshPoint { get; private set; }

		internal static Quaternion HeldAim => Quaternion.Euler(ModelRotX - HeldMuzzleUp, ModelRotY - HeldToeIn, ModelRotZ);

		internal static Quaternion HeldLocalRotation => HeldAim * HeldBaseRotation;

		internal static Vector3 HeldLocalPosition => -(HeldLocalRotation * (GripMeshPoint * ModelScale));

		internal static Vector3 RestLocalPosition => new Vector3(RestPosX, RestPosY + RestMeshLift, RestPosZ);

		internal static Quaternion RestLocalRotation => Quaternion.Euler(RestRotX, RestRotY, RestRotZ);

		internal static Vector3 MuzzleMeshPoint { get; private set; }

		public static string Name => "PeakShotgun";

		public static string Version => "1.0.25";

		internal static void UpdateMeshAnchors(Mesh mesh)
		{
			//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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unkno