Decompiled source of ChubbyBazooka v0.3.0

BepInEx/plugins/ChubbyBazooka/ChubbyBazooka.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Photon.Pun;
using REPOLib.Modules;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;

[assembly: AssemblyTitle("Chubby Bazooka")]
[assembly: AssemblyDescription("Original low-poly R.E.P.O. bazooka prototype")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.3.0.0")]
namespace RepoBazooka;

public sealed class AmmoPolicy : MonoBehaviour
{
	public void Initialize()
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		if (SemiFunc.IsMasterClientOrSingleplayer())
		{
			int num = (((Component)this).GetComponent<BazookaBehaviour>().InfiniteAmmo ? 6 : Plugin.StartingAmmo.Value);
			if (SemiFunc.IsMultiplayer())
			{
				((Component)this).GetComponent<PhotonView>().RPC("BazookaCapacityRPC", (RpcTarget)3, new object[1] { num });
			}
			else
			{
				BazookaCapacityRPC(num);
			}
		}
	}

	[PunRPC]
	public void BazookaCapacityRPC(int capacity, PhotonMessageInfo info = default(PhotonMessageInfo))
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		if (SemiFunc.MasterOnlyRPC(info) && capacity >= 1 && capacity <= 12)
		{
			ItemBattery component = ((Component)this).GetComponent<ItemBattery>();
			component.batteryBars = capacity;
			int num = Mathf.RoundToInt(component.batteryLife * (float)capacity / 100f);
			string[] array = new string[4] { "batteryLifeInt", "currentBars", "batteryLifeCountBars", "batteryLifeCountBarsPrev" };
			foreach (string text in array)
			{
				AccessTools.Field(typeof(ItemBattery), text).SetValue(component, num);
			}
		}
	}
}
[HarmonyPatch(typeof(ItemBattery), "Start")]
internal static class InitializeAmmoCapacity
{
	[HarmonyPostfix]
	private static void Postfix(ItemBattery __instance)
	{
		AmmoPolicy component = ((Component)__instance).GetComponent<AmmoPolicy>();
		if (Object.op_Implicit((Object)(object)component))
		{
			component.Initialize();
		}
	}
}
[HarmonyPatch(typeof(ItemBattery), "RemoveFullBar")]
internal static class TestAmmoOnly
{
	[HarmonyPrefix]
	private static bool Prefix(ItemBattery __instance)
	{
		BazookaBehaviour component = ((Component)__instance).GetComponent<BazookaBehaviour>();
		if (Object.op_Implicit((Object)(object)component))
		{
			return !component.InfiniteAmmo;
		}
		return true;
	}
}
[HarmonyPatch(typeof(ItemAttributes), "OnDestroy")]
internal static class PreserveSharedBazookaIcon
{
	[HarmonyPrefix]
	private static bool Prefix(ItemAttributes __instance)
	{
		return !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<BazookaBehaviour>());
	}
}
public static class Assets
{
	private static readonly Dictionary<string, Mesh> meshes = new Dictionary<string, Mesh>();

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

	private static readonly Dictionary<string, AudioClip> audio = new Dictionary<string, AudioClip>();

	private static readonly List<AudioSource> voices = new List<AudioSource>();

	private static Sprite itemIcon;

	public static Stream Open(string name)
	{
		return Assembly.GetExecutingAssembly().GetManifestResourceStream("Bazooka." + name);
	}

	public static Sprite ItemIcon()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		//IL_0071: 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)
		if (Object.op_Implicit((Object)(object)itemIcon))
		{
			return itemIcon;
		}
		using (Stream stream = Open("item-icon.png"))
		{
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray()))
			{
				throw new InvalidOperationException("Cannot decode bazooka icon");
			}
			((Object)val).name = "ChubbyBazookaIcon";
			itemIcon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}
		return itemIcon;
	}

	public static Material Material(string key)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		//IL_00d3: 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_00a7: 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)
		if (materials.TryGetValue(key, out var value))
		{
			return value;
		}
		Shader val = Shader.Find("Standard");
		if (!Object.op_Implicit((Object)(object)val))
		{
			val = Shader.Find("Unlit/Color");
		}
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("No supported shader available");
		}
		value = new Material(val);
		((Object)value).name = "Bazooka_" + key;
		value.color = (Color)(key switch
		{
			"metal" => new Color(0.29f, 0.33f, 0.3f), 
			"orange" => new Color(0.95f, 0.3f, 0.045f), 
			"olive" => new Color(0.18f, 0.25f, 0.12f), 
			_ => new Color(0.055f, 0.065f, 0.06f), 
		});
		if (value.HasProperty("_Glossiness"))
		{
			value.SetFloat("_Glossiness", (key == "metal") ? 0.48f : ((key == "black") ? 0.22f : 0.28f));
		}
		if (value.HasProperty("_Metallic"))
		{
			value.SetFloat("_Metallic", (key == "metal") ? 0.65f : 0f);
		}
		materials.Add(key, value);
		return value;
	}

	public static GameObject Model(string name, Transform parent)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Expected O, but got Unknown
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Expected O, but got Unknown
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name + "_Visual");
		val.transform.SetParent(parent, false);
		List<Vector3> list = new List<Vector3>();
		Dictionary<string, List<Vector3>> dictionary = new Dictionary<string, List<Vector3>>();
		string key = "olive";
		using (Stream stream = Open(name + ".obj"))
		{
			using StreamReader streamReader = new StreamReader(stream);
			string text;
			while ((text = streamReader.ReadLine()) != null)
			{
				string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
				if (array.Length == 0)
				{
					continue;
				}
				if (array[0] == "v")
				{
					list.Add(new Vector3(float.Parse(array[1], CultureInfo.InvariantCulture), float.Parse(array[2], CultureInfo.InvariantCulture), float.Parse(array[3], CultureInfo.InvariantCulture)));
				}
				if (array[0] == "usemtl")
				{
					key = array[1];
				}
				if (array[0] == "f")
				{
					if (!dictionary.ContainsKey(key))
					{
						dictionary.Add(key, new List<Vector3>());
					}
					for (int i = 1; i <= 3; i++)
					{
						dictionary[key].Add(list[int.Parse(array[i], CultureInfo.InvariantCulture) - 1]);
					}
				}
			}
		}
		foreach (KeyValuePair<string, List<Vector3>> item in dictionary)
		{
			string text2 = name + ":" + item.Key;
			if (!meshes.TryGetValue(text2, out var value))
			{
				value = new Mesh();
				((Object)value).name = text2;
				value.vertices = item.Value.ToArray();
				int[] array2 = new int[item.Value.Count];
				for (int j = 0; j < array2.Length; j++)
				{
					array2[j] = j;
				}
				value.triangles = array2;
				value.RecalculateNormals();
				value.RecalculateBounds();
				meshes.Add(text2, value);
			}
			GameObject val2 = new GameObject(item.Key);
			val2.transform.SetParent(val.transform, false);
			val2.AddComponent<MeshFilter>().sharedMesh = value;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = Material(item.Key);
		}
		return val;
	}

	public static AudioClip Clip(string name)
	{
		if (audio.TryGetValue(name, out var value))
		{
			return value;
		}
		using (BinaryReader binaryReader = new BinaryReader(Open(name + ".wav")))
		{
			binaryReader.BaseStream.Position = 24L;
			int num = binaryReader.ReadInt32();
			binaryReader.BaseStream.Position = 40L;
			int num2 = binaryReader.ReadInt32();
			float[] array = new float[num2 / 2];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = (float)binaryReader.ReadInt16() / 32768f;
			}
			value = AudioClip.Create("Bazooka_" + name, array.Length, 1, num, false);
			value.SetData(array, 0);
		}
		audio.Add(name, value);
		return value;
	}

	public static void Play(string name, Vector3 position)
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		voices.RemoveAll((AudioSource voice) => !Object.op_Implicit((Object)(object)voice));
		if (voices.Count >= 8)
		{
			Object.Destroy((Object)(object)((Component)voices[0]).gameObject);
			voices.RemoveAt(0);
		}
		GameObject val = new GameObject("Bazooka_Sound");
		val.transform.position = position;
		AudioSource val2 = val.AddComponent<AudioSource>();
		val2.clip = Clip(name);
		val2.spatialBlend = 1f;
		val2.minDistance = 4f;
		val2.maxDistance = 45f;
		val2.rolloffMode = (AudioRolloffMode)1;
		val2.volume = 0.85f;
		val2.dopplerLevel = 0f;
		if (Object.op_Implicit((Object)(object)AudioManager.instance))
		{
			val2.outputAudioMixerGroup = AudioManager.instance.SoundMasterGroup;
		}
		voices.Add(val2);
		val2.Play();
		Object.Destroy((Object)(object)val, val2.clip.length + 0.1f);
	}
}
[DefaultExecutionOrder(-50)]
public sealed class BazookaBehaviour : MonoBehaviour
{
	private static SphereCollider overlapProbe;

	public bool InfiniteAmmo;

	private readonly FireGate gate = new FireGate();

	private readonly Dictionary<int, Rocket> rockets = new Dictionary<int, Rocket>();

	private int sequence;

	internal int ActiveRockets => rockets.Count;

	private void Awake()
	{
		Rigidbody component = ((Component)this).GetComponent<Rigidbody>();
		component.mass = 3.2f;
		((Component)this).GetComponent<PhysGrabObject>().massOriginal = 3.2f;
	}

	public bool AllowShot()
	{
		PhysGrabObject component = ((Component)this).GetComponent<PhysGrabObject>();
		ItemEquippable component2 = ((Component)this).GetComponent<ItemEquippable>();
		ItemBattery component3 = ((Component)this).GetComponent<ItemBattery>();
		return gate.TryFire(Time.time, SemiFunc.IsMasterClientOrSingleplayer(), component.playerGrabbing.Count > 0, Object.op_Implicit((Object)(object)component2) && component2.IsEquipped(), component3.batteryLife, component3.batteryBars);
	}

