Decompiled source of LootBugShotgunKill v1.3.0

LootBugShotgunKill.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LootBugShotgunKill")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LootBugShotgunKill")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("23f7677e-cb64-4135-b6d6-83c2c16591f2")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LootBugShotgunKill;

[BepInPlugin("com.ben.lootbugshotgunkill", "Loot Bug Shotgun Kill", "1.3.0")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	private void Awake()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		new Harmony("com.ben.lootbugshotgunkill").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Loot Bug Shotgun Kill loaded (v1.3.0)");
	}
}
public class LootBugNet : NetworkBehaviour
{
	public static LootBugNet Instance;

	public override void OnNetworkSpawn()
	{
		Instance = this;
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
	}

	[ClientRpc]
	public void PlayLootBugFxClientRpc(Vector3 pos, Vector3 dir)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)NetworkManager.Singleton != (Object)null) || !NetworkManager.Singleton.IsHost)
		{
			EnemyDamagePatch.PlayFxOnly_Client(pos, dir);
		}
	}
}
[HarmonyPatch(typeof(GameNetworkManager))]
internal static class LootBugNetBootstrap
{
	private static bool created;

	[HarmonyPatch("Start")]
	[HarmonyPostfix]
	private static void StartPostfix()
	{
		TryCreate();
	}

	[HarmonyPatch("Awake")]
	[HarmonyPostfix]
	private static void AwakePostfix()
	{
		TryCreate();
	}

	private static void TryCreate()
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		if (created)
		{
			return;
		}
		NetworkManager singleton = NetworkManager.Singleton;
		if ((Object)(object)singleton == (Object)null || !singleton.IsHost)
		{
			return;
		}
		created = true;
		try
		{
			GameObject val = new GameObject("LootBugNetObject");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<LootBugNet>();
			NetworkObject val2 = val.AddComponent<NetworkObject>();
			val2.Spawn(false);
			Plugin.Log.LogInfo((object)"LootBugNetObject spawned by host.");
		}
		catch (Exception arg)
		{
			Plugin.Log.LogWarning((object)$"Failed to spawn LootBugNetObject: {arg}");
		}
	}
}
[HarmonyPatch(typeof(EnemyAI))]
internal class EnemyDamagePatch
{
	private static readonly Dictionary<int, float> processed = new Dictionary<int, float>();

	private const float ProcessedForgetSeconds = 20f;

	private static readonly List<GameObject> cachedBloodFxPrefabs = new List<GameObject>();

	private static bool bloodFxCacheBuilt = false;

	private const float BoomForce = 85f;

	private const int BloodFxLayers = 6;

	private const float BloodFxLifetime = 18f;

	private const int PuffCount = 140;

	private const int ChunkCount = 70;

	private const float PuffLifetimeMin = 5f;

	private const float PuffLifetimeMax = 10f;

	private const float ChunkLifetimeMin = 12f;

	private const float ChunkLifetimeMax = 22f;

