Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ChubbyBazooka v0.3.0
BepInEx/plugins/ChubbyBazooka/ChubbyBazooka.dll
Decompiled 12 hours ago
The result has been truncated due to the large size, download it to view full contents!
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