	public void ReceiveShot()
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: 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_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		if (SemiFunc.IsMasterClientOrSingleplayer())
		{
			ItemGun component = ((Component)this).GetComponent<ItemGun>();
			Transform gunMuzzle = component.gunMuzzle;
			if (!InfiniteAmmo)
			{
				((Component)this).GetComponent<ItemBattery>().RemoveFullBar(1);
			}
			Rigidbody component2 = ((Component)this).GetComponent<Rigidbody>();
			component2.AddForceAtPosition(-gunMuzzle.forward * component.gunRecoilForce, gunMuzzle.position, (ForceMode)1);
			int num = ++sequence;
			if (Plugin.DiagnosticLog.Value)
			{
				Plugin.Log(string.Concat("BAZOOKA_SHOT id=", num, " test=", InfiniteAmmo, " ammo=", ((Component)this).GetComponent<ItemBattery>().batteryLife, " origin=", gunMuzzle.position, " forward=", gunMuzzle.forward));
			}
			if (SemiFunc.IsMultiplayer())
			{
				((Component)this).GetComponent<PhotonView>().RPC("BazookaLaunchRPC", (RpcTarget)0, new object[3] { num, gunMuzzle.position, gunMuzzle.forward });
			}
			else
			{
				BazookaLaunchRPC(num, gunMuzzle.position, gunMuzzle.forward);
			}
			if (FindHit(((Component)this).transform.position, gunMuzzle.position - ((Component)this).transform.position, out var closest))
			{
				Impact(num, ((RaycastHit)(ref closest)).point + ((RaycastHit)(ref closest)).normal * 0.03f, explode: true);
			}
		}
	}

	[PunRPC]
	public void BazookaLaunchRPC(int id, Vector3 position, Vector3 direction, PhotonMessageInfo info = default(PhotonMessageInfo))
	{
		//IL_0000: 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_002d: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		if (SemiFunc.MasterOnlyRPC(info) && !rockets.ContainsKey(id))
		{
			sequence = Math.Max(sequence, id);
			TrackRocket(id, position, direction, SemiFunc.IsMasterClientOrSingleplayer());
			WeaponVfx.Muzzle(position, direction);
			Assets.Play("launch", position);
			if (Object.op_Implicit((Object)(object)Camera.main))
			{
				SemiFunc.CameraShakeImpactDistance(position, 2.5f, 0.1f, 2f, 9f);
			}
		}
	}

	private PlayerAvatar ShotOwner()
	{
		List<PhysGrabber> playerGrabbing = ((Component)this).GetComponent<PhysGrabObject>().playerGrabbing;
		int num = (int)AccessTools.Field(typeof(ItemToggle), "playerTogglePhotonID").GetValue(((Component)this).GetComponent<ItemToggle>());
		foreach (PhysGrabber item in playerGrabbing)
		{
			if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.playerAvatar))
			{
				PhotonView component = ((Component)item.playerAvatar).GetComponent<PhotonView>();
				if (Object.op_Implicit((Object)(object)component) && component.ViewID == num)
				{
					return item.playerAvatar;
				}
			}
		}
		foreach (PhysGrabber item2 in playerGrabbing)
		{
			if (Object.op_Implicit((Object)(object)item2) && Object.op_Implicit((Object)(object)item2.playerAvatar))
			{
				return item2.playerAvatar;
			}
		}
		return null;
	}

	internal Rocket TrackRocket(int id, Vector3 position, Vector3 direction, bool authority)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		Rocket rocket = Rocket.Create(this, id, position, direction, authority);
		rocket.Shooter = (authority ? ShotOwner() : null);
		rockets[id] = rocket;
		return rocket;
	}

	public bool FindHit(Vector3 start, Vector3 travel, out RaycastHit closest)
	{
		//IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: 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)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		closest = default(RaycastHit);
		float num = float.PositiveInfinity;
		bool flag = false;
		RaycastHit[] array = Physics.SphereCastAll(start, 0.06f, ((Vector3)(ref travel)).normalized, ((Vector3)(ref travel)).magnitude, -1, (QueryTriggerInteraction)1);
		for (int i = 0; i < array.Length; i++)
		{
			RaycastHit val = array[i];
			if (IgnoreCollider(((RaycastHit)(ref val)).collider) || !(((RaycastHit)(ref val)).distance < num))
			{
				continue;
			}
			closest = val;
			num = ((RaycastHit)(ref val)).distance;
			flag = true;
			if (((RaycastHit)(ref val)).distance <= 0.0001f)
			{
				if (Plugin.DiagnosticLog.Value)
				{
					Plugin.Log(string.Concat("BAZOOKA_INITIAL_OVERLAP collider=", ((Object)((RaycastHit)(ref val)).collider).name, " raw=", ((RaycastHit)(ref val)).point, " start=", start));
				}
				ContactAtOverlap(((RaycastHit)(ref val)).collider, start, travel, out var point, out var normal);
				((RaycastHit)(ref closest)).point = point;
				((RaycastHit)(ref closest)).normal = normal;
			}
		}
		if (!flag)
		{
			Collider[] array2 = Physics.OverlapSphere(start, 0.055f, -1, (QueryTriggerInteraction)1);
			foreach (Collider collider in array2)
			{
				if (!IgnoreCollider(collider))
				{
					ContactAtOverlap(collider, start, travel, out var point2, out var normal2);
					((RaycastHit)(ref closest)).point = point2;
					((RaycastHit)(ref closest)).normal = normal2;
					flag = true;
					break;
				}
			}
		}
		return flag;
	}

	private bool IgnoreCollider(Collider collider)
	{
		if (((Component)collider).transform.IsChildOf(((Component)this).transform))
		{
			return true;
		}
		PlayerAvatar componentInParent = ((Component)collider).GetComponentInParent<PlayerAvatar>();
		PlayerController componentInParent2 = ((Component)collider).GetComponentInParent<PlayerController>();
		foreach (PhysGrabber item in ((Component)this).GetComponent<PhysGrabObject>().playerGrabbing)
		{
			if (Object.op_Implicit((Object)(object)item) && ((Object.op_Implicit((Object)(object)componentInParent) && (Object)(object)item.playerAvatar == (Object)(object)componentInParent) || (Object.op_Implicit((Object)(object)componentInParent2) && item.isLocal && (Object)(object)componentInParent2 == (Object)(object)PlayerController.instance) || (Object)(object)((Component)collider).GetComponentInParent<PhysGrabber>() == (Object)(object)item))
			{
				return true;
			}
		}
		return false;
	}

	private static void ContactAtOverlap(Collider collider, Vector3 start, Vector3 travel, out Vector3 point, out Vector3 normal)
	{
		//IL_0047: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected O, but got Unknown
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)overlapProbe))
		{
			GameObject val = new GameObject("Bazooka_QuerySphere");
			Object.DontDestroyOnLoad((Object)(object)val);
			overlapProbe = val.AddComponent<SphereCollider>();
			overlapProbe.radius = 0.06f;
			((Collider)overlapProbe).enabled = false;
		}
		float num = default(float);
		if (Physics.ComputePenetration((Collider)(object)overlapProbe, start, Quaternion.identity, collider, ((Component)collider).transform.position, ((Component)collider).transform.rotation, ref normal, ref num))
		{
			point = start + normal * Mathf.Max(0f, num - 0.06f);
			return;
		}
		point = collider.ClosestPoint(start);
		Vector3 val2 = start - point;
		Vector3 val3;
		if (!(((Vector3)(ref val2)).sqrMagnitude > 1E-06f))
		{
			val3 = -((Vector3)(ref travel)).normalized;
		}
		else
		{
			Vector3 val4 = start - point;
			val3 = ((Vector3)(ref val4)).normalized;
		}
		normal = val3;
	}

	public void Impact(int id, Vector3 position, bool explode)
	{
		//IL_0036: 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_00bf: 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_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: 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)
		if (SemiFunc.IsMasterClientOrSingleplayer() && rockets.TryGetValue(id, out var value) && Object.op_Implicit((Object)(object)value) && !value.Resolved)
		{
			value.Resolved = true;
			int num = (explode ? BlastDamage.Apply(position, ((Component)this).transform) : 0);
			int num2 = (explode ? PlayerBlastDamage.Apply(position, ((Component)this).transform, value.Shooter) : 0);
			if (Plugin.DiagnosticLog.Value)
			{
				Plugin.Log("BAZOOKA_IMPACT id=" + id + " exploded=" + explode + " enemies=" + num + " players=" + num2 + " position=" + position);
			}
			if (SemiFunc.IsMultiplayer())
			{
				((Component)this).GetComponent<PhotonView>().RPC("BazookaImpactRPC", (RpcTarget)0, new object[3] { id, position, explode });
			}
			else
			{
				BazookaImpactRPC(id, position, explode);
			}
		}
	}

	[PunRPC]
	public void BazookaImpactRPC(int id, Vector3 position, bool explode, PhotonMessageInfo info = default(PhotonMessageInfo))
	{
		//IL_0000: 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)
		if (SemiFunc.MasterOnlyRPC(info) && rockets.TryGetValue(id, out var value))
		{
			if (Object.op_Implicit((Object)(object)value))
			{
				((Component)value).GetComponent<RocketTrail>().Release();
				Object.Destroy((Object)(object)((Component)value).gameObject);
			}
			rockets.Remove(id);
			if (explode)
			{
				Effects.Blast(position);
			}
		}
	}

	public void Forget(int id)
	{
		rockets.Remove(id);
	}

	private void OnDestroy()
	{
		foreach (Rocket value in rockets.Values)
		{
			if (Object.op_Implicit((Object)(object)value))
			{
				Object.Destroy((Object)(object)((Component)value).gameObject);
			}
		}
		rockets.Clear();
	}
}
public sealed class Rocket : MonoBehaviour
{
	public const float Speed = 18f;

	public const float Lifetime = 4f;

	public BazookaBehaviour Owner;

	public int Shot;

	public bool Authority;

	public bool Resolved;

	public PlayerAvatar Shooter;

	private Vector3 velocity;

	private float age;

	private bool finished;

