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;
}
}