Decompiled source of EverythingCanDie v1.3.0

EverythingCanDie.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("EverythingCanDie")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: AssemblyDescription("YEP")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.3.0.0")]
namespace EverythingCanDie;

public class Patches
{
	public static List<string> UnkillableEnemies = new List<string>();

	public static List<string> BonkableEnemies = new List<string>();

	public static List<string> NotBonkableEnemies = new List<string>();

	public static List<string> InvalidEnemies = new List<string>();

	private static readonly int Damage = Animator.StringToHash("damage");

	private static bool CheckingIfBonkable = false;

	public static void StartOfRoundPatch()
	{
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Expected O, but got Unknown
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Expected O, but got Unknown
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Expected O, but got Unknown
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Expected O, but got Unknown
		//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Expected O, but got Unknown
		//IL_032d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Expected O, but got Unknown
		Plugin.enemies = (from EnemyType e in Resources.FindObjectsOfTypeAll(typeof(EnemyType))
			where (Object)(object)e != (Object)null
			select e).ToList();
		Plugin.items = (from Item i in Resources.FindObjectsOfTypeAll(typeof(Item))
			where (Object)(object)i != (Object)null
			select i).ToList();
		Plugin.ENEMY_MASK = 524288;
		Plugin.PLAYER_HIT_MASK = StartOfRound.Instance.collidersRoomMaskDefaultAndPlayers | (Plugin.ENEMY_MASK & 0x280008);
		if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", "UnimmortalAllMobs")))
		{
			ConfigEntry<bool> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Mobs", "UnimmortalAllMobs", true, "Leave On To Customise Mobs Below Or Turn Off To Make All Mobs Return To Normal(Make Immortal mobs immortal again).");
		}
		if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", "ExplosionEffectAllMobs")))
		{
			ConfigEntry<bool> val2 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Mobs", "ExplosionEffectAllMobs", true, "If this is set to true then explosion effect stays and removes the body otherwise when false all explosions on death will not appear and the body will appear.");
		}
		if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", "HealthAllMobs")))
		{
			ConfigEntry<bool> val3 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Mobs", "HealthAllMobs", true, "If this is set to false the enemies health will remain the same otherwise have fun configging.");
		}
		foreach (EnemyType enemy in Plugin.enemies)
		{
			string text = Plugin.RemoveInvalidCharacters(enemy.enemyName).ToUpper();
			try
			{
				if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", text + ".Unimmortal")))
				{
					ConfigEntry<bool> val4 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Mobs", text + ".Unimmortal", true, "If true this mob will explode and if immortal it will also be killable.");
				}
				if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", text + ".Explodeable")))
				{
					ConfigEntry<bool> val5 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Mobs", text + ".Explodeable", true, "The value of whether to spawn an explosion effect(Default on)");
				}
				if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", text + ".Hittable")))
				{
					ConfigEntry<bool> val6 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Mobs", text + ".Hittable", true, "The value of whether this mob is hittable with things like shovels.(WARNING: If it is a modded item that happens to shoot then this might effect those items too)");
				}
				if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", text + ".Shootable")))
				{
					ConfigEntry<bool> val7 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Mobs", text + ".Shootable", true, "The value of whether this mob is shootable with things like shotguns.(WARNING: Only works for items that use the ShotgunItem as its parent)");
				}
				if (!((BaseUnityPlugin)Plugin.Instance).Config.ContainsKey(new ConfigDefinition("Mobs", text + ".Health")))
				{
					EnemyAI component = enemy.enemyPrefab.GetComponent<EnemyAI>();
					ConfigEntry<int> val8 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<int>("Mobs", text + ".Health", component.enemyHP, "The value of the mobs health.(Default Vanilla is 3 for most unkillable mobs)");
					if (Plugin.CanMob("HealthAllMobs", ".Unimmortal", text))
					{
						component.enemyHP = val8.Value;
						Plugin.Log.LogInfo((object)$"Set {((Object)enemy).name} HP to {component.enemyHP}");
					}
				}
			}
			catch (Exception)
			{
				Plugin.Log.LogInfo((object)("It was not possible to generate the configs for the enemy: " + enemy.enemyName));
				InvalidEnemies.Add(enemy.enemyName);
			}
			try
			{
				if (Plugin.CanMob("UnimmortalAllMobs", ".Unimmortal", text))
				{
					UnkillableEnemies.Add(enemy.enemyName);
					enemy.canDie = true;
				}
				Plugin.Log.LogInfo((object)$"Vanilla canDie variable for {enemy.enemyName} = {enemy.canDie}");
			}
			catch (Exception)
			{
				Plugin.Log.LogError((object)("It was not possible to determine whether the enemy " + enemy.enemyName + " was killable or not"));
			}
		}
		if ((Object)(object)Plugin.explosionPrefab == (Object)null && (Object)(object)StartOfRound.Instance.explosionPrefab != (Object)null)
		{
			Plugin.explosionPrefab = Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab);
			if ((Object)(object)Plugin.explosionPrefab.GetComponent<AudioSource>() != (Object)null)
			{
				Plugin.explosionPrefab.GetComponent<AudioSource>().volume = 0.35f;
			}
			Plugin.explosionPrefab.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)Plugin.explosionPrefab);
		}
	}

	public static void HitEnemyPatch(ref EnemyAI __instance, int force = 1, PlayerControllerB playerWhoHit = null)
	{
		if (!((Object)(object)__instance != (Object)null) || CheckingIfBonkable || (InvalidEnemies.Contains(__instance.enemyType.enemyName) && __instance.isEnemyDead))
		{
			return;
		}
		EnemyType enemyType = __instance.enemyType;
		string text = Plugin.RemoveInvalidCharacters(enemyType.enemyName).ToUpper();
		bool flag = true;
		if (!Plugin.CanMob("UnimmortalAllMobs", ".Unimmortal", text) || ((Object)(object)playerWhoHit == (Object)null && __instance.enemyType.enemyName == "RadMech"))
		{
			return;
		}
		if ((Object)(object)playerWhoHit != (Object)null && (Object)(object)playerWhoHit.ItemSlots[playerWhoHit.currentItemSlot] != (Object)null)
		{
			GrabbableObject val = playerWhoHit.ItemSlots[playerWhoHit.currentItemSlot];
			if (val.itemProperties.isDefensiveWeapon && !Plugin.Can(text + ".Hittable"))
			{
				flag = false;
				Plugin.Log.LogInfo((object)("Hit Disabled for " + __instance.enemyType.enemyName + "!"));
			}
			else if (val is ShotgunItem && !Plugin.Can(text + ".Shootable"))
			{
				flag = false;
				Plugin.Log.LogInfo((object)("Shoot Disabled for " + __instance.enemyType.enemyName + "!"));
			}
		}
		if (!flag)
		{
			return;
		}
		if (!BonkableEnemies.Contains(__instance.enemyType.enemyName) && !NotBonkableEnemies.Contains(__instance.enemyType.enemyName))
		{
			Plugin.Log.LogInfo((object)(__instance.enemyType.enemyName + " is not in the Bonkable or in the NotBonkable list"));
			CanEnemyGetBonked(__instance);
		}
		if (BonkableEnemies.Contains(__instance.enemyType.enemyName))
		{
			Plugin.Log.LogInfo((object)(__instance.enemyType.enemyName + " is in the Bonkable list"));
		}
		else if (NotBonkableEnemies.Contains(__instance.enemyType.enemyName))
		{
			Plugin.Log.LogInfo((object)(__instance.enemyType.enemyName + " is in the NotBonkable list"));
			if ((Object)(object)__instance.creatureAnimator != (Object)null)
			{
				__instance.creatureAnimator.SetTrigger(Damage);
			}
			if (__instance.enemyHP - force > 0)
			{
				EnemyAI obj = __instance;
				obj.enemyHP -= force;
			}
			else
			{
				__instance.enemyHP = 0;
			}
			if (__instance.enemyHP <= 0)
			{
				__instance.KillEnemyOnOwnerClient(false);
			}
		}
	}

	public static void CanEnemyGetBonked(EnemyAI __instance)
	{
		CheckingIfBonkable = true;
		int enemyHP = __instance.enemyHP;
		Plugin.Log.LogInfo((object)$"Enemy HP before bonk test: {enemyHP}");
		__instance.HitEnemy(1, (PlayerControllerB)null, false, -3);
		int enemyHP2 = __instance.enemyHP;
		Plugin.Log.LogInfo((object)$"Enemy HP after bonk test: {enemyHP2}");
		if (enemyHP != enemyHP2)
		{
			BonkableEnemies.Add(__instance.enemyType.enemyName);
			__instance.enemyHP = enemyHP;
			Plugin.Log.LogInfo((object)$"{__instance.enemyType.enemyName} is been added to the Bonkable list, HP = {__instance.enemyHP}");
		}
		else
		{
			NotBonkableEnemies.Add(__instance.enemyType.enemyName);
			Plugin.Log.LogInfo((object)$"{__instance.enemyType.enemyName} is been added to the NotBonkable list, HP = {__instance.enemyHP}");
		}
		CheckingIfBonkable = false;
	}

	public static void KillEnemyPatch(ref EnemyAI __instance)
	{
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: 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_016e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance != (Object)null) || InvalidEnemies.Contains(__instance.enemyType.enemyName))
		{
			return;
		}
		EnemyType enemyType = __instance.enemyType;
		string mobName = Plugin.RemoveInvalidCharacters(enemyType.enemyName).ToUpper();
		Plugin.Log.LogInfo((object)$"{((Object)__instance).name} HP is {__instance.enemyHP}, killing");
		if (!Plugin.CanMob("ExplosionEffectAllMobs", ".Explodeable", mobName))
		{
			return;
		}
		if (__instance.enemyType.enemyName == "Nutcracker" || __instance.enemyType.enemyName == "Butler")
		{
			HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			if (((NetworkBehaviour)__instance).IsServer)
			{
				Object.Instantiate<GameObject>(Plugin.explosionPrefab, ((Component)__instance).transform.position, Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform).SetActive(true);
			}
			return;
		}
		if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponentInChildren<PlayerControllerB>()))
		{
			HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			if (((NetworkBehaviour)__instance).IsServer)
			{
				Object.Instantiate<GameObject>(Plugin.explosionPrefab, ((Component)__instance).transform.position, Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform).SetActive(true);
			}
			return;
		}
		HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
		if (((NetworkBehaviour)__instance).IsServer)
		{
			Object.Instantiate<GameObject>(Plugin.explosionPrefab, ((Component)__instance).transform.position, Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform).SetActive(true);
		}
		((MonoBehaviour)__instance).StartCoroutine(MoveBody(__instance, 0.1f));
	}

	private static IEnumerator MoveBody(EnemyAI __instance, float time)
	{
		yield return (object)new WaitForSeconds(time);
		Vector3 OriginalBodyPos = new Vector3(-10000f, -10000f, -10000f);
		((Component)__instance).transform.position = OriginalBodyPos;
		__instance.SyncPositionToClients();
		if (__instance.enemyType.enemyName == "Blob" && ((NetworkBehaviour)__instance).IsServer)
		{
			((Component)__instance).GetComponent<NetworkObject>().Despawn(true);
		}
	}
}
[BepInPlugin("nwnt.EverythingCanDie", "EverythingCanDie", "1.3.0")]
public class Plugin : BaseUnityPlugin
{
	public const string Guid = "nwnt.EverythingCanDie";