	public static Rocket Create(BazookaBehaviour owner, int shot, Vector3 position, Vector3 direction, bool authority)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0011: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("ChubbyBazooka_Rocket");
		val.transform.SetPositionAndRotation(position, Quaternion.LookRotation(direction));
		Assets.Model("rocket", val.transform).transform.localScale = Vector3.one * 1.4f;
		val.AddComponent<RocketTrail>();
		Rocket rocket = val.AddComponent<Rocket>();
		rocket.Owner = owner;
		rocket.Shot = shot;
		rocket.Authority = authority;
		rocket.velocity = ((Vector3)(ref direction)).normalized * 18f;
		return rocket;
	}

	private void FixedUpdate()
	{
		Step(Time.fixedDeltaTime);
	}

	public void Step(float dt)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: 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_0101: Unknown result type (might be due to invalid IL or missing references)
		if (finished || dt <= 0f)
		{
			return;
		}
		if (!Object.op_Implicit((Object)(object)Owner))
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		age += dt;
		Vector3 val = velocity * dt;
		if (Authority && SemiFunc.IsMasterClientOrSingleplayer() && Owner.FindHit(((Component)this).transform.position, val, out var closest))
		{
			finished = true;
			Owner.Impact(Shot, ((RaycastHit)(ref closest)).point + ((RaycastHit)(ref closest)).normal * 0.03f, explode: true);
			return;
		}
		Transform transform = ((Component)this).transform;
		transform.position += val;
		if (age >= (Authority ? 4f : 5f))
		{
			finished = true;
			if (Authority && SemiFunc.IsMasterClientOrSingleplayer())
			{
				Owner.Impact(Shot, ((Component)this).transform.position, explode: false);
				return;
			}
			Owner.Forget(Shot);
			((Component)this).GetComponent<RocketTrail>().Release();
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
}
public static class BlastDamage
{
	private sealed class Target
	{
		public EnemyHealth Health;

		public Vector3 Point;

		public float Distance = float.PositiveInfinity;
	}

	public static EnemyHealth Resolve(Collider collider)
	{
		if (Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<EnemyBombThrowerHead>()))
		{
			return null;
		}
		EnemyHealth componentInParent = ((Component)collider).GetComponentInParent<EnemyHealth>();
		if (Object.op_Implicit((Object)(object)componentInParent))
		{
			return componentInParent;
		}
		EnemyRigidbody componentInParent2 = ((Component)collider).GetComponentInParent<EnemyRigidbody>();
		if (Object.op_Implicit((Object)(object)componentInParent2) && Object.op_Implicit((Object)(object)componentInParent2.enemy))
		{
			return ((Component)componentInParent2.enemy).GetComponent<EnemyHealth>();
		}
		EnemyParent componentInParent3 = ((Component)collider).GetComponentInParent<EnemyParent>();
		if (!Object.op_Implicit((Object)(object)componentInParent3))
		{
			return null;
		}
		return ((Component)componentInParent3).GetComponentInChildren<EnemyHealth>();
	}

	public static int Calculate(float distance, float radius, int maximum, bool falloff, float minimum)
	{
		if (float.IsNaN(distance) || float.IsInfinity(distance) || float.IsNaN(radius) || radius <= 0f || distance < 0f || distance >= radius || maximum <= 0)
		{
			return 0;
		}
		float num = (falloff ? Mathf.Lerp(1f, Mathf.Clamp01(minimum), distance / radius) : 1f);
		return Mathf.Max(0, Mathf.RoundToInt((float)maximum * num));
	}

	public static int Apply(Vector3 centre, Transform launcher)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: 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_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			return 0;
		}
		float value = Plugin.BlastRadius.Value;
		int num = 0;
		Dictionary<EnemyHealth, Target> dictionary = new Dictionary<EnemyHealth, Target>();
		Collider[] array = Physics.OverlapSphere(centre, value, -1, (QueryTriggerInteraction)2);
		foreach (Collider val in array)
		{
			EnemyHealth val2 = Resolve(val);
			if (!Object.op_Implicit((Object)(object)val2) || !((Behaviour)val2).enabled || !((Component)val2).gameObject.activeInHierarchy)
			{
				continue;
			}
			Vector3 val3 = val.ClosestPoint(centre);
			float num2 = Vector3.Distance(centre, val3);
			if (!Plugin.BlastLineOfSight.Value || Visible(centre, val3, val2, launcher))
			{
				if (!dictionary.TryGetValue(val2, out var value2))
				{
					Target target = new Target();
					target.Health = val2;
					value2 = target;
					dictionary.Add(val2, value2);
				}
				if (num2 < value2.Distance)
				{
					value2.Distance = num2;
					value2.Point = val3;
				}
			}
		}
		foreach (Target value3 in dictionary.Values)
		{
			int num3 = Calculate(value3.Distance, value, Plugin.BlastMaxDamage.Value, Plugin.DamageFalloff.Value, Plugin.MinimumDamageFraction.Value);
			if (num3 > 0)
			{
				Vector3 val4 = value3.Point - centre;
				Vector3 val5 = ((Vector3)(ref val4)).normalized;
				if (val5 == Vector3.zero)
				{
					val5 = Vector3.up;
				}
				value3.Health.Hurt(num3, val5);
				num++;
				if (Plugin.DiagnosticLog.Value)
				{
					Plugin.Log("BAZOOKA_ENEMY_DAMAGE target=" + ((Object)value3.Health).name + " requested=" + num3 + " distance=" + value3.Distance.ToString("F2"));
				}
			}
		}
		return num;
	}

	private static bool Visible(Vector3 centre, Vector3 point, EnemyHealth target, Transform launcher)
	{
		//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_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = point - centre;
		if (((Vector3)(ref val)).sqrMagnitude < 0.0025f)
		{
			return true;
		}
		RaycastHit[] array = Physics.RaycastAll(centre, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1);
		for (int i = 0; i < array.Length; i++)
		{
			RaycastHit val2 = array[i];
			if ((!Object.op_Implicit((Object)(object)launcher) || !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(launcher)) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerAvatar>()) && !Object.op_Implicit((Object)(object)Resolve(((RaycastHit)(ref val2)).collider)))
			{
				return false;
			}
		}
		return true;
	}
}
public sealed class FireGate
{
	public const double Cooldown = 2.0;

	private double next = double.NegativeInfinity;

	public bool TryFire(double now, bool authority, bool held, bool equipped, float battery, int capacity = 6)
	{
		if (double.IsNaN(now) || double.IsInfinity(now) || float.IsNaN(battery) || float.IsInfinity(battery) || !authority || !held || equipped || capacity < 1 || battery + 0.01f < 100f / (float)capacity || now < next)
		{
			return false;
		}
		next = now + 2.0;
		return true;
	}
}
public static class PlayerBlastDamage
{
	private sealed class Target
	{
		public PlayerAvatar Avatar;

		public float Distance = float.PositiveInfinity;
	}

	private static readonly FieldInfo disabled = AccessTools.Field(typeof(PlayerAvatar), "isDisabled");

	private static readonly FieldInfo dead = AccessTools.Field(typeof(PlayerAvatar), "deadSet");

	public static PlayerAvatar Resolve(Collider collider)
	{
		PlayerAvatar componentInParent = ((Component)collider).GetComponentInParent<PlayerAvatar>();
		if (Object.op_Implicit((Object)(object)componentInParent))
		{
			return componentInParent;
		}
		PlayerTumble componentInParent2 = ((Component)collider).GetComponentInParent<PlayerTumble>();
		if (Object.op_Implicit((Object)(object)componentInParent2))
		{
			return componentInParent2.playerAvatar;
		}
		PlayerController componentInParent3 = ((Component)collider).GetComponentInParent<PlayerController>();
		if (!Object.op_Implicit((Object)(object)componentInParent3))
		{
			return null;
		}
		return componentInParent3.playerAvatarScript;
	}

	public static int Calculate(float distance, float radius, int maximum)
	{
		return BlastDamage.Calculate(distance, radius, maximum, falloff: true, 0f);
	}

	public static int Apply(Vector3 centre, Transform launcher, PlayerAvatar shooter)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer() || !Plugin.EnableFriendlyFire.Value)
		{
			return 0;
		}
		if (!Object.op_Implicit((Object)(object)shooter) && !Plugin.AllowSelfDamage.Value)
		{
			return 0;
		}
		float value = Plugin.PlayerDamageRadius.Value;
		int num = 0;
		Dictionary<PlayerAvatar, Target> dictionary = new Dictionary<PlayerAvatar, Target>();
		Collider[] array = Physics.OverlapSphere(centre, value, -1, (QueryTriggerInteraction)2);
		foreach (Collider val in array)
		{
			if (Object.op_Implicit((Object)(object)launcher) && ((Component)val).transform.IsChildOf(launcher))
			{
				continue;
			}
			PlayerAvatar val2 = Resolve(val);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.playerHealth) || !((Component)val2).gameObject.activeInHierarchy || (bool)disabled.GetValue(val2) || (bool)dead.GetValue(val2) || ((Object)(object)val2 == (Object)(object)shooter && !Plugin.AllowSelfDamage.Value))
			{
				continue;
			}
			Vector3 val3 = val.ClosestPoint(centre);
			float num2 = Vector3.Distance(centre, val3);
			if (Visible(centre, val3, launcher))
			{
				if (!dictionary.TryGetValue(val2, out var value2))
				{
					Target target = new Target();
					target.Avatar = val2;
					value2 = target;
					dictionary.Add(val2, value2);
				}
				if (num2 < value2.Distance)
				{
					value2.Distance = num2;
				}
			}
		}
		foreach (Target value3 in dictionary.Values)
		{
			int num3 = Calculate(value3.Distance, value, Plugin.PlayerMaxDamage.Value);
			if (num3 > 0)
			{
				value3.Avatar.playerHealth.HurtOther(num3, ((Component)value3.Avatar).transform.position, false, -1, false);
				num++;
				if (Plugin.DiagnosticLog.Value)
				{
					Plugin.Log("BAZOOKA_PLAYER_DAMAGE target=" + ((Object)value3.Avatar).name + " requested=" + num3 + " distance=" + value3.Distance.ToString("F2") + " native_owner_dispatch=true");
				}
			}
		}
		return num;
	}

	private static bool Visible(Vector3 centre, Vector3 point, Transform launcher)
	{
		//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_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = point - centre;
		if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
		{
			return true;
		}
		RaycastHit[] array = Physics.RaycastAll(centre, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1);
		for (int i = 0; i < array.Length; i++)
		{
			RaycastHit val2 = array[i];
			if ((!Object.op_Implicit((Object)(object)launcher) || !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(launcher)) && !Object.op_Implicit((Object)(object)Resolve(((RaycastHit)(ref val2)).collider)) && !Object.op_Implicit((Object)(object)BlastDamage.Resolve(((RaycastHit)(ref val2)).collider)))
			{
				return false;
			}
		}
		return true;
	}
}
public static class PlayerDamageChecks
{
	private static readonly Dictionary<PlayerHealth, int> requests = new Dictionary<PlayerHealth, int>();

