Decompiled source of Bazooka v1.0.2

plugins/PeakBazooka.dll

Decompiled a day 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 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 bazooka built from PEAK's AntiZooka that fires exploding rockets instead of antigravity bubbles.")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+622fd7e5f25f86c72c4803355cad40493175de80")]
[assembly: AssemblyProduct("PeakBazooka")]
[assembly: AssemblyTitle("PeakBazooka")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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.Bazooka
{
	public class Action_Ammo : ItemAction
	{
		internal bool TrySpendOne()
		{
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			if (Plugin.InfiniteShots)
			{
				ApplyInfinite();
				return true;
			}
			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);
			return true;
		}

		internal bool HasAmmo()
		{
			if (Plugin.InfiniteShots || ((ItemActionBase)this).item.totalUses <= 0)
			{
				return true;
			}
			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;
		}

		internal void EnsureHostMagazine()
		{
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				return;
			}
			if (Plugin.InfiniteShots)
			{
				ApplyInfinite();
				return;
			}
			int shotCount = Plugin.ShotCount;
			((ItemActionBase)this).item.totalUses = shotCount;
			((ItemActionBase)this).item.UIData.hideFuel = false;
			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 void ApplyInfinite()
		{
			((ItemActionBase)this).item.totalUses = -1;
			((ItemActionBase)this).item.UIData.hideFuel = true;
			OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			data.HasData = false;
			data.Value = -1;
			((ItemActionBase)this).item.SetUseRemainingPercentage(1f);
			BazookaAmmoUI.Refresh();
		}

		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)
		{
			if (capacity <= 0)
			{
				ApplyInfinite();
				return;
			}
			((ItemActionBase)this).item.totalUses = Mathf.Max(1, capacity);
			((ItemActionBase)this).item.UIData.hideFuel = false;
			OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			data.HasData = true;
			data.Value = Mathf.Max(0, remaining);
			((ItemActionBase)this).item.SetUseRemainingPercentage((float)data.Value / (float)((ItemActionBase)this).item.totalUses);
			SyncHolderSlotUses(data.Value);
			BazookaAmmoUI.Refresh();
		}

		private void SyncHolderSlotUses(int remaining)
		{
			//IL_0098: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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;
				}
				else
				{
					val2.data.RegisterEntry<OptionableIntItemData>((DataEntryKey)2, new OptionableIntItemData
					{
						HasData = true,
						Value = remaining
					});
				}
			}
		}

		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
	{
		public float fireRate = 0.8f;

		public Transform? spawnTransform;

		public Action? OnShoot;

		private const float PendingShotRetry = 1.5f;

		private const float HostFireRateTolerance = 0.9f;

		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 Coroutine? recoilRoutine;

		private Vector3 HoldPosition
		{
			get
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				Item val = (((Object)(object)Plugin.BazookaPrefab != (Object)null) ? Plugin.BazookaPrefab.GetComponent<Item>() : null);
				if (!((Object)(object)val != (Object)null))
				{
					return ((ItemActionBase)this).item.defaultPos;
				}
				return val.defaultPos;
			}
		}

		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_009c: 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)
			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))
			{
				Action_Ammo component = ((Component)this).GetComponent<Action_Ammo>();
				if (!((Object)(object)component != (Object)null) || component.HasAmmo())
				{
					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)
				{
					ShotLedger.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 void Fire(int shotId, Vector3 forward)
		{
			//IL_0067: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			BazookaShooter bazookaShooter = (((Object)(object)((ItemActionBase)this).character != (Object)null) ? ((Component)((ItemActionBase)this).character).GetComponent<BazookaShooter>() : null);
			if (!((Object)(object)spawnTransform == (Object)null) && !((Object)(object)((ItemActionBase)this).character == (Object)null) && ((ItemActionBase)this).character.IsLocal && !((Object)(object)bazookaShooter == (Object)null))
			{
				OnShoot?.Invoke();
				Vector3 position = spawnTransform.position;
				if (Plugin.Recoil > 0f && !Plugin.RocketJumpMode)
				{
					((ItemActionBase)this).character.AddForce(-forward * (Plugin.Recoil / Time.fixedDeltaTime), 1f, 1f);
				}
				bazookaShooter.LaunchRocket(position, forward, shotId);
				PlayVanillaShootJuice();
			}
		}

		private void PlayVanillaShootJuice()
		{
			if (PhotonNetwork.InRoom)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPCA_Shoot", (RpcTarget)0, Array.Empty<object>());
				return;
			}
			Action_Antizooka component = ((Component)this).GetComponent<Action_Antizooka>();
			if ((Object)(object)component != (Object)null)
			{
				AccessTools.Method(typeof(Action_Antizooka), "RPCA_Shoot", (Type[])null, (Type[])null)?.Invoke(component, null);
			}
		}

		internal void PlayShotJuice(Action_Antizooka juice)
		{
			//IL_000b: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			GamefeelHandler.instance.AddPerlinShakeProximity(((Component)this).transform.position, juice.shakeAmount, 0.3f, 15f, 10f);
			if ((Object)(object)juice.sfx != (Object)null)
			{
				juice.sfx.Play(((ItemActionBase)this).item.transform.position);
			}
			if (recoilRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(recoilRoutine);
			}
			recoilRoutine = ((MonoBehaviour)this).StartCoroutine(Recoil(juice.recoilPos));
		}

		private IEnumerator Recoil(Vector3 kick)
		{
			//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)
			Vector3 hold = HoldPosition;
			float t = 0f;
			((ItemActionBase)this).item.defaultPos = hold + kick;
			while (t < 1f)
			{
				t += Time.deltaTime * 4f;
				((ItemActionBase)this).item.defaultPos = Vector3.Lerp(hold + kick, hold, t);
				yield return null;
			}
			((ItemActionBase)this).item.defaultPos = hold;
			recoilRoutine = null;
		}
	}
	[HarmonyPatch(typeof(Action_Antizooka), "PlayChargeFX")]
	internal static class AntizookaChargeStartPatch
	{
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(Action_Antizooka), "PlayChargeFX", (Type[])null, (Type[])null) != null;
		}

		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(Action_Antizooka), "StopChargeFX")]
	internal static class AntizookaChargeStopPatch
	{
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(Action_Antizooka), "StopChargeFX", (Type[])null, (Type[])null) != null;
		}

		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(Action_Antizooka), "RPCA_Shoot")]
	internal static class AntizookaShotJuicePatch
	{
		private static bool Prepare()
		{
			return AccessTools.Method(typeof(Action_Antizooka), "RPCA_Shoot", (Type[])null, (Type[])null) != null;
		}

		private static bool Prefix(Action_Antizooka __instance)
		{
			Action_Gun component = ((Component)__instance).GetComponent<Action_Gun>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			component.PlayShotJuice(__instance);
			return false;
		}
	}
	internal static class BazookaAmmoUI
	{
		internal static void Refresh()
		{
			if ((Object)(object)GUIManager.instance == (Object)null)
			{
				return;
			}
			if (GUIManager.instance.items != null)
			{
				InventoryItemUI[] items = GUIManager.instance.items;
				foreach (InventoryItemUI val in items)
				{
					if (val != null)
					{
						val.UpdateNameText();
					}
				}
			}
			InventoryItemUI temporaryItem = GUIManager.instance.temporaryItem;
			if (temporaryItem != null)
			{
				temporaryItem.UpdateNameText();
			}
			GUIManager.instance.UpdateItemPrompts();
		}

		internal static bool TryGetRemaining(Item item, ItemInstanceData? data, out int remaining)
		{
			remaining = 0;
			if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).GetComponent<Action_Gun>() == (Object)null || Plugin.InfiniteShots || item.totalUses <= 0)
			{
				return false;
			}
			OptionableIntItemData val = default(OptionableIntItemData);
			if (data != null && data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val) && val.HasData && val.Value >= 0)
			{
				remaining = val.Value;
				return true;
			}
			OptionableIntItemData data2 = item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (data2.HasData && data2.Value >= 0)
			{
				remaining = data2.Value;
				return true;
			}
			remaining = item.totalUses;
			return true;
		}
	}
	[HarmonyPatch(typeof(Item), "GetItemName")]
	internal static class BazookaNamePatch
	{
		[HarmonyPostfix]
		private static void AppendShots(Item __instance, ItemInstanceData data, ref string __result)
		{
			if (BazookaAmmoUI.TryGetRemaining(__instance, data, out var remaining))
			{
				__result = $"{__result} ({remaining})";
			}
		}
	}
	[HarmonyPatch(typeof(GUIManager), "GetMainInteractPrompt")]
	internal static class BazookaPromptPatch
	{
		[HarmonyPostfix]
		private static void AppendShots(Item item, ref string __result)
		{
			if (BazookaAmmoUI.TryGetRemaining(item, null, out var remaining))
			{
				__result = $"{__result} ({remaining})";
			}
		}
	}
	internal static class BazookaCombat
	{
		private static readonly Dictionary<int, int> worldHitCounts = new Dictionary<int, int>();

		private static readonly Dictionary<long, ShotTargetKind> worldDefeats = new Dictionary<long, ShotTargetKind>();

		internal static Vector3 BlastPoint { get; set; }

		internal static void ClearWorldHitCounts()
		{
			worldHitCounts.Clear();
			worldDefeats.Clear();
		}

		internal static int[] PackWorldDefeats()
		{
			int[] array = new int[worldDefeats.Count * 3];
			int num = 0;
			foreach (KeyValuePair<long, ShotTargetKind> worldDefeat in worldDefeats)
			{
				UnpackDefeatKey(worldDefeat.Key, out var viewId, out var extra);
				array[num++] = viewId;
				array[num++] = (int)worldDefeat.Value;
				array[num++] = extra;
			}
			return array;
		}

		internal static void ApplyPackedWorldDefeats(int[]? packed)
		{
			if (packed != null)
			{
				for (int i = 0; i + 2 < packed.Length; i += 3)
				{
					int num = packed[i];
					ShotTargetKind shotTargetKind = (ShotTargetKind)packed[i + 1];
					int extra = packed[i + 2];
					worldDefeats[DefeatKey(num, extra)] = shotTargetKind;
					PhotonView view = PhotonView.Find(num);
					ClientApplyDefeat(view, shotTargetKind, extra);
				}
			}
		}

		private static long DefeatKey(int viewId, int extra)
		{
			return ((long)viewId << 32) | (uint)extra;
		}

		private static void UnpackDefeatKey(long key, out int viewId, out int extra)
		{
			viewId = (int)(key >> 32);
			extra = (int)key;
		}

		internal static bool TryHit(Collider collider, Character? shooter, BazookaShooter source, int shotId, Vector3 hitPoint, Vector3 direction, float strength)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)collider == (Object)null)
			{
				return false;
			}
			int num = 1 << ((Component)collider).gameObject.layer;
			if ((((LayerMask)(ref HelperFunctions.CharacterAndDefaultMask)).value & num) == 0)
			{
				return TryHitStage(ShotStage.World, collider, source, shotId, num);
			}
			if (TryHitStage(ShotStage.BeforeCharacters, collider, source, shotId))
			{
				return true;
			}
			Character componentInParent = ((Component)collider).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)shooter)
			{
				return TryHitCharacter(componentInParent, collider, source, shotId, hitPoint, direction, strength);
			}
			if ((Object)(object)componentInParent != (Object)null)
			{
				return false;
			}
			return TryHitStage(ShotStage.World, collider, source, shotId);
		}

		private static bool TryHitStage(ShotStage stage, Collider collider, BazookaShooter source, int shotId, int extraLayerBit = 0)
		{
			foreach (ShotTarget item in ShotTargetRegistry.All)
			{
				if (item.Stage == stage && !item.Broken && item.Rule.Enabled && (extraLayerBit == 0 || (item.ExtraLayerMask & extraLayerBit) != 0))
				{
					Component val = ShotTargetRegistry.Classify(item, collider);
					if ((Object)(object)val != (Object)null)
					{
						HitWorldTarget(item, val, source, shotId);
						return true;
					}
				}
			}
			return false;
		}

		private static void HitWorldTarget(ShotTarget target, Component component, BazookaShooter source, int shotId)
		{
			PhotonView val = ShotTargetRegistry.ViewOf(target, component);
			int num = ShotTargetRegistry.ExtraOf(target, component);
			if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient || (Object)(object)val == (Object)null)
			{
				ApplyRegisteredHit(target, component, val, source, num);
				return;
			}
			((MonoBehaviourPun)source).photonView.RPC("RPC_HostShootTarget", (RpcTarget)2, new object[4]
			{
				val.ViewID,
				(int)target.Kind,
				shotId,
				num
			});
		}

		internal static void HostApply(PhotonView view, ShotTargetKind kind, BazookaShooter? source = null, int extra = 0)
		{
			ShotTarget shotTarget = ShotTargetRegistry.For(kind);
			if (shotTarget != null && shotTarget.Rule.Enabled)
			{
				Component val = ShotTargetRegistry.FindFromView(shotTarget, view, extra);
				if ((Object)(object)val != (Object)null && (Object)(object)ShotTargetRegistry.ViewOf(shotTarget, val) == (Object)(object)view)
				{
					ApplyRegisteredHit(shotTarget, val, view, source, extra);
				}
			}
		}

		private static void ApplyRegisteredHit(ShotTarget target, Component component, PhotonView? view, BazookaShooter? source, int extra)
		{
			if (target.Rule.Enabled)
			{
				if (!RegisterWorldHitTowardDefeat(target, component, view, extra))
				{
					ShotTargetRegistry.PartialHit(target, component, new ShotHit(view, source, extra));
				}
				else if (ShotTargetRegistry.Defeat(target, component, new ShotHit(view, source, extra)))
				{
					ReplicateWorldDefeat(target, source, view, extra);
				}
			}
		}

		private static void ReplicateWorldDefeat(ShotTarget target, BazookaShooter? source, PhotonView? view, int extra)
		{
			if (!target.BroadcastsDefeat)
			{
				return;
			}
			if ((Object)(object)view != (Object)null && view.ViewID != 0)
			{
				worldDefeats[DefeatKey(view.ViewID, extra)] = target.Kind;
			}
			if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
			{
				HostConfigSync.PublishWorldDefeats();
				if ((Object)(object)source != (Object)null && (Object)(object)view != (Object)null)
				{
					((MonoBehaviourPun)source).photonView.RPC("RPC_ApplyWorldDefeat", (RpcTarget)1, new object[3]
					{
						view.ViewID,
						(int)target.Kind,
						extra
					});
				}
			}
		}

		internal static void BroadcastEffect(ShotTarget target, Component component, ShotHit hit, Vector3 push, int variant = 0)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom && (Object)(object)hit.Shooter != (Object)null && (Object)(object)hit.View != (Object)null && hit.View.ViewID != 0)
			{
				((MonoBehaviourPun)hit.Shooter).photonView.RPC("RPC_ShotEffect", (RpcTarget)0, new object[5]
				{
					hit.View.ViewID,
					(int)target.Kind,
					hit.Extra,
					push,
					variant
				});
			}
			else
			{
				ShotTargetRegistry.Effect(target, component, push, variant);
			}
		}

		internal static void ApplyEffect(PhotonView? view, ShotTargetKind kind, int extra, Vector3 push, int variant)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			ShotTarget shotTarget = ShotTargetRegistry.For(kind);
			if (shotTarget != null && !((Object)(object)view == (Object)null))
			{
				Component val = ShotTargetRegistry.FindFromView(shotTarget, view, extra);
				if ((Object)(object)val != (Object)null)
				{
					ShotTargetRegistry.Effect(shotTarget, val, push, variant);
				}
			}
		}

		internal static void ClientApplyDefeat(PhotonView? view, ShotTargetKind kind, int extra = 0)
		{
			ShotTarget shotTarget = ShotTargetRegistry.For(kind);
			if (shotTarget != null && shotTarget.BroadcastsDefeat)
			{
				ShotTargetRegistry.ClientDefeat(shotTarget, view, extra);
			}
		}

		private static bool RegisterWorldHitTowardDefeat(ShotTarget target, Component component, PhotonView? view, int extra)
		{
			int hitsToDefeat = target.Rule.HitsToDefeat;
			if (hitsToDefeat <= 1)
			{
				return true;
			}
			int key = (((Object)(object)view != (Object)null && view.ViewID != 0) ? (view.ViewID ^ (extra * -1640531527)) : (int.MinValue ^ ((Object)component).GetInstanceID()));
			worldHitCounts.TryGetValue(key, out var value);
			value++;
			if (value >= hitsToDefeat)
			{
				worldHitCounts.Remove(key);
				return true;
			}
			worldHitCounts[key] = value;
			return false;
		}

		private static bool TryHitCharacter(Character character, Collider collider, BazookaShooter source, int shotId, Vector3 hitPoint, Vector3 direction, float strength)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (character.isScoutmaster)
			{
				return TryHitStage(ShotStage.Scoutmaster, collider, source, shotId);
			}
			if (GunCharacterLaunch.IsZombie(character))
			{
				if (!ShootableRules.Zombies.Enabled)
				{
					return false;
				}
				GunCharacterLaunch component = ((Component)character).GetComponent<GunCharacterLaunch>();
				if (((MonoBehaviourPun)character).photonView.IsMine)
				{
					component?.Blast(direction, strength, Plugin.Knockback);
				}
				else
				{
					((MonoBehaviourPun)character).photonView.RPC("RPC_BazookaBlast", ((MonoBehaviourPun)character).photonView.Owner, new object[4]
					{
						direction,
						strength,
						Plugin.Knockback,
						shotId
					});
				}
				return true;
			}
			if (!ShootableRules.Scouts.Enabled)
			{
				return false;
			}
			if (Plugin.RocketJumpMode)
			{
				return true;
			}
			((MonoBehaviourPun)source).photonView.RPC("RPC_GunImpact", (RpcTarget)0, new object[5]
			{
				((MonoBehaviourPun)character).photonView.Owner,
				direction,
				strength,
				Plugin.Knockback,
				shotId
			});
			return true;
		}
	}
	internal sealed class BazookaInstanceSetup : MonoBehaviour
	{
		internal static readonly HashSet<BazookaInstanceSetup> Active = new HashSet<BazookaInstanceSetup>();

		internal Item? Item { get; private set; }

		private void Awake()
		{
			Item = ((Component)this).GetComponent<Item>();
			Plugin.StripItemAntigrav(((Component)this).gameObject, immediate: false);
			ApplyLocal();
		}

		private void Start()
		{
			ApplyLocal();
			if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)
			{
				((MonoBehaviour)this).StartCoroutine(HostEnsureMagazine());
			}
		}

		internal void ApplyLocal()
		{
			if (!((Object)(object)Item == (Object)null))
			{
				Item.carryWeight = Plugin.CarryWeight;
				if (Plugin.InfiniteShots)
				{
					Item.totalUses = -1;
					Item.UIData.hideFuel = true;
				}
				else
				{
					Item.totalUses = Plugin.ShotCount;
					Item.UIData.hideFuel = false;
				}
			}
		}

		private IEnumerator HostEnsureMagazine()
		{
			yield return null;
			if ((Object)(object)Item == (Object)null)
			{
				yield break;
			}
			ApplyLocal();
			if (Plugin.InfiniteShots)
			{
				((Component)this).GetComponent<Action_Ammo>()?.ApplyInfinite();
				yield break;
			}
			if (Item.HasData((DataEntryKey)2))
			{
				OptionableIntItemData data = Item.GetData<OptionableIntItemData>((DataEntryKey)2);
				if (data.HasData && data.Value >= 0)
				{
					yield break;
				}
			}
			((Component)this).GetComponent<Action_Ammo>()?.EnsureHostMagazine();
		}

		private void OnEnable()
		{
			Active.Add(this);
		}

		private void OnDisable()
		{
			Active.Remove(this);
		}

		private void OnDestroy()
		{
			Active.Remove(this);
		}
	}
	internal static class BazookaPaint
	{
		private enum Paint
		{
			Red,
			Original,
			White
		}

		private static readonly Color32 RocketRed = new Color32((byte)224, (byte)42, (byte)31, byte.MaxValue);

		private static readonly Color32 PaperWhite = new Color32((byte)242, (byte)240, (byte)234, byte.MaxValue);

		private const float GrimeKept = 0.3f;

		private const float GripBelow = -1.2f;

		private const string BrassMaterialName = "M_Tarnished Gold Antizooka";

		internal const string ShellName = "Shell";

		private static readonly Dictionary<Paint, Material> materials = new Dictionary<Paint, Material>();

		internal static void Apply(GameObject gun)
		{
			HideShell(gun);
			MeshRenderer[] componentsInChildren = gun.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
				int num = Array.FindIndex(sharedMaterials, (Material m) => (Object)(object)m != (Object)null && ((Object)m).name.StartsWith("M_Tarnished Gold Antizooka"));
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				if (num < 0 || (Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
				{
					continue;
				}
				Material val2 = sharedMaterials[num];
				Mesh sharedMesh = component.sharedMesh;
				Mesh val3 = ((sharedMesh.subMeshCount == sharedMaterials.Length) ? MeshReadback.ReadableCopy(sharedMesh) : null);
				if ((Object)(object)val3 == (Object)null)
				{
					Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
					for (int num2 = 0; num2 < sharedMaterials.Length; num2++)
					{
						array[num2] = Painted(val2, (num2 != num) ? Paint.White : Paint.Red);
					}
					((Renderer)val).sharedMaterials = array;
					Plugin.Log.LogWarning((object)("Bazooka paint: mesh '" + ((Object)sharedMesh).name + "' could not be read; red fittings and grips, white tube."));
					return;
				}
				((Object)val3).name = ((Object)sharedMesh).name + " (Bazooka)";
				SortedDictionary<Paint, List<int>> sortedDictionary = Split(val3, num);
				val3.subMeshCount = sortedDictionary.Count;
				List<Material> list = new List<Material>();
				List<string> list2 = new List<string>();
				int num3 = 0;
				foreach (KeyValuePair<Paint, List<int>> item in sortedDictionary)
				{
					val3.SetTriangles(item.Value, num3++, false);
					list.Add((Material)((item.Key == Paint.Original) ? ((object)val2) : ((object)Painted(val2, item.Key))));
					list2.Add($"{item.Key} {item.Value.Count / 3}");
				}
				component.sharedMesh = val3;
				((Renderer)val).sharedMaterials = list.ToArray();
				Plugin.Log.LogInfo((object)("Bazooka paint: " + string.Join(", ", list2) + " triangles."));
				return;
			}
			Plugin.Log.LogWarning((object)"Bazooka paint: no AntiZooka renderer found; keeping the vanilla look.");
		}

		private static SortedDictionary<Paint, List<int>> Split(Mesh mesh, int brassSubmesh)
		{
			Vector3[] vertices = mesh.vertices;
			SortedDictionary<Paint, List<int>> parts = new SortedDictionary<Paint, List<int>>();
			for (int i = 0; i < mesh.subMeshCount; i++)
			{
				int[] triangles = mesh.GetTriangles(i);
				if (i != brassSubmesh)
				{
					Add(Paint.White, triangles);
					continue;
				}
				List<List<int>> list = Pieces(vertices, triangles);
				List<int> list2 = null;
				float num = 0f;
				foreach (List<int> item in list)
				{
					float num2 = 0f;
					foreach (int item2 in item)
					{
						num2 = Mathf.Max(num2, Mathf.Abs(vertices[item2].x));
					}
					if (num2 > num)
					{
						num = num2;
						list2 = item;
					}
				}
				foreach (List<int> item3 in list)
				{
					float num3 = float.MaxValue;
					foreach (int item4 in item3)
					{
						num3 = Mathf.Min(num3, vertices[item4].z);
					}
					Add((item3 == list2 || num3 < -1.2f) ? Paint.Original : Paint.Red, item3);
				}
			}
			return parts;
			void Add(Paint paint, IEnumerable<int> collection)
			{
				if (!parts.TryGetValue(paint, out List<int> value))
				{
					value = new List<int>();
					parts[paint] = value;
				}
				value.AddRange(collection);
			}
		}

		private static List<List<int>> Pieces(Vector3[] vertices, int[] triangles)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_005e: 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_0088: 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)
			Dictionary<int, int> parent = new Dictionary<int, int>();
			Dictionary<Vector3Int, int> dictionary = new Dictionary<Vector3Int, int>();
			Vector3Int key = default(Vector3Int);
			foreach (int num in triangles)
			{
				if (!parent.ContainsKey(num))
				{
					parent[num] = num;
					Vector3 val = vertices[num];
					((Vector3Int)(ref key))..ctor(Mathf.RoundToInt(val.x * 10000f), Mathf.RoundToInt(val.y * 10000f), Mathf.RoundToInt(val.z * 10000f));
					if (dictionary.TryGetValue(key, out var value))
					{
						Union(num, value);
					}
					else
					{
						dictionary[key] = num;
					}
				}
			}
			for (int j = 0; j < triangles.Length; j += 3)
			{
				Union(triangles[j], triangles[j + 1]);
				Union(triangles[j], triangles[j + 2]);
			}
			Dictionary<int, List<int>> dictionary2 = new Dictionary<int, List<int>>();
			for (int k = 0; k < triangles.Length; k += 3)
			{
				int key2 = Find(triangles[k]);
				if (!dictionary2.TryGetValue(key2, out var value2))
				{
					value2 = (dictionary2[key2] = new List<int>());
				}
				value2.Add(triangles[k]);
				value2.Add(triangles[k + 1]);
				value2.Add(triangles[k + 2]);
			}
			return new List<List<int>>(dictionary2.Values);
			int Find(int a)
			{
				while (parent[a] != a)
				{
					parent[a] = parent[parent[a]];
					a = parent[a];
				}
				return a;
			}
			void Union(int a, int b)
			{
				a = Find(a);
				b = Find(b);
				if (a != b)
				{
					parent[a] = b;
				}
			}
		}

		private static void HideShell(GameObject gun)
		{
			Transform[] componentsInChildren = gun.GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name != "Shell")
				{
					continue;
				}
				Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val2 in componentsInChildren2)
				{
					if ((val2 is MeshRenderer || val2 is SkinnedMeshRenderer) ? true : false)
					{
						val2.enabled = false;
					}
				}
			}
		}

		private static Material Painted(Material template, Paint paint)
		{
			//IL_001b: 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)
			//IL_0037: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if (materials.TryGetValue(paint, out Material value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Material val = new Material(template)
			{
				name = $"M_Bazooka_{paint}"
			};
			Texture2D val2 = Flat((paint == Paint.White) ? PaperWhite : RocketRed);
			((Object)val2).name = ((Object)val).name + "_Tex";
			val.SetTexture("_MainTex", (Texture)(object)val2);
			val.SetTextureScale("_MainTex", Vector2.one);
			val.SetTextureOffset("_MainTex", Vector2.zero);
			string[] array = new string[2] { "_HueShifts", "_HueShifts1" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetColor(text, Color.clear);
				}
			}
			string[] array2 = new string[4] { "_Color1", "_Color2", "_Color3", "_Color4" };
			foreach (string text2 in array2)
			{
				if (val.HasProperty(text2))
				{
					Color color = val.GetColor(text2);
					color.a *= 0.3f;
					val.SetColor(text2, color);
				}
			}
			SetIfPresent(val, "_AddSpecular", 1.5f);
			SetIfPresent(val, "_Metallic", 0.1f);
			SetIfPresent(val, "_BaseMetallic", 0.1f);
			SetIfPresent(val, "_Metalic", 0.1f);
			SetIfPresent(val, "_Smoothness", 0.45f);
			SetIfPresent(val, "_BaseSmooth", 0.45f);
			materials[paint] = val;
			return val;
		}

		private static Texture2D Flat(Color32 colour)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0018: 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)
			Texture2D val = new Texture2D(4, 4, (TextureFormat)4, false);
			Color32[] array = (Color32[])(object)new Color32[16];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = colour;
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			return val;
		}

		private static void SetIfPresent(Material material, string property, float value)
		{
			if (material.HasProperty(property))
			{
				material.SetFloat(property, value);
			}
		}
	}
	internal sealed class BazookaRocket : MonoBehaviour
	{
		private const float Radius = 0.18f;

		private const float GravityScale = 0.28f;

		private const float MaxLife = 6f;

		private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[32];

		internal BazookaShooter? Shooter;

		internal int ShotId;

		internal bool ReportsImpact;

		private Vector3 velocity;

		private float age;

		private bool exploded;

		internal void Launch(Vector3 origin, Vector3 direction, float speed)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			//IL_0020: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = origin;
			((Component)this).transform.rotation = Quaternion.LookRotation(direction);
			velocity = ((Vector3)(ref direction)).normalized * speed;
		}

		private void Update()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006e: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (exploded)
			{
				return;
			}
			age += Time.deltaTime;
			velocity += Physics.gravity * 0.28f * Time.deltaTime;
			Vector3 val = velocity * Time.deltaTime;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.0001f)
			{
				return;
			}
			Vector3 direction = val / magnitude;
			if (TryFindImpact(((Component)this).transform.position, direction, magnitude, out var impact))
			{
				Explode(impact);
				return;
			}
			Transform transform = ((Component)this).transform;
			transform.position += val;
			if (((Vector3)(ref velocity)).sqrMagnitude > 0.001f)
			{
				((Component)this).transform.rotation = Quaternion.LookRotation(velocity);
			}
			if (age >= 6f)
			{
				Explode(((Component)this).transform.position);
			}
		}

		private bool TryFindImpact(Vector3 from, Vector3 direction, float distance, out Vector3 impact)
		{
			//IL_0000: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			int num = LayerMask.op_Implicit(HelperFunctions.CharacterAndDefaultMask) | LayerMask.op_Implicit(HelperFunctions.terrainMapMask) | ShotTargetRegistry.ExtraLayerMask;
			int num2 = Physics.SphereCastNonAlloc(from, 0.18f, direction, Hits, distance, num, (QueryTriggerInteraction)2);
			float num3 = float.MaxValue;
			impact = from;
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val = Hits[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !(((RaycastHit)(ref val)).distance >= num3) && !IsShooterCollider(((RaycastHit)(ref val)).collider) && (!(((RaycastHit)(ref val)).distance <= 0f) || (!((RaycastHit)(ref val)).collider.isTrigger && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>() == (Object)null))))
				{
					num3 = ((RaycastHit)(ref val)).distance;
					impact = ((((RaycastHit)(ref val)).distance <= 0f) ? from : ((RaycastHit)(ref val)).point);
				}
			}
			return num3 < float.MaxValue;
		}

		private bool IsShooterCollider(Collider collider)
		{
			Character val = (((Object)(object)Shooter != (Object)null) ? Shooter.Character : null);
			if ((Object)(object)val == (Object)null || (Object)(object)collider == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)collider).GetComponentInParent<Character>() == (Object)(object)val)
			{
				return true;
			}
			Item componentInParent = ((Component)collider).GetComponentInParent<Item>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return (Object)(object)componentInParent.holderCharacter == (Object)(object)val;
			}
			return false;
		}

		private void Explode(Vector3 point)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			if (!exploded)
			{
				exploded = true;
				if (ReportsImpact && (Object)(object)Shooter != (Object)null)
				{
					Shooter.DetonateRocket(ShotId, point, (((Vector3)(ref velocity)).sqrMagnitude > 0.01f) ? ((Vector3)(ref velocity)).normalized : ((Component)this).transform.forward);
				}
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public class BazookaShooter : MonoBehaviourPun
	{
		private const float ScoutInjury = 0.4f;

		private const float LooseItemMinSpeed = 4f;

		private const float LooseItemMaxSpeed = 14f;

		private Character? character;

		internal Character? Character => character;

		private void Awake()
		{
			character = ((Component)this).GetComponent<Character>();
		}

		internal void LaunchRocket(Vector3 origin, Vector3 forward, int shotId)
		{
			//IL_003b: 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_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)
			if (PhotonNetwork.InRoom)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_LaunchRocket", (RpcTarget)0, new object[3] { origin, forward, shotId });
			}
			else
			{
				SpawnRocket(origin, forward, shotId, reportsImpact: true);
			}
		}

		[PunRPC]
		private void RPC_LaunchRocket(Vector3 origin, Vector3 forward, int shotId, PhotonMessageInfo info)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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)
			if (FromOwner(info))
			{
				SpawnRocket(origin, forward, shotId, ((MonoBehaviourPun)this).photonView.IsMine);
			}
		}

		private bool FromOwner(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)
			{
				if (info.Sender != null)
				{
					return info.Sender == ((MonoBehaviourPun)this).photonView.Owner;
				}
				return false;
			}
			return true;
		}

		private void SpawnRocket(Vector3 origin, Vector3 forward, int shotId, bool reportsImpact)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = BuildRocketVisual();
			val.transform.position = origin;
			BazookaRocket bazookaRocket = val.AddComponent<BazookaRocket>();
			bazookaRocket.Shooter = this;
			bazookaRocket.ShotId = shotId;
			bazookaRocket.ReportsImpact = reportsImpact;
			bazookaRocket.Launch(origin, forward, Plugin.MuzzleVelocity);
		}

		private static GameObject BuildRocketVisual()
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = RocketModel.Create();
			if ((Object)(object)val != (Object)null)
			{
				((Object)val).name = "BazookaRocket";
				return val;
			}
			GameObject bazookaPrefab = Plugin.BazookaPrefab;
			Transform val2 = null;
			if ((Object)(object)bazookaPrefab != (Object)null)
			{
				Transform[] componentsInChildren = bazookaPrefab.GetComponentsInChildren<Transform>(true);
				foreach (Transform val3 in componentsInChildren)
				{
					if ((Object)(object)val3 != (Object)null && ((Object)val3).name == "Shell")
					{
						val2 = val3;
						break;
					}
				}
			}
			GameObject val4;
			if ((Object)(object)val2 != (Object)null)
			{
				val4 = Object.Instantiate<GameObject>(((Component)val2).gameObject);
				val4.SetActive(true);
				Renderer[] componentsInChildren2 = val4.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val5 in componentsInChildren2)
				{
					val5.enabled = true;
				}
				Collider[] componentsInChildren3 = val4.GetComponentsInChildren<Collider>(true);
				foreach (Collider val6 in componentsInChildren3)
				{
					Object.Destroy((Object)(object)val6);
				}
			}
			else
			{
				val4 = GameObject.CreatePrimitive((PrimitiveType)0);
				val4.transform.localScale = Vector3.one * 0.22f;
				Object.Destroy((Object)(object)val4.GetComponent<Collider>());
				MeshRenderer val7 = (((Object)(object)bazookaPrefab != (Object)null) ? bazookaPrefab.GetComponentInChildren<MeshRenderer>(true) : null);
				MeshRenderer component = val4.GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null && (Object)(object)val7 != (Object)null)
				{
					((Renderer)component).sharedMaterial = ((Renderer)val7).sharedMaterial;
				}
			}
			((Object)val4).name = "BazookaRocket";
			return val4;
		}

		internal void DetonateRocket(int shotId, Vector3 point, Vector3 direction)
		{
			//IL_0032: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_RocketExplode", (RpcTarget)0, new object[2] { point, shotId });
			}
			else
			{
				PlayExplosion(point);
			}
			ApplyBlast(shotId, point, direction);
		}

		[PunRPC]
		private void RPC_RocketExplode(Vector3 point, int shotId, PhotonMessageInfo info)
		{
			//IL_0001: 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)
			if (!FromOwner(info))
			{
				return;
			}
			PlayExplosion(point);
			BazookaRocket[] array = Object.FindObjectsByType<BazookaRocket>((FindObjectsSortMode)0);
			foreach (BazookaRocket bazookaRocket in array)
			{
				if ((Object)(object)bazookaRocket != (Object)null && (Object)(object)bazookaRocket.Shooter == (Object)(object)this && bazookaRocket.ShotId == shotId)
				{
					Object.Destroy((Object)(object)((Component)bazookaRocket).gameObject);
				}
			}
		}

		private static void PlayExplosion(Vector3 point)
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Plugin.ExplosionPrefab != (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(Plugin.ExplosionPrefab, point, Quaternion.identity);
				float num = Plugin.ExplosionRadius / 5f;
				val.transform.localScale = Vector3.one * num;
				ExplosionEffect val2 = val.GetComponent<ExplosionEffect>() ?? val.GetComponentInChildren<ExplosionEffect>();
				if ((Object)(object)val2 != (Object)null)
				{
					val2.baseScale *= num;
					val2.explosionRadius = Plugin.ExplosionRadius;
					val2.explosionPointCount = 1;
					val2.subExplosionPointCount = 0;
					val2.minDelay = 0f;
					val2.maxDelay = 0f;
				}
				float explosionVolume = Plugin.ExplosionVolume;
				AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val3 in componentsInChildren)
				{
					val3.volume *= explosionVolume;
					if (val3.isPlaying)
					{
						val3.Stop();
						val3.Play();
					}
				}
				val.SetActive(true);
				Object.Destroy((Object)(object)val, 7f);
			}
			GamefeelHandler.instance.AddPerlinShakeProximity(point, Plugin.ExplosionShake, 0.2f, 15f, 10f);
			BlastLooseItems(point);
		}

		private static void BlastLooseItems(Vector3 point)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			float blastReach = Plugin.BlastReach;
			HashSet<Item> hashSet = new HashSet<Item>();
			Collider[] array = Physics.OverlapSphere(point, blastReach, LayerMask.op_Implicit(HelperFunctions.DefaultMask), (QueryTriggerInteraction)1);
			foreach (Collider val in array)
			{
				Item val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<Item>() : null);
				if ((Object)(object)val2 == (Object)null || (int)val2.itemState != 0 || !((MonoBehaviourPun)val2).photonView.IsMine || !hashSet.Add(val2))
				{
					continue;
				}
				if ((Object)(object)val2.cooking != (Object)null)
				{
					val2.cooking.FinishCooking();
				}
				if (!((Object)(object)val2.rig == (Object)null) && !val2.rig.isKinematic)
				{
					Vector3 val3 = val2.Center() - point;
					float num = Mathf.Clamp01(1f - ((Vector3)(ref val3)).magnitude / blastReach);
					Vector3 val5;
					if (!(((Vector3)(ref val3)).sqrMagnitude < 0.0001f))
					{
						Vector3 val4 = ((Vector3)(ref val3)).normalized + Vector3.up * 0.6f;
						val5 = ((Vector3)(ref val4)).normalized;
					}
					else
					{
						val5 = Vector3.up;
					}
					Vector3 val6 = val5;
					val2.rig.AddForce(val6 * (Mathf.Lerp(4f, 14f, num) * Plugin.KnockbackScale), (ForceMode)2);
				}
			}
		}

		private void ApplyBlast(int shotId, Vector3 point, Vector3 fallbackDirection)
		{
			//IL_010a: 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_0022: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || !character.IsLocal)
			{
				return;
			}
			ApplySelfBlast(character, point);
			Dictionary<int, (Collider, Vector3, float)> dictionary = new Dictionary<int, (Collider, Vector3, float)>();
			int num = LayerMask.op_Implicit(HelperFunctions.CharacterAndDefaultMask) | ShotTargetRegistry.ExtraLayerMask;
			int value = ((LayerMask)(ref HelperFunctions.terrainMapMask)).value;
			float blastReach = Plugin.BlastReach;
			Collider[] array = Physics.OverlapSphere(point, blastReach, num, (QueryTriggerInteraction)2);
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null || ((1 << ((Component)val).gameObject.layer) & value) != 0)
				{
					continue;
				}
				Character componentInParent = ((Component)val).GetComponentInParent<Character>();
				if (!((Object)(object)componentInParent == (Object)(object)character))
				{
					int key;
					if ((Object)(object)componentInParent != (Object)null)
					{
						key = ((Object)componentInParent).GetInstanceID();
					}
					else
					{
						PhotonView componentInParent2 = ((Component)val).GetComponentInParent<PhotonView>();
						key = (((Object)(object)componentInParent2 != (Object)null && componentInParent2.ViewID != 0) ? componentInParent2.ViewID : ((Object)val).GetInstanceID());
					}
					Vector3 val2 = ((Component)val).transform.position;
					try
					{
						val2 = val.ClosestPoint(point);
					}
					catch (Exception)
					{
					}
					float num2 = Vector3.Distance(val2, point);
					if (!dictionary.TryGetValue(key, out var value2) || num2 < value2.Item3)
					{
						dictionary[key] = (val, val2, num2);
					}
				}
			}
			BazookaCombat.BlastPoint = point;
			foreach (var value3 in dictionary.Values)
			{
				Collider item = value3.Item1;
				Vector3 item2 = value3.Item2;
				float item3 = value3.Item3;
				Vector3 direction = item2 - point;
				direction = ((((Vector3)(ref direction)).sqrMagnitude < 0.0001f) ? fallbackDirection : ((Vector3)(ref direction)).normalized);
				float strength = Mathf.Clamp01(1f - item3 / blastReach);
				BazookaCombat.TryHit(item, character, this, shotId, item2, direction, strength);
			}
		}

		private static void ApplySelfBlast(Character shooter, Vector3 point)
		{
			//IL_000f: 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_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_001e: 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_0020: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			if (shooter.data.dead)
			{
				return;
			}
			Vector3 center = shooter.Center;
			float num = NearestBlastDistance(shooter, point, center);
			Vector3 val = center - point;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.up;
			}
			if (Plugin.RocketJumpMode)
			{
				RocketJump(shooter, num, ((Vector3)(ref val)).normalized);
				return;
			}
			float blastReach = Plugin.BlastReach;
			if (!(num > blastReach))
			{
				float num2 = 1f - num / blastReach;
				float num3 = num2 * num2;
				shooter.Fall(2f, 0f);
				float num4 = Plugin.SelfKnockback * num3;
				if (num4 > 0.01f)
				{
					Vector3 val2 = ((Vector3)(ref val)).normalized + Vector3.up * Plugin.SelfKnockbackUp;
					Vector3 normalized = ((Vector3)(ref val2)).normalized;
					shooter.AddForce(normalized * (num4 / Time.fixedDeltaTime), 1f, 1f);
				}
				float num5 = Plugin.SelfDamage * Mathf.Lerp(0.5f, 1f, num2);
				if (num5 > 0.0001f)
				{
					shooter.refs.afflictions.AddAffliction((Affliction)new Affliction_AdjustStatus((STATUSTYPE)0, num5, 1f), false);
				}
			}
		}

		private static void RocketJump(Character shooter, float distance, Vector3 away)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			float blastReach = Plugin.BlastReach;
			float num = Plugin.JumpLaunchSpeed * (1f - 0.5f * (distance / blastReach));
			if (!(distance > blastReach) && !(num < 0.01f))
			{
				Vector3 val = away + Vector3.up * Plugin.JumpLaunchUp;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				((Component)shooter).GetComponent<GunCharacterLaunch>()?.BeginRocketFlight(normalized * num);
			}
		}

		private static float NearestBlastDistance(Character shooter, Vector3 point, Vector3 fallback)
		{
			//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_0078: 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)
			//IL_007f: 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)
			float num = Vector3.Distance(fallback, point);
			CharacterRagdoll val = ((shooter.refs != null) ? shooter.refs.ragdoll : null);
			if (val?.partList == null)
			{
				return num;
			}
			foreach (Bodypart part in val.partList)
			{
				if ((Object)(object)part == (Object)null)
				{
					continue;
				}
				Collider[] components = ((Component)part).GetComponents<Collider>();
				foreach (Collider val2 in components)
				{
					if ((Object)(object)val2 == (Object)null || !val2.enabled)
					{
						continue;
					}
					try
					{
						Vector3 val3 = val2.ClosestPoint(point) - point;
						float magnitude = ((Vector3)(ref val3)).magnitude;
						if (magnitude < num)
						{
							num = magnitude;
						}
					}
					catch (Exception)
					{
					}
				}
			}
			return num;
		}

		[PunRPC]
		public void RPC_GunImpact(Player? hitPlayer, Vector3 direction, float strength, float knockback, int shotId, PhotonMessageInfo info)
		{
			//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_0053: 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)
			if (hitPlayer == null || !hitPlayer.IsLocal)
			{
				return;
			}
			Character local = Character.localCharacter;
			if (!((Object)(object)local == (Object)null))
			{
				int viewID = ((MonoBehaviourPun)local).photonView.ViewID;
				if (ShotLedger.TryConsumeOrDeferHit(info.Sender, shotId, viewID, delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					ApplyGunImpact(local, direction, strength, knockback);
				}))
				{
					ApplyGunImpact(local, direction, strength, knockback);
				}
			}
		}

		private static void ApplyGunImpact(Character local, Vector3 direction, float strength, float knockback)
		{
			//IL_0022: 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_005c: Expected O, but got Unknown
			if (ShootableRules.Scouts.Enabled && !Plugin.RocketJumpMode)
			{
				strength = Mathf.Clamp01(strength);
				((Component)local).GetComponent<GunCharacterLaunch>().Blast(direction, strength, knockback);
				local.refs.afflictions.AddAffliction((Affliction)new Affliction_AdjustStatus((STATUSTYPE)0, 0.4f * Mathf.Lerp(0.5f, 1f, strength), 1f), false);
			}
		}

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

		[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)
			{
				BazookaCombat.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)
			{
				BazookaCombat.ApplyEffect(PhotonView.Find(viewId), (ShotTargetKind)kind, extra, push, variant);
			}
		}
	}
	internal static class BazookaText
	{
		internal const string BazookaItemName = "Bazooka";

		internal const string ShootPrompt = "SHOOT";

		internal const string OverrideFileName = "PeakBazooka.localization.csv";

		private const string ResourceName = "Peak.Bazooka.localization.strings.csv";

		private static Dictionary<string, string[]>? rows;

		private static bool injecting;

		private static bool reportedFailure;

		internal static void Inject()
		{
			if (injecting)
			{
				return;
			}
			injecting = true;
			try
			{
				if (rows == null)
				{
					rows = Load();
				}
				Dictionary<string, List<string>> mainTable = LocalizedText.mainTable;
				foreach (KeyValuePair<string, string[]> row in rows)
				{
					mainTable[row.Key] = new List<string>(row.Value);
				}
			}
			catch (Exception ex)
			{
				if (!reportedFailure)
				{
					reportedFailure = true;
					Plugin.Log.LogWarning((object)("Could not add bazooka translations; names may show in English or as LOC keys: " + ex.Message));
				}
			}
			finally
			{
				injecting = false;
			}
		}

		private static Dictionary<string, string[]> Load()
		{
			int length = Enum.GetValues(typeof(Language)).Length;
			Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>();
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Peak.Bazooka.localization.strings.csv"))
			{
				if (stream == null)
				{
					Plugin.Log.LogWarning((object)"Translation resource Peak.Bazooka.localization.strings.csv was not found.");
				}
				else
				{
					using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
					Merge(dictionary, streamReader.ReadToEnd(), length, "Peak.Bazooka.localization.strings.csv");
				}
			}
			string text = Path.Combine(Paths.ConfigPath, "PeakBazooka.localization.csv");
			if (File.Exists(text))
			{
				Merge(dictionary, File.ReadAllText(text, Encoding.UTF8), length, text);
				Plugin.Log.LogInfo((object)("Loaded translation overrides from " + text + "."));
			}
			foreach (KeyValuePair<string, string[]> item in dictionary)
			{
				string text2 = (string.IsNullOrEmpty(item.Value[0]) ? item.Key : item.Value[0]);
				for (int i = 0; i < item.Value.Length; i++)
				{
					if (string.IsNullOrEmpty(item.Value[i]))
					{
						item.Value[i] = text2;
					}
				}
			}
			return dictionary;
		}

		private static void Merge(Dictionary<string, string[]> into, string csv, int languages, string source)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected I4, but got Unknown
			List<List<string>> list = ParseCsv(csv);
			if (list.Count == 0)
			{
				return;
			}
			List<string> list2 = list[0];
			int[] array = new int[list2.Count];
			for (int i = 0; i < list2.Count; i++)
			{
				array[i] = -1;
				if (i > 0 && Enum.TryParse<Language>(list2[i].Trim(), ignoreCase: true, out Language result))
				{
					array[i] = (int)result;
				}
				else if (i > 0)
				{
					Plugin.Log.LogWarning((object)(source + ": column '" + list2[i] + "' is not a PEAK language and is ignored."));
				}
			}
			for (int j = 1; j < list.Count; j++)
			{
				List<string> list3 = list[j];
				string text = ((list3.Count > 0) ? list3[0].Trim().ToUpperInvariant() : "");
				if (text.Length == 0 || text[0] == '#')
				{
					continue;
				}
				if (!into.TryGetValue(text, out string[] value))
				{
					value = (into[text] = new string[languages]);
				}
				for (int k = 1; k < list3.Count && k < array.Length; k++)
				{
					int num = array[k];
					if (num >= 0 && num < languages && list3[k].Length > 0)
					{
						value[num] = list3[k];
					}
				}
			}
		}

		private static List<List<string>> ParseCsv(string text)
		{
			List<List<string>> list = new List<List<string>>();
			List<string> list2 = new List<string>();
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = false;
			int num = ((text.Length > 0 && text[0] == '\ufeff') ? 1 : 0);
			for (int i = num; i < text.Length; i++)
			{
				char c = text[i];
				if (flag)
				{
					if (c != '"')
					{
						stringBuilder.Append(c);
					}
					else if (i + 1 < text.Length && text[i + 1] == '"')
					{
						stringBuilder.Append('"');
						i++;
					}
					else
					{
						flag = false;
					}
					continue;
				}
				switch (c)
				{
				case '"':
					flag = true;
					break;
				case ',':
					list2.Add(stringBuilder.ToString());
					stringBuilder.Clear();
					break;
				case '\n':
					list2.Add(stringBuilder.ToString());
					stringBuilder.Clear();
					list.Add(list2);
					list2 = new List<string>();
					break;
				default:
					stringBuilder.Append(c);
					break;
				case '\r':
					break;
				}
			}
			if (stringBuilder.Length > 0 || list2.Count > 0)
			{
				list2.Add(stringBuilder.ToString());
				list.Add(list2);
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(LocalizedText), "LoadMainTable")]
	internal static class LocalizedTextReloadPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			BazookaText.Inject();
		}
	}
	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(Action_Antizooka), "RPCA_Shoot", (Type[])null, (Type[])null) == null)
			{
				list.Add("Action_Antizooka.RPCA_Shoot (muzzle flash / fire juice)");
			}
			if (AccessTools.Method(typeof(Action_Antizooka), "PlayChargeFX", (Type[])null, (Type[])null) == null)
			{
				list.Add("Action_Antizooka.PlayChargeFX (instant-fire skip of charge SFX)");
			}
			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");

		internal const float BlastRagdollSeconds = 2f;

		private const float EdgeShove = 0.4f;

		private const float ShoveUp = 0.8f;

		private bool heldDown;

		private Coroutine? flightRoutine;

		private float flightStarted;

		private const float FlightSinceGrounded = 0.21f;

		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_BazookaBlast(Vector3 direction, float strength, float knockback, 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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)
			{
				int viewID = ((MonoBehaviourPun)component).photonView.ViewID;
				if (ShotLedger.TryConsumeOrDeferHit(info.Sender, shotId, viewID, delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					Blast(direction, strength, knockback);
				}))
				{
					Blast(direction, strength, knockback);
				}
			}
		}

		internal void BeginRocketFlight(Vector3 velocityChange)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_00be: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			Character component = ((Component)this).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || !component.IsLocal || component.data.dead || component.data.fallSeconds > 0f)
			{
				return;
			}
			RocketFlight.Begin(component);
			Vector3 normalized = ((Vector3)(ref velocityChange)).normalized;
			float num = Mathf.Min(0f, Vector3.Dot(component.data.avarageVelocity, normalized));
			Vector3 val = velocityChange - normalized * num;
			foreach (Bodypart part in component.refs.ragdoll.partList)
			{
				Rigidbody val2 = (((Object)(object)part != (Object)null) ? part.Rig : null);
				if ((Object)(object)val2 != (Object)null && !val2.isKinematic)
				{
					val2.linearVelocity += val;
				}
			}
			Rigidbody val3 = (((Object)(object)component.data.currentItem != (Object)null) ? component.data.currentItem.rig : null);
			if ((Object)(object)val3 != (Object)null && !val3.isKinematic)
			{
				val3.linearVelocity += val;
			}
			component.data.sinceJump = 0f;
			component.refs.movement.CapFallDamage(0f, 2f);
			flightStarted = Time.time;
			if (flightRoutine == null)
			{
				flightRoutine = ((MonoBehaviour)this).StartCoroutine(RocketFlightRoutine(component));
			}
		}

		private IEnumerator RocketFlightRoutine(Character character)
		{
			WaitForFixedUpdate step = new WaitForFixedUpdate();
			while (true)
			{
				yield return step;
				if (!KeepFlying(character, Time.time - flightStarted))
				{
					break;
				}
				if (character.data.sinceGrounded > 0.21f)
				{
					character.data.sinceGrounded = 0.21f;
				}
				character.refs.movement.CapFallDamage(0f, 2f);
			}
			flightRoutine = null;
			RocketFlight.End();
		}

		private static bool KeepFlying(Character character, float seconds)
		{
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			CharacterData data = character.data;
			if (data.dead || data.passedOut || data.fullyPassedOut || data.fallSeconds > 0f || (Object)(object)data.carrier != (Object)null || data.isClimbing || data.isRopeClimbing || data.isVineClimbing || seconds > 15f)
			{
				return false;
			}
			return !data.isGrounded;
		}

		private void OnDestroy()
		{
			if (RocketFlight.IsFlying(((Component)this).GetComponent<Character>()))
			{
				RocketFlight.End();
			}
		}

		public void Blast(Vector3 direction, float strength, float knockback)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00fe: 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 || component.data.dead)
			{
				return;
			}
			strength = Mathf.Clamp01(strength);
			component.Fall(Mathf.Lerp(1.5f, 3f, strength), 0f);
			component.data.currentRagdollControll = 0f;
			float num = Mathf.Clamp(knockback, 0f, 60f) * Mathf.Lerp(0.4f, 1f, strength);
			Vector3 val = ((Vector3)(ref direction)).normalized + Vector3.up * 0.8f;
			Vector3 val2 = ((Vector3)(ref val)).normalized * num;
			foreach (Bodypart part in component.refs.ragdoll.partList)
			{
				Rigidbody val3 = (((Object)(object)part != (Object)null) ? part.Rig : null);
				if ((Object)(object)val3 != (Object)null && !val3.isKinematic)
				{
					val3.linearVelocity += val2;
				}
			}
			if (IsZombie(component))
			{
				KnockDown(component);
			}
		}

		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_BazookaZombieShotState", (RpcTarget)1, new object[1] { heldDown });
			}
		}

		[PunRPC]
		public void RPC_BazookaZombieShotState(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)
			{
				heldDown = down;
				if (down)
				{
					Silence();
				}
			}
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine && heldDown)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_BazookaZombieShotState", newPlayer, new object[1] { 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>();
			((Component)__instance).gameObject.AddComponent<BazookaShooter>();
		}
	}
	internal sealed class HostConfigSync : MonoBehaviour, IInRoomCallbacks, IMatchmakingCallbacks
	{
		internal const string RoomShotsKey = "PeakBazooka_Shots";

		internal const string RoomShootablesKey = "PeakBazooka_Shootables";

		internal const string RoomWorldDownKey = "PeakBazooka_WorldDown";

		internal const string RoomModeKey = "PeakBazooka_Mode";

		private static int? hostShots;

		private static ShootTargets? hostShootables;

		private static BazookaMode? hostMode;

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

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

		internal static BazookaMode Mode => hostMode ?? Plugin.LocalMode;

		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;
				hostMode = Plugin.LocalMode;
				BazookaCombat.ClearWorldHitCounts();
				Plugin.ApplyShotCountConfig();
				Plugin.Log.LogInfo((object)("Shots (offline/local) = " + (Plugin.InfiniteShots ? "infinite" : ShotCount.ToString()) + " (" + reason + ")."));
			}
			else if (PhotonNetwork.IsMasterClient)
			{
				PublishHostSettings(reason);
			}
			else if (!TryApplyRoomSettings())
			{
				Plugin.Log.LogInfo((object)("Waiting for host bazooka 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_006f: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0087: Expected O, but got Unknown
			int localConfiguredShots = Plugin.LocalConfiguredShots;
			ShootTargets localShootables = ShootableRules.LocalShootables;
			BazookaMode localMode = Plugin.LocalMode;
			hostShots = localConfiguredShots;
			hostShootables = localShootables;
			hostMode = localMode;
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Hashtable val = new Hashtable();
			((Dictionary<object, object>)val).Add((object)"PeakBazooka_Shots", (object)localConfiguredShots);
			((Dictionary<object, object>)val).Add((object)"PeakBazooka_Shootables", (object)(int)localShootables);
			((Dictionary<object, object>)val).Add((object)"PeakBazooka_WorldDown", (object)BazookaCombat.PackWorldDefeats());
			((Dictionary<object, object>)val).Add((object)"PeakBazooka_Mode", (object)(int)localMode);
			currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			Plugin.ApplyShotCountConfig();
			Plugin.Log.LogInfo((object)string.Format("Host published Mode = {0}, Shots = {1}, Targets = {2} ({3}).", localMode, (localConfiguredShots <= 0) ? "infinite" : localConfiguredShots.ToString(), localShootables, 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)"PeakBazooka_Shootables", out object value) && value is int num && hostShootables != (ShootTargets?)num)
			{
				hostShootables = (ShootTargets)num;
				Plugin.Log.LogInfo((object)$"Client applied host Targets = {hostShootables}.");
			}
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakBazooka_WorldDown", out object value2) && value2 is int[] packed)
			{
				BazookaCombat.ApplyPackedWorldDefeats(packed);
			}
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakBazooka_Mode", out object value3) && value3 is int num2 && Enum.IsDefined(typeof(BazookaMode), num2))
			{
				BazookaMode bazookaMode = (BazookaMode)num2;
				if (hostMode != bazookaMode)
				{
					hostMode = bazookaMode;
					Plugin.Log.LogInfo((object)$"Client applied host Mode = {bazookaMode}.");
				}
			}
			if (!((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakBazooka_Shots", out object value4) || !(value4 is int num3))
			{
				return ((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"PeakBazooka_Shootables");
			}
			int num4 = Mathf.Max(0, num3);
			if (hostShots != num4)
			{
				hostShots = num4;
				Plugin.ApplyShotCountConfig();
				Plugin.Log.LogInfo((object)("Client applied host Shots = " + ((num4 <= 0) ? "infinite" : num4.ToString()) + "."));
			}
			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)"PeakBazooka_WorldDown", (object)BazookaCombat.PackWorldDefeats());
				currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			}
		}

		private static void ClearHostSettings()
		{
			hostShots = null;
			hostShootables = null;
			hostMode = null;
			BazookaCombat.ClearWorldHitCounts();
			ShotLedger.Clear();
		}

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

		public void OnLeftRoom()
		{
			ClearHostSettings();
		}

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

		public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			if (propertiesThatChanged != null && (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakBazooka_Shots") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakBazooka_Shootables") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakBazooka_WorldDown") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakBazooka_Mode")))
			{
				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)
		{
		}
	}
	internal static class MeshReadback
	{
		internal static Mesh? ReadableCopy(Mesh source)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing referenc