	public const string Name = "EverythingCanDie";

	public const string Version = "1.3.0";

	public static Plugin Instance;

	public static Harmony Harmony;

	public static ManualLogSource Log;

	public static GameObject explosionPrefab;

	public static List<EnemyType> enemies;

	public static List<Item> items;

	public const float range = 30f;

	public static int ENEMY_MASK = 524288;

	public static int PLAYER_HIT_MASK;

	public static int numTightPellets = 2;

	public static float tightPelletAngle = 2.5f;

	public static int numLoosePellets = 3;

	public static float loosePelletAngle = 10f;

	private void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		Harmony = new Harmony("nwnt.EverythingCanDie");
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		Harmony.PatchAll(typeof(Plugin));
		Log = ((BaseUnityPlugin)this).Logger;
		CreateHarmonyPatch(Harmony, typeof(StartOfRound), "Start", null, typeof(Patches), "StartOfRoundPatch", isPrefix: false);
		CreateHarmonyPatch(Harmony, typeof(EnemyAI), "HitEnemy", new Type[4]
		{
			typeof(int),
			typeof(PlayerControllerB),
			typeof(bool),
			typeof(int)
		}, typeof(Patches), "HitEnemyPatch", isPrefix: false);
		CreateHarmonyPatch(Harmony, typeof(EnemyAI), "KillEnemy", new Type[1] { typeof(bool) }, typeof(Patches), "KillEnemyPatch", isPrefix: false);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Patching should be complete now :]");
	}

	public static Type FindType(string fullName)
	{
		try
		{
			if ((from a in AppDomain.CurrentDomain.GetAssemblies()
				where !a.IsDynamic
				select a).SelectMany((Assembly a) => a.GetTypes()).FirstOrDefault((Type t) => t.FullName.Equals(fullName)) != null)
			{
				return (from a in AppDomain.CurrentDomain.GetAssemblies()
					where !a.IsDynamic
					select a).SelectMany((Assembly a) => a.GetTypes()).FirstOrDefault((Type t) => t.FullName.Equals(fullName));
			}
		}
		catch
		{
			return null;
		}
		return null;
	}

	public static void CreateHarmonyPatch(Harmony harmony, Type typeToPatch, string methodToPatch, Type[] parameters, Type patchType, string patchMethod, bool isPrefix)
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Expected O, but got Unknown
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		if (typeToPatch == null || patchType == null)
		{
			Log.LogInfo((object)"Type is either incorrect or does not exist!");
			return;
		}
		MethodInfo methodInfo = AccessTools.Method(typeToPatch, methodToPatch, parameters, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(patchType, patchMethod, (Type[])null, (Type[])null);
		if (isPrefix)
		{
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log.LogInfo((object)("Prefix " + methodInfo.Name + " Patched!"));
		}
		else
		{
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log.LogInfo((object)("Postfix " + methodInfo.Name + " Patched!"));
		}
	}

	public static string RemoveInvalidCharacters(string source)
	{
		StringBuilder stringBuilder = new StringBuilder();
		foreach (char c in source)
		{
			if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
			{
				stringBuilder.Append(c);
			}
		}
		return string.Join("", stringBuilder.ToString().Split((string[]?)null, StringSplitOptions.RemoveEmptyEntries));
	}

	public static bool Can(string identifier)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		if (((BaseUnityPlugin)Instance).Config[new ConfigDefinition("Mobs", identifier)].BoxedValue.ToString().ToUpper().Equals("TRUE"))
		{
			return true;
		}
		return false;
	}

	public static bool CanMob(string parentIdentifier, string identifier, string mobName)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		string text = RemoveInvalidCharacters(mobName).ToUpper();
		if (((BaseUnityPlugin)Instance).Config[new ConfigDefinition("Mobs", parentIdentifier)].BoxedValue.ToString().ToUpper().Equals("TRUE"))
		{
			foreach (ConfigDefinition key in ((BaseUnityPlugin)Instance).Config.Keys)
			{
				if (RemoveInvalidCharacters(key.Key.ToUpper()).Equals(RemoveInvalidCharacters(text + identifier.ToUpper())))
				{
					return ((BaseUnityPlugin)Instance).Config[key].BoxedValue.ToString().ToUpper().Equals("TRUE");
				}
			}
			Log.LogInfo((object)(identifier + ": No mob found!"));
			return false;
		}
		Log.LogInfo((object)(parentIdentifier + ": All mobs disabled!"));
		return false;
	}
}