	private static int calls;

	private static bool Skip()
	{
		return false;
	}

	private static bool Dispatch(PlayerHealth __instance, int damage, Vector3 hurtPosition)
	{
		//IL_0018: 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)
		requests[__instance] = damage;
		calls++;
		if (hurtPosition != ((Component)__instance).transform.position)
		{
			throw new Exception("Player RPC must receive target-position snapshot");
		}
		return false;
	}

	private static bool Deny(ref bool __result)
	{
		__result = false;
		return false;
	}

	public static void Run(Action<bool, string> check, Harmony harmony, BazookaBehaviour launcher)
	{
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Expected O, but got Unknown
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Expected O, but got Unknown
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Expected O, but got Unknown
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Expected O, but got Unknown
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Expected O, but got Unknown
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_0311: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0369: Unknown result type (might be due to invalid IL or missing references)
		//IL_036e: Unknown result type (might be due to invalid IL or missing references)
		//IL_038e: Unknown result type (might be due to invalid IL or missing references)
		//IL_039e: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0404: Unknown result type (might be due to invalid IL or missing references)
		//IL_0406: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0430: Unknown result type (might be due to invalid IL or missing references)
		//IL_0488: Unknown result type (might be due to invalid IL or missing references)
		//IL_0496: Expected O, but got Unknown
		//IL_049f: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f6: Expected O, but got Unknown
		check(!Plugin.EnableFriendlyFire.Value && !Plugin.AllowSelfDamage.Value, "Friendly fire and self damage default OFF");
		check(Plugin.PlayerMaxDamage.Value == 60 && Plugin.PlayerDamageRadius.Value == 3f, "Host player damage defaults: 60 HP / 3 m");
		check(PlayerBlastDamage.Calculate(0f, 3f, 60) == 60 && PlayerBlastDamage.Calculate(1.5f, 3f, 60) == 30, "Player damage falls linearly from 60 to 30 at half radius");
		check(PlayerBlastDamage.Calculate(3f, 3f, 60) == 0 && PlayerBlastDamage.Calculate(float.NaN, 3f, 60) == 0, "Player radius edge and invalid distance dispatch no damage");
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PlayerDamageChecks), "Skip", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerHealth), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PlayerDamageChecks), "Skip", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerHealth), "HurtOther", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PlayerDamageChecks), "Dispatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		GameObject val = new GameObject("PlayerDispatchFixture");
		val.SetActive(false);
		val.transform.position = new Vector3(500f, 500f, 500f);
		PlayerAvatar val2 = val.AddComponent<PlayerAvatar>();
		val2.playerHealth = val.AddComponent<PlayerHealth>();
		SphereCollider val3 = val.AddComponent<SphereCollider>();
		val3.radius = 0.2f;
		GameObject val4 = new GameObject("SecondPlayerCollider");
		val4.transform.SetParent(val.transform, false);
		val4.AddComponent<SphereCollider>().radius = 0.1f;
		val.SetActive(true);
		Physics.SyncTransforms();
		Vector3 val5 = val.transform.position - Vector3.right;
		check((Object)(object)PlayerBlastDamage.Resolve((Collider)(object)val3) == (Object)(object)val2, "Avatar collider resolves to native player identity");
		GameObject val6 = new GameObject("ShooterFixture");
		val6.SetActive(false);
		PlayerAvatar shooter = val6.AddComponent<PlayerAvatar>();
		calls = 0;
		requests.Clear();
		check(PlayerBlastDamage.Apply(val5, ((Component)launcher).transform, shooter) == 0 && calls == 0, "Disabled friendly fire dispatches no player health calls");
		Plugin.EnableFriendlyFire.Value = true;
		check(PlayerBlastDamage.Apply(val5, ((Component)launcher).transform, null) == 0, "Missing shooter identity fails closed when self damage is disabled");
		check(PlayerBlastDamage.Apply(val5, ((Component)launcher).transform, shooter) == 1 && calls == 1 && requests[val2.playerHealth] == 44, "Two player colliders dispatch once, with falloff and target-position snapshot");
		int num = calls;
		check(PlayerBlastDamage.Apply(val5, ((Component)launcher).transform, val2) == 0 && calls == num, "Firing player excluded while self damage is OFF");
		Plugin.AllowSelfDamage.Value = true;
		check(PlayerBlastDamage.Apply(val5, ((Component)launcher).transform, val2) == 1 && calls == num + 1, "Self damage can be explicitly enabled by host");
		Plugin.AllowSelfDamage.Value = false;
		GameObject val7 = GameObject.CreatePrimitive((PrimitiveType)3);
		val7.transform.position = val.transform.position - Vector3.right * 0.5f;
		val7.transform.localScale = new Vector3(0.1f, 2f, 2f);
		Physics.SyncTransforms();
		check(PlayerBlastDamage.Apply(val5, ((Component)launcher).transform, shooter) == 0, "World cover blocks player blast even when enemy LOS config is disabled");
		Object.DestroyImmediate((Object)(object)val7);
		Physics.SyncTransforms();
		check(PlayerBlastDamage.Apply(val5 - Vector3.right * 10f, ((Component)launcher).transform, shooter) == 0, "Player outside configured radius receives no request");
		num = calls;
		Rocket rocket = launcher.TrackRocket(7001, val5, Vector3.right, authority: true);
		rocket.Shooter = shooter;
		launcher.Impact(7001, val5, explode: true);
		launcher.Impact(7001, val5, explode: true);
		check(calls == num + 1, "Duplicate rocket impact dispatches player damage only once");
		MethodInfo methodInfo = AccessTools.Method(typeof(SemiFunc), "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null);
		harmony.Unpatch((MethodBase)methodInfo, (HarmonyPatchType)1, harmony.Id);
		harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PlayerDamageChecks), "Deny", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		num = calls;
		check(PlayerBlastDamage.Apply(val5, ((Component)launcher).transform, shooter) == 0 && calls == num, "Non-host cannot calculate or dispatch player damage regardless of config");
		harmony.Unpatch((MethodBase)methodInfo, (HarmonyPatchType)1, harmony.Id);
		harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(RuntimeChecks), "True", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		Plugin.EnableFriendlyFire.Value = false;
		Plugin.AllowSelfDamage.Value = false;
		harmony.Unpatch((MethodBase)AccessTools.Method(typeof(PlayerHealth), "HurtOther", (Type[])null, (Type[])null), (HarmonyPatchType)1, harmony.Id);
		Object.DestroyImmediate((Object)(object)val);
		Object.DestroyImmediate((Object)(object)val6);
	}
}
[BepInPlugin("berat.repo.chubbybazooka", "Chubby Bazooka", "0.3.0")]
[BepInDependency("REPOLib", "4.2.0")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string Id = "berat.repo.chubbybazooka";

	public static Plugin Instance;

	public static bool SelfTest;

	private ConfigEntry<bool> spawnEnabled;

	private ConfigEntry<KeyCode> spawnKey;

	private float nextSpawn;

	public static ConfigEntry<int> ShopPrice;

	public static ConfigEntry<int> StartingAmmo;

	public static ConfigEntry<float> SpawnCooldown;

	public static ConfigEntry<float> BlastRadius;

	public static ConfigEntry<int> BlastMaxDamage;

	public static ConfigEntry<bool> DamageFalloff;

	public static ConfigEntry<float> MinimumDamageFraction;

	public static ConfigEntry<bool> BlastLineOfSight;

	public static ConfigEntry<bool> DiagnosticLog;

	public static ConfigEntry<bool> EnableFriendlyFire;

	public static ConfigEntry<bool> AllowSelfDamage;

	public static ConfigEntry<int> PlayerMaxDamage;

	public static ConfigEntry<float> PlayerDamageRadius;

	private void Awake()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Expected O, but got Unknown
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Expected O, but got Unknown
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Expected O, but got Unknown
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Expected O, but got Unknown
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Expected O, but got Unknown
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Expected O, but got Unknown
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		SelfTest = Array.IndexOf(Environment.GetCommandLineArgs(), "--bazooka-selftest") >= 0;
		ShopPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "Price", 5000, new ConfigDescription("Starting price in dollars; vanilla shop rounds UP to thousands. Host config; restart after changing.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1000, 100000), new object[0]));
		StartingAmmo = ((BaseUnityPlugin)this).Config.Bind<int>("Ammo", "StartingRockets", 6, new ConfigDescription("Normal bazooka capacity/starting rockets. Native charging station refills it. Host config is synchronized per item; restart after changing.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), new object[0]));
		spawnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "EnableInfiniteAmmoSpawn", false, "Enable F7 infinite-ammo TEST bazooka spawning. Host/singleplayer only; missions and truck lobby.");
		spawnKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Testing", "InfiniteAmmoSpawnKey", (KeyCode)288, "Test spawn key. Old V0.2 F6 settings do not enable this feature.");
		SpawnCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Testing", "SpawnCooldownSeconds", 3f, new ConfigDescription("Minimum time between TEST bazooka spawns.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[0]));
		BlastRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "Radius", 3f, new ConfigDescription("Enemy blast radius in metres. Host configuration is authoritative.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), new object[0]));
		BlastMaxDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Damage", "MaxDamage", 120, new ConfigDescription("Enemy damage at the centre; vanilla resistance still applies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), new object[0]));
		DamageFalloff = ((BaseUnityPlugin)this).Config.Bind<bool>("Damage", "DistanceFalloff", true, "Reduce enemy damage linearly with distance.");
		MinimumDamageFraction = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "MinimumDamageFraction", 0.25f, new ConfigDescription("Damage fraction at the edge when falloff is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
		BlastLineOfSight = ((BaseUnityPlugin)this).Config.Bind<bool>("Damage", "RequireLineOfSight", true, "World geometry and physical objects block blast damage.");
		EnableFriendlyFire = ((BaseUnityPlugin)this).Config.Bind<bool>("FriendlyFire", "EnableFriendlyFire", false, "Allow bazooka blasts to damage players. Only the host setting is used.");
		AllowSelfDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("FriendlyFire", "AllowSelfDamage", false, "Allow the firing player to take blast damage. Host only.");
		PlayerMaxDamage = ((BaseUnityPlugin)this).Config.Bind<int>("FriendlyFire", "PlayerMaxDamage", 60, new ConfigDescription("Player damage at centre, falling linearly to zero at radius. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), new object[0]));
		PlayerDamageRadius = ((BaseUnityPlugin)this).Config.Bind<float>("FriendlyFire", "PlayerDamageRadius", 3f, new ConfigDescription("Player blast radius in metres; world cover always blocks it. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), new object[0]));
		DiagnosticLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "DiagnosticLog", false, "Log launches, impacts and enemy damage for testing.");
		new Harmony("berat.repo.chubbybazooka").PatchAll(typeof(Plugin).Assembly);
		try
		{
			if (SelfTest)
			{
				PrefabFactory.Register();
				RuntimeChecks.Run();
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Bazooka 0.3.0 ready; waiting for the real RunManager scene before constructing persistent prefabs.");
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)ex);
			if (SelfTest)
			{
				RuntimeChecks.Fail(ex);
				Environment.Exit(1);
			}
		}
		if (SelfTest)
		{
			Environment.Exit(0);
		}
	}

	public void HandleInput()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		if (!SelfTest && spawnEnabled.Value && Input.GetKeyDown(spawnKey.Value))
		{
			TrySpawnTest();
		}
	}

	public bool TrySpawnTest()
	{
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		if (!spawnEnabled.Value)
		{
			return false;
		}
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"F7 test spawn refused: only the host can spawn this item.");
			return false;
		}
		if (!Object.op_Implicit((Object)(object)RunManager.instance) || !Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated || (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsLobby()) || !SemiFunc.NoTextInputsActive() || Time.unscaledTime < nextSpawn)
		{
			return false;
		}
		if (!Object.op_Implicit((Object)(object)PlayerAvatar.instance) || !Object.op_Implicit((Object)(object)Camera.main) || (Object)(object)PrefabFactory.TestItem == (Object)null)
		{
			return false;
		}
		nextSpawn = Time.unscaledTime + SpawnCooldown.Value;
		Vector3 val = ((Component)Camera.main).transform.position + ((Component)Camera.main).transform.forward * 1.4f;
		GameObject val2 = Items.SpawnItem(PrefabFactory.TestItem, val, Quaternion.LookRotation(((Component)Camera.main).transform.forward, Vector3.up));
		((BaseUnityPlugin)this).Logger.LogInfo((object)(Object.op_Implicit((Object)(object)val2) ? "BAZOOKA_TEST_SPAWN: infinite ammo; host spawned one TEST bazooka." : "Bazooka test spawn failed; inspect REPOLib log."));
		return Object.op_Implicit((Object)(object)val2);
	}

	public static void Log(string value)
	{
		((BaseUnityPlugin)Instance).Logger.LogInfo((object)value);
	}
}
[HarmonyPatch(typeof(RunManager), "Awake")]
internal static class GameRuntimeReady
{
	[HarmonyPostfix]
	private static void Postfix()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		if (!Plugin.SelfTest && !Object.op_Implicit((Object)(object)BazookaRuntime.Instance))
		{
			GameObject val = new GameObject("ChubbyBazooka_Runtime");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<BazookaRuntime>();
			PrefabFactory.Register();
		}
	}
}
public sealed class BazookaRuntime : MonoBehaviour
{
	public static BazookaRuntime Instance;