	[HarmonyPatch("HitEnemy")]
	[HarmonyPrefix]
	private static bool HitEnemyPrefix(EnemyAI __instance, int force, bool playHitSFX, int hitID)
	{
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: 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_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.enemyType == (Object)null)
			{
				return true;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton != (Object)null) || !singleton.IsHost)
			{
				return true;
			}
			string text = __instance.enemyType.enemyName ?? "";
			if (!text.ToLower().Contains("hoarding"))
			{
				return true;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			float time = Time.time;
			CleanupProcessed(time);
			if (processed.ContainsKey(instanceID))
			{
				return false;
			}
			processed[instanceID] = time;
			Plugin.Log.LogInfo((object)$"Loot bug kill triggered ONCE. force={force}");
			__instance.enemyHP = 0;
			Vector3 val = ((Component)__instance).transform.forward;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			Vector3 val2 = val + Vector3.up * 0.15f;
			val = ((Vector3)(ref val2)).normalized;
			Vector3 pos = ((Component)__instance).transform.position + Vector3.up * 1.05f;
			SpawnDeathEffect(__instance, pos, val);
			LootBugNet.Instance?.PlayLootBugFxClientRpc(pos, val);
			return false;
		}
		catch (Exception arg)
		{
			Plugin.Log.LogError((object)$"HitEnemyPrefix exception: {arg}");
			return true;
		}
	}

	private static void CleanupProcessed(float now)
	{
		if (processed.Count < 50)
		{
			return;
		}
		List<int> list = new List<int>();
		foreach (KeyValuePair<int, float> item in processed)
		{
			if (now - item.Value > 20f)
			{
				list.Add(item.Key);
			}
		}
		for (int i = 0; i < list.Count; i++)
		{
			processed.Remove(list[i]);
		}
	}

	private static void SpawnDeathEffect(EnemyAI bug, Vector3 pos, Vector3 dir)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)bug == (Object)null))
		{
			DoLandmineBoomNoDamage(pos);
			SpawnBloodFxBurst(pos, dir);
			SpawnDebris(pos, dir);
			Object.Destroy((Object)(object)((Component)bug).gameObject);
		}
	}

	public static void PlayFxOnly_Client(Vector3 pos, Vector3 dir)
	{
		//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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		SpawnBloodFxBurst(pos, dir);
		SpawnDebris(pos, dir);
	}

	private static void DoLandmineBoomNoDamage(Vector3 pos)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Landmine.SpawnExplosion(pos, true, 0f, 0f, 0, 85f, (GameObject)null, false);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Landmine.SpawnExplosion failed: " + ex.Message));
		}
	}

	private static void BuildBloodFxCacheIfNeeded()
	{
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		if (bloodFxCacheBuilt)
		{
			return;
		}
		bloodFxCacheBuilt = true;
		string[] array = new string[4] { "blood", "splatter", "spurt", "bleed" };
		string[] array2 = new string[19]
		{
			"giant", "coil", "nutcracker", "robot", "mine", "landmine", "turret", "spawn", "ship", "teleport",
			"radar", "ui", "magnet", "spark", "smoke", "dust", "footstep", "steam", "fire"
		};
		GameObject[] array3 = Resources.FindObjectsOfTypeAll<GameObject>();
		foreach (GameObject val in array3)
		{
			if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(((Object)val).name))
			{
				continue;
			}
			string text = ((Object)val).name.ToLower();
			bool flag = false;
			for (int j = 0; j < array.Length; j++)
			{
				if (text.Contains(array[j]))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				continue;
			}
			bool flag2 = false;
			for (int k = 0; k < array2.Length; k++)
			{
				if (text.Contains(array2[k]))
				{
					flag2 = true;
					break;
				}
			}
			if (flag2 || (Object)(object)val.GetComponentInChildren<ParticleSystem>(true) == (Object)null)
			{
				continue;
			}
			bool flag3 = false;
			ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val2 in componentsInChildren)
			{
				MainModule main = val2.main;
				if (((MainModule)(ref main)).loop || ((MainModule)(ref main)).duration > 10f)
				{
					continue;
				}
				EmissionModule emission = val2.emission;
				if (!((EmissionModule)(ref emission)).enabled)
				{
					continue;
				}
				if (((EmissionModule)(ref emission)).burstCount <= 0)
				{
					MinMaxCurve rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
					if (!(((MinMaxCurve)(ref rateOverTime)).constant > 15f))
					{
						continue;
					}
				}
				flag3 = true;
				break;
			}
			if (!flag3)
			{
				continue;
			}
			bool flag4 = false;
			for (int m = 0; m < cachedBloodFxPrefabs.Count; m++)
			{
				if ((Object)(object)cachedBloodFxPrefabs[m] != (Object)null && ((Object)cachedBloodFxPrefabs[m]).name == ((Object)val).name)
				{
					flag4 = true;
					break;
				}
			}
			if (!flag4)
			{
				cachedBloodFxPrefabs.Add(val);
				Plugin.Log.LogInfo((object)("FX cached (blood-only): " + ((Object)val).name));
				if (cachedBloodFxPrefabs.Count >= 12)
				{
					break;
				}
			}
		}
		Plugin.Log.LogInfo((object)$"Blood FX cache built. Count={cachedBloodFxPrefabs.Count}");
	}

	private static void SpawnBloodFxBurst(Vector3 pos, Vector3 forward)
	{
		//IL_0063: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		BuildBloodFxCacheIfNeeded();
		if (cachedBloodFxPrefabs.Count == 0)
		{
			return;
		}
		int num = Mathf.Min(6, cachedBloodFxPrefabs.Count);
		for (int i = 0; i < num; i++)
		{
			GameObject val = cachedBloodFxPrefabs[Random.Range(0, cachedBloodFxPrefabs.Count)];
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 val2 = Random.insideUnitSphere * 0.25f;
				Quaternion val3 = Quaternion.LookRotation(forward);
				val3 *= Quaternion.Euler(Random.Range(-20f, 20f), Random.Range(-90f, 90f), Random.Range(-20f, 20f));
				GameObject val4 = Object.Instantiate<GameObject>(val, pos + val2, val3);
				ParticleSystem[] componentsInChildren = val4.GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val5 in componentsInChildren)
				{
					MainModule main = val5.main;
					((MainModule)(ref main)).loop = false;
					val5.Play(true);
				}
				Object.Destroy((Object)(object)val4, 18f);
			}
		}
	}

	private static void SpawnDebris(Vector3 center, Vector3 dir)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: 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_00ea: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: 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_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: 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_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: 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_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val4;
		for (int i = 0; i < 140; i++)
		{
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
			val.transform.position = center + Vector3.up * 0.2f + Random.insideUnitSphere * 0.9f;
			float num = Random.Range(0.05f, 0.14f);
			val.transform.localScale = Vector3.one * num;
			Collider component = val.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			ApplyChunkLook(val);
			Rigidbody val2 = val.AddComponent<Rigidbody>();
			val2.mass = 0.03f;
			val2.drag = 0.25f;
			val2.angularDrag = 0.2f;
			Vector3 val3 = Random.insideUnitSphere * 0.9f;
			val4 = dir * 1.3f + val3 + Vector3.up * 0.55f;
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			val2.AddForce(normalized * Random.Range(2.5f, 7f), (ForceMode)1);
			Object.Destroy((Object)(object)val, Random.Range(5f, 10f));
		}
		for (int j = 0; j < 70; j++)
		{
			PrimitiveType val5 = (PrimitiveType)((j % 3 == 0) ? 1 : ((j % 3 == 1) ? 3 : 0));
			GameObject val6 = GameObject.CreatePrimitive(val5);
			val6.transform.position = center + Vector3.up * 0.3f + Random.insideUnitSphere * 0.6f;
			float num2 = Random.Range(0.24f, 0.7f);
			float num3 = Random.Range(0.2f, 0.6f);
			float num4 = Random.Range(0.24f, 0.7f);
			val6.transform.localScale = new Vector3(num2, num3, num4);
			ApplyChunkLook(val6);
			Rigidbody val7 = val6.AddComponent<Rigidbody>();
			val7.mass = 0.18f;
			val7.drag = 0.05f;
			val7.angularDrag = 0.02f;
			Vector3 val8 = Random.insideUnitSphere * 1.1f;
			val4 = dir * 2f + val8 + Vector3.up * 0.6f;
			Vector3 normalized2 = ((Vector3)(ref val4)).normalized;
			val7.AddForce(normalized2 * Random.Range(18f, 42f), (ForceMode)1);
			val7.AddTorque(Random.insideUnitSphere * Random.Range(10f, 28f), (ForceMode)1);
			Object.Destroy((Object)(object)val6, Random.Range(12f, 22f));
		}
	}

	private static void ApplyChunkLook(GameObject go)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_0072: 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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		Renderer component = go.GetComponent<Renderer>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		Shader val = Shader.Find("Standard");
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Unlit/Color");
		}
		if (!((Object)(object)val == (Object)null))
		{
			Material val2 = new Material(val);
			Color[] array = (Color[])(object)new Color[4]
			{
				new Color(0.85f, 0.1f, 0.12f, 1f),
				new Color(0.65f, 0.06f, 0.1f, 1f),
				new Color(0.9f, 0.22f, 0.25f, 1f),
				new Color(0.45f, 0.05f, 0.1f, 1f)
			};
			Color val4 = (val2.color = array[Random.Range(0, array.Length)]);
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", 0f);
			}
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", 0.1f);
			}
			if (val2.HasProperty("_EmissionColor"))
			{
				val2.EnableKeyword("_EMISSION");
				val2.SetColor("_EmissionColor", val4 * 2.2f);
			}
			component.material = val2;
			component.shadowCastingMode = (ShadowCastingMode)0;
			component.receiveShadows = false;
		}
	}
}