	private void Awake()
	{
		Instance = this;
	}

	private void Update()
	{
		Plugin.Instance.HandleInput();
	}
}
[HarmonyPatch(typeof(ItemToggle), "ToggleItemRPC")]
internal static class HeldInteractionPermission
{
	[HarmonyPrefix]
	private static bool Prefix(ItemToggle __instance, int player, PhotonMessageInfo _info)
	{
		if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<BazookaBehaviour>()) || !SemiFunc.IsMultiplayer() || !SemiFunc.IsMasterClientOrSingleplayer())
		{
			return true;
		}
		if (_info.Sender == null)
		{
			return false;
		}
		PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>();
		foreach (PhysGrabber item in component.playerGrabbing)
		{
			if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.playerAvatar))
			{
				PhotonView component2 = ((Component)item.playerAvatar).GetComponent<PhotonView>();
				if (Object.op_Implicit((Object)(object)component2) && component2.ViewID == player && component2.OwnerActorNr == _info.Sender.ActorNumber)
				{
					return true;
				}
			}
		}
		return false;
	}
}
[HarmonyPatch(typeof(StatsManager), "RunStartStats")]
internal static class StatsRegistration
{
	[HarmonyPrefix]
	private static void Prefix()
	{
		PrefabFactory.Register();
	}

	[HarmonyPostfix]
	[HarmonyPriority(0)]
	private static void Postfix(StatsManager __instance)
	{
		if (Object.op_Implicit((Object)(object)PrefabFactory.Item) && __instance.itemDictionary.ContainsKey(((Object)PrefabFactory.Item).name))
		{
			Plugin.Log("BAZOOKA_STATS_REGISTERED: " + ((Object)PrefabFactory.Item).name);
		}
	}
}
[HarmonyPatch(typeof(ItemGun), "Shoot")]
internal static class FirePermission
{
	[HarmonyPrefix]
	private static bool Prefix(ItemGun __instance, ref bool __result)
	{
		BazookaBehaviour component = ((Component)__instance).GetComponent<BazookaBehaviour>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			return true;
		}
		if (component.AllowShot())
		{
			return true;
		}
		__result = false;
		return false;
	}
}
[HarmonyPatch(typeof(ItemGun), "ShootRPC")]
internal static class RocketInsteadOfBullet
{
	[HarmonyPrefix]
	private static bool Prefix(ItemGun __instance, PhotonMessageInfo _info)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		BazookaBehaviour component = ((Component)__instance).GetComponent<BazookaBehaviour>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			return true;
		}
		if (SemiFunc.MasterOnlyRPC(_info) && SemiFunc.IsMasterClientOrSingleplayer())
		{
			component.ReceiveShot();
		}
		return false;
	}
}
public static class PrefabFactory
{
	public const string ItemId = "Item Chubby Bazooka V01";

	public const string TestItemId = "Item Chubby Bazooka TEST V021";

	public static Item Item;

	public static Item TestItem;

	public static GameObject TestPrefab;

	public static GameObject Prefab;

	public static GameObject Storage;

	public static void Register()
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_036b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_040d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0471: Unknown result type (might be due to invalid IL or missing references)
		//IL_0496: Unknown result type (might be due to invalid IL or missing references)
		//IL_0434: Unknown result type (might be due to invalid IL or missing references)
		//IL_0439: Unknown result type (might be due to invalid IL or missing references)
		//IL_0445: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)Prefab))
		{
			return;
		}
		GameObject val = Resources.Load<GameObject>("items/items/Item Gun Handgun");
		if (!Object.op_Implicit((Object)(object)val))
		{
			val = Resources.Load<GameObject>("items/Item Gun Handgun");
		}
		ItemAttributes val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemAttributes>() : null);
		Item val3 = (Object.op_Implicit((Object)(object)val2) ? val2.item : null);
		if (!Object.op_Implicit((Object)(object)val3) || val3.prefab == null)
		{
			throw new InvalidOperationException("Supported vanilla handgun prefab/item was not found. Bazooka disabled.");
		}
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ItemGun>()) || !Object.op_Implicit((Object)(object)val.GetComponent<PhysGrabObject>()) || !Object.op_Implicit((Object)(object)val.GetComponent<ItemBattery>()))
		{
			throw new InvalidOperationException("Vanilla handgun prefab layout changed. Bazooka disabled.");
		}
		Storage = new GameObject("ChubbyBazooka_PrefabStorage");
		Storage.SetActive(false);
		Object.DontDestroyOnLoad((Object)(object)Storage);
		Prefab = Object.Instantiate<GameObject>(val, Storage.transform, false);
		((Object)Prefab).name = "Item Chubby Bazooka V01";
		Prefab.SetActive(true);
		Item = Object.Instantiate<Item>(val3);
		((Object)Item).name = "Item Chubby Bazooka V01";
		Item.itemName = "Chubby Bazooka";
		Item.itemNameLocalized = null;
		Item.description = "Short tube. Big noise. Limited rechargeable rockets. Explosions damage enemies.";
		Item.disabled = false;
		Item.maxAmount = 2;
		Item.maxAmountInShop = 1;
		Item.maxPurchase = true;
		Item.maxPurchaseAmount = 2;
		Item.value = ScriptableObject.CreateInstance<Value>();
		((Object)Item.value).name = "ChubbyBazookaValue";
		Item.value.valueMin = (float)Plugin.ShopPrice.Value / 4f;
		Item.value.valueMax = Item.value.valueMin;
		Item.itemVolume = (itemVolume)2;
		Item.itemSecretShopType = (itemSecretShopType)0;
		ItemAttributes component = Prefab.GetComponent<ItemAttributes>();
		component.item = Item;
		component.costOffset = new Vector3(0f, 0.4f, 0f);
		component.icon = Assets.ItemIcon();
		Prefab.GetComponent<ItemEquippable>().ItemIcon = component.icon;
		MeshRenderer[] componentsInChildren = Prefab.GetComponentsInChildren<MeshRenderer>(true);
		foreach (MeshRenderer val4 in componentsInChildren)
		{
			((Renderer)val4).enabled = false;
		}
		SkinnedMeshRenderer[] componentsInChildren2 = Prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val5 in componentsInChildren2)
		{
			((Renderer)val5).enabled = false;
		}
		Collider[] componentsInChildren3 = Prefab.GetComponentsInChildren<Collider>(true);
		foreach (Collider val6 in componentsInChildren3)
		{
			if (!val6.isTrigger)
			{
				Object.DestroyImmediate((Object)(object)val6);
			}
		}
		PhysGrabObjectCollider[] componentsInChildren4 = Prefab.GetComponentsInChildren<PhysGrabObjectCollider>(true);
		foreach (PhysGrabObjectCollider val7 in componentsInChildren4)
		{
			Object.DestroyImmediate((Object)(object)val7);
		}
		Assets.Model("bazooka", Prefab.transform);
		Collider("BodyCollider", new Vector3(0f, 0f, 0.085f), new Vector3(0.42f, 0.42f, 1.11f));
		Collider("GripCollider", new Vector3(0f, -0.34f, -0.14f), new Vector3(0.15f, 0.32f, 0.2f));
		Transform val8 = Prefab.transform.Find("Force Grab Point");
		if (!Object.op_Implicit((Object)(object)val8))
		{
			val8 = Anchor("Force Grab Point", Vector3.zero);
		}
		val8.localPosition = new Vector3(0f, -0.28f, -0.17f);
		val8.localRotation = Quaternion.identity;
		Transform val9 = Prefab.transform.Find("Center of Mass");
		if (!Object.op_Implicit((Object)(object)val9))
		{
			val9 = Anchor("Center of Mass", Vector3.zero);
		}
		val9.localPosition = new Vector3(0f, -0.035f, 0f);
		ItemVolume componentInChildren = Prefab.GetComponentInChildren<ItemVolume>(true);
		if (Object.op_Implicit((Object)(object)componentInChildren))
		{
			componentInChildren.itemVolume = Item.itemVolume;
			((Component)componentInChildren).transform.localPosition = Vector3.zero;
		}
		ItemGun component2 = Prefab.GetComponent<ItemGun>();
		component2.gunMuzzle = Anchor("BazookaMuzzle", new Vector3(0f, 0f, 0.67f));
		component2.gunTrigger = Anchor("BazookaTrigger", new Vector3(0f, -0.23f, -0.08f));
		component2.hasOneShot = true;
		component2.hasBuildUp = false;
		component2.shootCooldown = 2f;
		component2.misfirePercentageChange = 0f;
		component2.gunRecoilForce = 5.2f;
		component2.aimVerticalOffset = 0f;
		component2.grabVerticalOffset = -0.18f;
		component2.distanceKeep = 1.1f;
		ItemBattery component3 = Prefab.GetComponent<ItemBattery>();
		component3.batteryBars = 6;
		component3.autoDrain = false;
		component3.batteryLife = 100f;
		Rigidbody component4 = Prefab.GetComponent<Rigidbody>();
		component4.mass = 3.2f;
		NotValuableObject component5 = Prefab.GetComponent<NotValuableObject>();
		if (!Object.op_Implicit((Object)(object)component5) || !Object.op_Implicit((Object)(object)component5.physAttributePreset))
		{
			throw new InvalidOperationException("Vanilla physics preset missing.");
		}
		component5.physAttributePreset = Object.Instantiate<PhysAttribute>(component5.physAttributePreset);
		((Object)component5.physAttributePreset).name = "ChubbyBazooka_Physics";
		component5.physAttributePreset.mass = 3.2f;
		PhysGrabObject component6 = Prefab.GetComponent<PhysGrabObject>();
		component6.massOriginal = 3.2f;
		component6.colliders.Clear();
		Prefab.AddComponent<BazookaBehaviour>();
		Prefab.AddComponent<AmmoPolicy>();
		if (Items.RegisterItem(component) == null)
		{
			throw new InvalidOperationException("REPOLib refused bazooka registration.");
		}
		TestPrefab = Object.Instantiate<GameObject>(Prefab, Storage.transform, false);
		((Object)TestPrefab).name = "Item Chubby Bazooka TEST V021";
		TestItem = Object.Instantiate<Item>(Item);
		((Object)TestItem).name = "Item Chubby Bazooka TEST V021";
		TestItem.itemName = "Chubby Bazooka TEST";
		TestItem.description = "Host test bazooka. Infinite rockets; normal firing cooldown.";
		TestItem.maxAmountInShop = 0;
		TestItem.maxAmount = 2;
		TestItem.maxPurchase = false;
		TestPrefab.GetComponent<ItemAttributes>().item = TestItem;
		TestPrefab.GetComponent<BazookaBehaviour>().InfiniteAmmo = true;
		if (Items.RegisterItem(TestPrefab.GetComponent<ItemAttributes>()) == null)
		{
			throw new InvalidOperationException("REPOLib refused TEST bazooka registration.");
		}
		Plugin.Log("BAZOOKA_PREFAB_READY: " + ((Object)val3).name + " -> Item Chubby Bazooka V01; 2 physical colliders; embedded original mesh.");
	}

	private static Transform Anchor(string name, Vector3 pos)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(Prefab.transform, false);
		val.transform.localPosition = pos;
		return val.transform;
	}

	private static void Collider(string name, Vector3 pos, Vector3 size)
	{
		//IL_0001: 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)
		Transform val = Anchor(name, pos);
		((Component)val).gameObject.layer = LayerMask.NameToLayer("PhysGrabObject");
		((Component)val).gameObject.tag = "Phys Grab Object";
		BoxCollider val2 = ((Component)val).gameObject.AddComponent<BoxCollider>();
		val2.size = size;
		((Component)val).gameObject.AddComponent<PhysGrabObjectCollider>();
	}
}
public static class RuntimeChecks
{
	private static int passed;

	private static string ReportPath
	{
		get
		{
			string[] commandLineArgs = Environment.GetCommandLineArgs();
			int num = Array.IndexOf(commandLineArgs, "--bazooka-report");
			if (num < 0 || num + 1 >= commandLineArgs.Length)
			{
				return Path.Combine(Paths(), "runtime-checks.txt");
			}
			return commandLineArgs[num + 1];
		}
	}

	private static string Paths()
	{
		return Path.GetDirectoryName(typeof(Plugin).Assembly.Location);
	}

	private static void Check(bool condition, string name)
	{
		if (!condition)
		{
			throw new Exception("CHECK FAILED: " + name);
		}
		passed++;
		File.AppendAllText(ReportPath, "PASS: " + name + Environment.NewLine);
		Plugin.Log("SELFTEST PASS: " + name);
	}

	public static void Fail(Exception e)
	{
		File.AppendAllText(ReportPath, string.Concat("FAIL: ", e, Environment.NewLine));
	}

	private static bool True(ref bool __result)
	{
		__result = true;
		return false;
	}

	private static bool False(ref bool __result)
	{
		__result = false;
		return false;
	}

	private static bool SkipAwake()
	{
		return false;
	}

	public static void Run()
	{
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Expected O, but got Unknown
		//IL_045c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0462: Invalid comparison between Unknown and I4
		//IL_050d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0514: Expected O, but got Unknown
		//IL_053c: Unknown result type (might be due to invalid IL or missing references)
		//IL_054a: Expected O, but got Unknown
		//IL_0573: Unknown result type (might be due to invalid IL or missing references)
		//IL_0581: Expected O, but got Unknown
		//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b8: Expected O, but got Unknown
		//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ef: Expected O, but got Unknown
		//IL_0722: Unknown result type (might be due to invalid IL or missing references)
		//IL_072a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0730: Unknown result type (might be due to invalid IL or missing references)
		//IL_0761: Unknown result type (might be due to invalid IL or missing references)
		//IL_0781: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_07cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0804: Unknown result type (might be due to invalid IL or missing references)
		//IL_0809: Unknown result type (might be due to invalid IL or missing references)
		//IL_0821: Unknown result type (might be due to invalid IL or missing references)
		//IL_0835: Unknown result type (might be due to invalid IL or missing references)
		//IL_0848: Unknown result type (might be due to invalid IL or missing references)
		//IL_084d: Unknown result type (might be due to invalid IL or missing references)
		//IL_086c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0871: Unknown result type (might be due to invalid IL or missing references)
		//IL_089c: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_08df: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0904: Unknown result type (might be due to invalid IL or missing references)
		//IL_0940: Unknown result type (might be due to invalid IL or missing references)
		//IL_0945: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a1c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a24: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a2a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aa7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ab3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ab9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0af2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0af8: Unknown result type (might be due to invalid IL or missing references)
		File.WriteAllText(ReportPath, "Chubby Bazooka 0.3.0 - Unity batch runtime checks\n" + DateTime.UtcNow.ToString("o") + "\nApplication.version: " + Application.version + "; Unity: " + Application.unityVersion + "\n");
		Check(Object.op_Implicit((Object)(object)PrefabFactory.Prefab) && Object.op_Implicit((Object)(object)PrefabFactory.Item), "Runtime prefab and Item created from installed game resources");
		Check(NetworkPrefabs.HasNetworkPrefab("Items/Item Chubby Bazooka V01"), "REPOLib network prefab registered with stable ID");
		GameObject prefab = PrefabFactory.Prefab;
		Check(prefab.activeSelf && !prefab.activeInHierarchy, "Template inactive in storage; spawned copies retain activeSelf");
		Check(Object.op_Implicit((Object)(object)prefab.GetComponent<ItemEquippable>()) && Object.op_Implicit((Object)(object)prefab.GetComponent<ItemToggle>()) && Object.op_Implicit((Object)(object)prefab.GetComponent<PhysGrabObject>()) && Object.op_Implicit((Object)(object)prefab.GetComponent<PhotonView>()), "Vanilla inventory, interaction, physics and Photon components present");
		Check(prefab.GetComponentsInChildren<PhysGrabObjectCollider>(true).Length == 2, "Two grab-aware physical collider markers");
		Check(Math.Abs(prefab.GetComponent<NotValuableObject>().physAttributePreset.mass - 3.2f) < 0.001f, "Native NotValuableObject preset keeps bazooka mass at 3.2 kg");
		Check(prefab.GetComponent<ItemGun>().gunMuzzle.localPosition.z > 0.64f, "Muzzle clears barrel mesh");
		int num = 0;
		MeshFilter[] componentsInChildren = ((Component)prefab.transform.Find("bazooka_Visual")).GetComponentsInChildren<MeshFilter>(true);
		foreach (MeshFilter val in componentsInChildren)
		{
			num += val.sharedMesh.triangles.Length / 3;
			Check(val.sharedMesh.vertexCount > 0, "Mesh loaded: " + ((Object)val.sharedMesh).name);
		}
		Check(num < 2000 && num > 100, "Low-poly bazooka triangle budget: " + num);
		Check(Assets.Clip("launch").samples > 1000 && Assets.Clip("impact").samples > 1000, "Both embedded PCM sound assets decoded");
		Check(Object.op_Implicit((Object)(object)prefab.GetComponent<ItemAttributes>().icon) && (Object)(object)prefab.GetComponent<ItemEquippable>().ItemIcon == (Object)(object)Assets.ItemIcon(), "Original bazooka icon assigned to item and inventory");
		FireGate fireGate = new FireGate();
		Check(!fireGate.TryFire(0.0, authority: false, held: true, equipped: false, 100f), "Client cannot authorize a shot");
		Check(!fireGate.TryFire(0.0, authority: true, held: false, equipped: false, 100f), "Unheld item cannot fire");
		Check(!fireGate.TryFire(0.0, authority: true, held: true, equipped: true, 100f), "Stored inventory item cannot fire");
		Check(!fireGate.TryFire(0.0, authority: true, held: true, equipped: false, 0f), "Empty battery cannot fire");
		Check(fireGate.TryFire(0.0, authority: true, held: true, equipped: false, 100f), "First held host shot accepted");
		Check(!fireGate.TryFire(1.99, authority: true, held: true, equipped: false, 100f), "Cooldown blocks rapid repeat");
		Check(fireGate.TryFire(2.0, authority: true, held: true, equipped: false, 100f), "Shot accepted at cooldown boundary");
		Check(!fireGate.TryFire(double.NaN, authority: true, held: true, equipped: false, 100f), "Invalid clock rejected");
		Check(!fireGate.TryFire(10.0, authority: true, held: true, equipped: false, float.NaN), "Invalid battery value rejected");
		GameObject val2 = new GameObject("Bazooka_TestStats");
		val2.SetActive(false);
		StatsManager val3 = (StatsManager.instance = val2.AddComponent<StatsManager>());
		typeof(Items).GetMethod("RegisterItems", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
		Check(val3.itemDictionary.ContainsKey("Item Chubby Bazooka V01"), "REPOLib registers Item in a real StatsManager fixture");
		Check(PrefabFactory.Item.value.valueMin == 1250f && PrefabFactory.Item.value.valueMax == 1250f, "Default native shop value x4 gives exactly $5000");
		Check(PrefabFactory.Item.maxAmountInShop == 1 && (int)PrefabFactory.Item.itemSecretShopType == 0, "Normal bazooka eligible for regular shop pool");
		Check(PrefabFactory.TestItem.maxAmountInShop == 0, "TEST bazooka excluded from native shop pool");
		Check(val3.itemDictionary.ContainsKey("Item Chubby Bazooka TEST V021") && NetworkPrefabs.HasNetworkPrefab("Items/Item Chubby Bazooka TEST V021"), "Separate TEST save/network identity registered");
		Check(!prefab.GetComponent<BazookaBehaviour>().InfiniteAmmo && PrefabFactory.TestPrefab.GetComponent<BazookaBehaviour>().InfiniteAmmo, "Only TEST template has infinite ammo");
		Check(!((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Testing", "EnableInfiniteAmmoSpawn", false, (ConfigDescription)null).Value, "F7 test mode defaults OFF");
		Harmony val4 = new Harmony("berat.repo.chubbybazooka.tests");
		val4.Patch((MethodBase)AccessTools.Method(typeof(SemiFunc), "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RuntimeChecks), "True", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val4.Patch((MethodBase)AccessTools.Method(typeof(SemiFunc), "IsMultiplayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RuntimeChecks), "False", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val4.Patch((MethodBase)AccessTools.Method(typeof(SemiFunc), "MasterOnlyRPC", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RuntimeChecks), "True", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val4.Patch((MethodBase)AccessTools.Method(typeof(SemiFunc), "RunIsShop", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RuntimeChecks), "False", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		BazookaBehaviour component = prefab.GetComponent<BazookaBehaviour>();
		GameManager val5 = val2.AddComponent<GameManager>();
		AccessTools.Field(typeof(GameManager), "instance").SetValue(null, val5);
		val5.SetGameMode(0);
		ItemBattery component2 = prefab.GetComponent<ItemBattery>();
		ItemGun component3 = prefab.GetComponent<ItemGun>();
		AccessTools.Field(typeof(ItemGun), "itemBattery").SetValue(component3, component2);
		AccessTools.Field(typeof(ItemBattery), "itemAttributes").SetValue(component2, prefab.GetComponent<ItemAttributes>());
		PhysGrabber val6 = val2.AddComponent<PhysGrabber>();
		PhysGrabObject component4 = prefab.GetComponent<PhysGrabObject>();
		component4.playerGrabbing.Add(val6);
		prefab.GetComponent<Rigidbody>().isKinematic = false;
		Check(component3.Shoot(), "Real ItemGun.Shoot passes through Harmony to rocket launch");
		Check(component2.batteryLife > 83f && component2.batteryLife < 84f, "Actual launch consumes exactly one of six battery bars");
		Check(component.ActiveRockets == 1, "Actual launch creates one tracked rocket");
		Check(!component3.Shoot(), "Actual firing method rejects repeat during cooldown");
		AmmoChecks(val2, val6, component2);
		Check(Object.FindObjectsOfType<ItemGunBullet>().Length == 0, "Original hitscan bullet is suppressed for bazooka");
		component.BazookaImpactRPC(1, Vector3.zero, explode: false);
		component4.playerGrabbing.Clear();
		GameObject val7 = GameObject.CreatePrimitive((PrimitiveType)3);
		val7.transform.position = new Vector3(100f, 100f, 104f);
		val7.transform.localScale = new Vector3(4f, 4f, 0.02f);
		Physics.SyncTransforms();
		Check(component.FindHit(new Vector3(100f, 100f, 100f), new Vector3(0f, 0f, 8f), out var closest), "Swept sphere detects a thin wall at rocket speed");
		Check(Math.Abs(((RaycastHit)(ref closest)).point.z - 103.99f) < 0.1f, "Collision point lies on the wall");
		Check(component.FindHit(new Vector3(100f, 100f, 104f), Vector3.back, out closest), "Initial sphere overlap with thin wall is detected");
		int condition;
		if (Vector3.Distance(((RaycastHit)(ref closest)).point, new Vector3(100f, 100f, 104f)) < 0.1f)
		{
			Vector3 point = ((RaycastHit)(ref closest)).point;
			condition = ((((Vector3)(ref point)).sqrMagnitude > 1000f) ? 1 : 0);
		}
		else
		{
			condition = 0;
		}
		Check((byte)condition != 0, "Initial-overlap contact stays on real surface, never resets to world origin");
		Vector3 normal = ((RaycastHit)(ref closest)).normal;
		Check(((Vector3)(ref normal)).sqrMagnitude > 0.9f, "Initial-overlap contact has an outward surface normal");
		Check(!component.FindHit(new Vector3(110f, 100f, 100f), new Vector3(0f, 0f, 1f), out closest), "Clear flight path has no false collision");
		Rocket rocket = component.TrackRocket(1000, new Vector3(110f, 100f, 100f), Vector3.forward, authority: true);
		rocket.Step(0.02f);
		Check(Math.Abs(((Component)rocket).transform.position.z - 100.36f) < 0.001f, "Rocket advances 18 m/s in FixedUpdate step");
		Rocket rocket2 = component.TrackRocket(1001, new Vector3(100f, 100f, 100f), Vector3.forward, authority: true);
		rocket2.Step(0.25f);
		bool condition2 = (bool)typeof(Rocket).GetField("finished", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(rocket2);
		Check(condition2, "Rocket collision stops simulation instead of tunnelling through wall");
		Check(component.ActiveRockets == 1, "Impact removes the correct shot from the active projectile table");
		Check(Object.FindObjectsOfType<Effects>().Length == 1, "Authoritative impact creates the blast visual");
		Effects effects = Object.FindObjectOfType<Effects>();
		Check(((Component)effects).GetComponentsInChildren<ParticleSystem>().Length == 4 && ((Component)effects).GetComponentsInChildren<Collider>().Length == 0, "Actual blast creates flash/fire/sparks/smoke without gameplay colliders");
		Check(prefab.GetComponent<ItemGun>().gunRecoilForce > 3.2f, "Held physical recoil increased while weapon mass stays unchanged");
		Check(VfxLight.Active <= 6, "Dynamic VFX light budget bounded to six");
		component.BazookaImpactRPC(1001, ((RaycastHit)(ref closest)).point, explode: true);
		Check(Object.FindObjectsOfType<Effects>().Length == 1, "Duplicate impact does not create a second blast");
		rocket.Step(4f);
		Check((bool)typeof(Rocket).GetField("finished", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(rocket), "Rocket lifetime caps flight duration");
		Check(component.ActiveRockets == 0, "Expired projectile removed from active table");
		component.BazookaLaunchRPC(987, new Vector3(120f, 100f, 100f), Vector3.forward);
		Check(component.ActiveRockets == 1, "Launch uses host-supplied shot ID even after earlier missed shots");
		component.BazookaImpactRPC(987, new Vector3(120f, 100f, 103f), explode: false);
		Check(component.ActiveRockets == 0, "Host-supplied ID matches subsequent impact");
		Object.DestroyImmediate((Object)(object)val7);
		Object.DestroyImmediate((Object)(object)((Component)rocket).gameObject);
		Object.DestroyImmediate((Object)(object)((Component)rocket2).gameObject);
		DamageChecks(val4, component);
		PlayerDamageChecks.Run(Check, val4, component);
		File.AppendAllText(ReportPath, "RESULT: " + passed + " passed; isolated fixtures in real Unity/game assemblies. Map gameplay and multiplayer require separate integration evidence.\n");
		Plugin.Log("BAZOOKA_SELFTEST_COMPLETE: " + passed + " checks passed.");
	}

	private static int Health(EnemyHealth health)
	{
		return (int)AccessTools.Field(typeof(EnemyHealth), "healthCurrent").GetValue(health);
	}

	private static void AmmoChecks(GameObject fixture, PhysGrabber holder, ItemBattery normal)
	{
		//IL_0182: 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_0190: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(PrefabFactory.TestPrefab, PrefabFactory.Storage.transform, false);
		BazookaBehaviour component = val.GetComponent<BazookaBehaviour>();
		ItemGun component2 = val.GetComponent<ItemGun>();
		ItemBattery component3 = val.GetComponent<ItemBattery>();
		AccessTools.Field(typeof(ItemGun), "itemBattery").SetValue(component2, component3);
		AccessTools.Field(typeof(ItemBattery), "itemAttributes").SetValue(component3, val.GetComponent<ItemAttributes>());
		val.GetComponent<PhysGrabObject>().playerGrabbing.Add(holder);
		val.GetComponent<AmmoPolicy>().Initialize();
		Check(component.InfiniteAmmo && component3.batteryBars == 6, "Cloned TEST prefab retains isolated ammo policy");
		Sprite val2 = Assets.ItemIcon();
		AccessTools.Method(typeof(ItemAttributes), "OnDestroy", (Type[])null, (Type[])null).Invoke(val.GetComponent<ItemAttributes>(), null);
		Check(Object.op_Implicit((Object)(object)val2) && (Object)(object)PrefabFactory.Prefab.GetComponent<ItemAttributes>().icon == (Object)(object)val2, "Destroying a purchased shelf item preserves the shared bazooka icon");
		float batteryLife = normal.batteryLife;
		for (int i = 0; i < 8; i++)
		{
			FireGate obj = (FireGate)AccessTools.Field(typeof(BazookaBehaviour), "gate").GetValue(component);
			AccessTools.Field(typeof(FireGate), "next").SetValue(obj, double.NegativeInfinity);
			Check(component2.Shoot(), "TEST actual ItemGun shot beyond normal capacity: " + (i + 1));
			component.BazookaImpactRPC(i + 1, new Vector3(300f, 100f, 100f), explode: false);
		}
		Check(component3.batteryLife == 100f && normal.batteryLife == batteryLife, "Eight TEST shots do not drain TEST or refill normal ammo");
		Check(!component2.Shoot(), "TEST still rejects immediate repeat during normal cooldown");
		component3.RemoveFullBar(1);
		Check(component3.batteryLife == 100f, "Scoped native RemoveFullBar protection only on TEST");
		normal.RemoveFullBar(1);
		Check(normal.batteryLife < batteryLife, "Normal ammo still drains while TEST item exists");
		Plugin.StartingAmmo.Value = 3;
		PrefabFactory.Prefab.GetComponent<AmmoPolicy>().Initialize();
		Check(normal.batteryBars == 3, "Host config sets normal capacity to three rockets");
		FireGate fireGate = new FireGate();
		Check(fireGate.TryFire(0.0, authority: true, held: true, equipped: false, 8.333333f, 12), "Last round accepted with configured twelve-round capacity");
		Check(!fireGate.TryFire(3.0, authority: true, held: true, equipped: false, 0f, 12), "Configured normal capacity never allows empty fire");
		Plugin.StartingAmmo.Value = 6;
		PrefabFactory.Prefab.GetComponent<AmmoPolicy>().Initialize();
		Object.DestroyImmediate((Object)(object)val);
	}

	private static void DamageChecks(Harmony harmony, BazookaBehaviour owner)
	{
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Expected O, but got Unknown
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Expected O, but got Unknown
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Expected O, but got Unknown
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Expected O, but got Unknown
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Expected O, but got Unknown
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Expected O, but got Unknown
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Expected O, but got Unknown
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Expected O, but got Unknown
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0224: Expected O, but got Unknown
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Expected O, but got Unknown
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0330: Unknown result type (might be due to invalid IL or missing references)
		//IL_0335: Unknown result type (might be due to invalid IL or missing references)
		//IL_033a: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0418: Unknown result type (might be due to invalid IL or missing references)
		//IL_0453: Unknown result type (might be due to invalid IL or missing references)
		//IL_0455: Unknown result type (might be due to invalid IL or missing references)
		//IL_045f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0464: Unknown result type (might be due to invalid IL or missing references)
		//IL_0496: Unknown result type (might be due to invalid IL or missing references)
		//IL_0498: Unknown result type (might be due to invalid IL or missing references)
		//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0522: Unknown result type (might be due to invalid IL or missing references)
		//IL_0530: Expected O, but got Unknown
		//IL_0531: Unknown result type (might be due to invalid IL or missing references)
		//IL_0579: Unknown result type (might be due to invalid IL or missing references)
		//IL_0587: Expected O, but got Unknown
		//IL_058e: Unknown result type (might be due to invalid IL or missing references)
		//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
		Check(BlastDamage.Calculate(0f, 3f, 120, falloff: true, 0.25f) == 120, "Blast centre uses maximum damage");
		Check(BlastDamage.Calculate(1.5f, 3f, 120, falloff: true, 0.25f) == 75, "Linear distance falloff produces expected damage");
		Check(BlastDamage.Calculate(3f, 3f, 120, falloff: true, 0.25f) == 0, "Outside blast radius produces zero damage");
		Check(BlastDamage.Calculate(2f, 3f, 120, falloff: false, 0.25f) == 120, "Falloff can be disabled");
		Check(BlastDamage.Calculate(float.NaN, 3f, 120, falloff: true, 0.25f) == 0, "Invalid target distance rejected");
		harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyHealth), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RuntimeChecks), "SkipAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(Enemy), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RuntimeChecks), "SkipAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyBombThrowerHead), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RuntimeChecks), "SkipAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		GameObject val = new GameObject("Bazooka_EnemyHealthFixture");
		val.SetActive(false);
		val.transform.position = new Vector3(200f, 200f, 200f);
		Enemy value = val.AddComponent<Enemy>();
		EnemyHealth val2 = val.AddComponent<EnemyHealth>();
		val2.health = 1000;
		AccessTools.Field(typeof(EnemyHealth), "enemy").SetValue(val2, value);
		val2.onHurt = new UnityEvent();
		val2.onDeathStart = new UnityEvent();
		val2.onDeath = new UnityEvent();
		int deathEvents = 0;
		val2.onDeath.AddListener((UnityAction)delegate
		{
			deathEvents++;
		});
		SphereCollider val3 = val.AddComponent<SphereCollider>();
		val3.radius = 0.2f;
		GameObject val4 = new GameObject("DetachedCleanupHeadFixture");
		val4.transform.SetParent(val.transform, false);
		val4.transform.localPosition = Vector3.right * 10f;
		val4.AddComponent<EnemyBombThrowerHead>();
		SphereCollider collider = val4.AddComponent<SphereCollider>();
		Check(!Object.op_Implicit((Object)(object)BlastDamage.Resolve((Collider)(object)collider)), "Detached Cleanup Crew bomb never forwards damage to distant body health");
		Object.DestroyImmediate((Object)(object)val4);
		GameObject val5 = new GameObject("SecondEnemyCollider");
		val5.transform.SetParent(val.transform, false);
		val5.transform.localPosition = new Vector3(0.1f, 0f, 0f);
		val5.AddComponent<SphereCollider>().radius = 0.1f;
		val.SetActive(true);
		val2.OnSpawn();
		Physics.SyncTransforms();
		Plugin.BlastRadius.Value = 3f;
		Plugin.BlastMaxDamage.Value = 120;
		Plugin.DamageFalloff.Value = true;
		Plugin.MinimumDamageFraction.Value = 0.25f;
		Plugin.BlastLineOfSight.Value = false;
		Vector3 val6 = val.transform.position - Vector3.right;
		int num = BlastDamage.Apply(val6, ((Component)owner).transform);
		Check(num == 1, "Two colliders resolve to one unique EnemyHealth target");
		Check(Health(val2) == 904, "Real EnemyHealth.Hurt subtracts expected blast damage once");
		val2.OverrideDamageResistance(0.5f, 1f);
		val2.Hurt(100, Vector3.up);
		Check(Health(val2) == 854, "Native enemy damage resistance remains effective");
		val2.OverrideDamageResistance(0f, 0f);
		GameObject val7 = GameObject.CreatePrimitive((PrimitiveType)3);
		val7.transform.position = val.transform.position - Vector3.right * 0.5f;
		val7.transform.localScale = new Vector3(0.1f, 2f, 2f);
		Plugin.BlastLineOfSight.Value = true;
		Physics.SyncTransforms();
		Check(BlastDamage.Apply(val6, ((Component)owner).transform) == 0 && Health(val2) == 854, "World cover blocks blast damage");
		Object.DestroyImmediate((Object)(object)val7);
		Plugin.BlastLineOfSight.Value = false;
		Check(BlastDamage.Apply(val6 - Vector3.right * 10f, ((Component)owner).transform) == 0 && Health(val2) == 854, "Enemy outside radius is not damaged");
		owner.TrackRocket(2001, val6, Vector3.right, authority: true);
		owner.Impact(2001, val6, explode: true);
		int num2 = Health(val2);
		owner.Impact(2001, val6, explode: true);
		Check(num2 == 758 && Health(val2) == num2, "Duplicate authoritative impact cannot apply a second blast");
		MethodInfo methodInfo = AccessTools.Method(typeof(SemiFunc), "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null);
		harmony.Unpatch((MethodBase)methodInfo, (HarmonyPatchType)1, harmony.Id);
		harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(RuntimeChecks), "False", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		Check(BlastDamage.Apply(val6, ((Component)owner).transform) == 0 && Health(val2) == num2, "Non-host blast cannot mutate enemy health");
		harmony.Unpatch((MethodBase)methodInfo, (HarmonyPatchType)1, harmony.Id);
		harmon