Decompiled source of MortalEnemies v1.1.1

rivinwin.MortalEnemies.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour.HookGen;
using MortalEnemies.Patches;
using MyceliumNetworking;
using Photon.Pun;
using UnityEngine;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("rivinwin.MortalEnemies")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A Content Warning mod to make enemies damageable, used as a dependancy.")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+624a8facbb0bba106dfa56d43d9c2c0566ed0204")]
[assembly: AssemblyProduct("MortalEnemies")]
[assembly: AssemblyTitle("rivinwin.MortalEnemies")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/RivinwinCW/CW_MortalEnemies")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MortalEnemies
{
	[ContentWarningPlugin("rivinwin.MortalEnemies", "1.1.1", false)]
	[BepInPlugin("rivinwin.MortalEnemies", "MortalEnemies", "1.1.1")]
	public class MortalEnemies : BaseUnityPlugin
	{
		public static MortalEnemies Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"rivinwin.MortalEnemies v1.1.1 installed, hooking...");
			HookAll();
		}

		internal static void HookAll()
		{
			ClassPatches.Init();
			Logger.LogDebug((object)"Finished hooking");
		}

		internal static void UnhookAll()
		{
			HookEndpointManager.RemoveAllOwnedBy((object)Assembly.GetExecutingAssembly());
			Logger.LogDebug((object)"Finished unhooking");
		}
	}
	public abstract class Mortality : MonoBehaviour
	{
		private enum TimedEffectState
		{
			None,
			Damaging,
			Healing
		}

		public class DoTSource
		{
			internal float damagePerTick;

			internal uint expireTick;

			internal uint ticksRemaining;

			internal ushort ID;

			internal bool paused;

			internal bool Paused
			{
				get
				{
					return paused;
				}
				set
				{
					if (paused != value)
					{
						if (value)
						{
							ticksRemaining = expireTick - MortalSingleton.Instance.CurrentTick;
						}
						else
						{
							expireTick = MortalSingleton.Instance.CurrentTick + ticksRemaining;
						}
						paused = value;
					}
				}
			}

			internal DoTSource(float newDpT, uint newTicks, ushort newID)
			{
				damagePerTick = newDpT;
				ticksRemaining = newTicks;
				expireTick = MortalSingleton.Instance.CurrentTick + newTicks;
				ID = newID;
			}
		}

		public static readonly uint modId = (uint)"rivinwin.MortalEnemies".GetHashCode();

		public int viewIDClone;

		private bool isAutonomousProxy;

		private MortalSingleton mortalSingleton = MortalSingleton.Instance;

		private TimedEffectState uiEffectState;

		private List<DoTSource> dotSources = new List<DoTSource>();

		private static ushort nextDoTSourceID;

		internal float damagePerTick;

		private bool damagePerTickDirty;

		public bool IsAlive => Health > 0f;

		public abstract float MaxHealth { get; internal set; }

		public abstract float Health { get; internal set; }

		protected virtual void Awake()
		{
			mortalSingleton.Mortalities.Add(this);
			viewIDClone = ((Component)this).GetComponent<PhotonView>().ViewID;
			MyceliumNetwork.RegisterNetworkObject((object)this, modId, viewIDClone);
		}

		private void FixedUpdate()
		{
			if (dotSources.Count != 0)
			{
				while (dotSources.Count > 0 && dotSources[0].expireTick < mortalSingleton.CurrentTick)
				{
					dotSources.RemoveAt(0);
					damagePerTickDirty = true;
				}
				if (damagePerTickDirty)
				{
					CalcDamagePerTick();
				}
				if (uiEffectState == TimedEffectState.Damaging)
				{
					DoTEffect();
				}
				else if (uiEffectState == TimedEffectState.Healing && Health < MaxHealth)
				{
					HoTEffect();
				}
				Health -= damagePerTick;
			}
		}

		protected virtual void OnDestroy()
		{
			MyceliumNetwork.DeregisterNetworkObject((object)this, modId, viewIDClone);
			mortalSingleton.Mortalities.Remove(this);
		}

		public virtual void DamageEffect()
		{
		}

		public virtual void DoTEffect()
		{
		}

		public virtual void HealEffect()
		{
		}

		public virtual void HoTEffect()
		{
		}

		protected abstract void KillEffect();

		protected abstract void ReviveEffect();

		public void Damage(float inDamage)
		{
			if (!(inDamage <= 0f))
			{
				if (isAutonomousProxy)
				{
					RPCA_Damage(inDamage);
				}
				else if (MyceliumNetwork.IsHost)
				{
					MyceliumNetwork.RPCMasked(modId, "RPCA_Damage", (ReliableType)1, viewIDClone, new object[1] { inDamage });
				}
			}
		}

		public ushort DamageOverTime(float inDamagePerSecond, float inSeconds)
		{
			if (!isAutonomousProxy && !MyceliumNetwork.IsHost)
			{
				return 0;
			}
			ushort unigueDoTSourceID = GetUnigueDoTSourceID();
			uint num = (ushort)Mathf.RoundToInt(inSeconds / Time.fixedDeltaTime);
			float num2 = inDamagePerSecond * Time.fixedDeltaTime;
			if (isAutonomousProxy)
			{
				RPCA_AddDoTSource(num2, num, unigueDoTSourceID);
			}
			else if (MyceliumNetwork.IsHost)
			{
				MyceliumNetwork.RPCMasked(modId, "RPCA_AddDoTSource", (ReliableType)1, viewIDClone, new object[3] { num2, num, unigueDoTSourceID });
			}
			return unigueDoTSourceID;
		}

		public void Heal(float inHealth)
		{
			if (!(inHealth <= 0f))
			{
				if (isAutonomousProxy)
				{
					RPCA_Heal(inHealth);
				}
				else if (MyceliumNetwork.IsHost)
				{
					MyceliumNetwork.RPCMasked(modId, "RPCA_Heal", (ReliableType)1, viewIDClone, new object[1] { inHealth });
				}
			}
		}

		public ushort HealOverTime(float inHealthPerSecond, float inSeconds)
		{
			return DamageOverTime(0f - inHealthPerSecond, inSeconds);
		}

		public void Revive(float newHealth = 100f)
		{
			if (!(newHealth <= 0f))
			{
				if (newHealth > MaxHealth)
				{
					newHealth = MaxHealth;
				}
				if (isAutonomousProxy)
				{
					RPCA_Revive(newHealth);
				}
				else if (MyceliumNetwork.IsHost)
				{
					MyceliumNetwork.RPCMasked(modId, "RPCA_Revive", (ReliableType)1, viewIDClone, new object[1] { newHealth });
				}
			}
		}

		private static ushort GetUnigueDoTSourceID()
		{
			if (!MyceliumNetwork.IsHost)
			{
				return 0;
			}
			return ++nextDoTSourceID;
		}

		public void RemoveDot(ushort IDtoRemove)
		{
			if (isAutonomousProxy)
			{
				RPCA_RemoveDoTSource(IDtoRemove);
			}
			else if (MyceliumNetwork.IsHost)
			{
				MyceliumNetwork.RPCMasked(modId, "RPCA_RemoveDoTSource", (ReliableType)1, viewIDClone, new object[1] { IDtoRemove });
			}
		}

		public void PauseDoT(ushort IDtoPause)
		{
			if (isAutonomousProxy)
			{
				RPCA_PauseDoTSource(IDtoPause);
			}
			else if (MyceliumNetwork.IsHost)
			{
				MyceliumNetwork.RPCMasked(modId, "RPCA_PauseDoTSource", (ReliableType)1, viewIDClone, new object[1] { IDtoPause });
			}
		}

		public void ResumeDoT(ushort IDtoResume)
		{
			if (isAutonomousProxy)
			{
				RPCA_ResumeDoTSource(IDtoResume);
			}
			else if (MyceliumNetwork.IsHost)
			{
				MyceliumNetwork.RPCMasked(modId, "RPCA_ResumeDoTSource", (ReliableType)1, viewIDClone, new object[1] { IDtoResume });
			}
		}

		protected virtual void CalcDamagePerTick()
		{
			damagePerTick = 0f;
			foreach (DoTSource dotSource in dotSources)
			{
				if (!dotSource.paused)
				{
					damagePerTick += dotSource.damagePerTick;
				}
			}
			damagePerTickDirty = false;
			if ((double)Mathf.Abs(damagePerTick) > 0.015)
			{
				uiEffectState = ((damagePerTick > 0f) ? TimedEffectState.Damaging : TimedEffectState.Healing);
			}
			else
			{
				uiEffectState = TimedEffectState.None;
			}
		}

		[CustomRPC]
		internal void RPCA_Damage(float sentDamage)
		{
			DamageEffect();
			Health -= sentDamage;
		}

		[CustomRPC]
		internal void RPCA_Heal(float sentHealth)
		{
			HealEffect();
			Health += sentHealth;
		}

		[CustomRPC]
		internal void RPCA_Revive(float sentHealth)
		{
			Health = sentHealth;
			ReviveEffect();
		}

		[CustomRPC]
		internal void RPCA_AddDoTSource(float sentDpT, uint sentTicks, ushort sentID)
		{
			DoTSource doTSource = new DoTSource(sentDpT, sentTicks, sentID);
			for (int num = dotSources.Count - 1; num >= 0; num--)
			{
				if (dotSources[num].expireTick <= doTSource.expireTick)
				{
					dotSources.Insert(num + 1, doTSource);
					damagePerTickDirty = true;
					return;
				}
			}
			dotSources.Insert(0, doTSource);
			damagePerTickDirty = true;
		}

		[CustomRPC]
		internal void RPCA_RemoveDoTSource(ushort toRemove)
		{
			foreach (DoTSource dotSource in dotSources)
			{
				if (dotSource.ID == toRemove)
				{
					dotSources.Remove(dotSource);
					damagePerTickDirty = true;
					break;
				}
			}
		}

		[CustomRPC]
		internal void RPCA_PauseDoTSource(ushort toPause)
		{
			foreach (DoTSource dotSource in dotSources)
			{
				if (dotSource.ID == toPause)
				{
					dotSource.Paused = true;
					damagePerTickDirty = true;
					break;
				}
			}
		}

		[CustomRPC]
		internal void RPCA_ResumeDoTSource(ushort toResume)
		{
			foreach (DoTSource dotSource in dotSources)
			{
				if (dotSource.ID == toResume)
				{
					dotSource.Paused = false;
					damagePerTickDirty = true;
					break;
				}
			}
		}
	}
	public class Mortality_Bot : Mortality
	{
		private float health;

		private float maxHealth = 100f;

		private Bot? botRef;

		private Player? playerRef;

		private HashSet<MonoBehaviour>? componentsToDeactivate;

		private float storedConstantGravity = 2f;

		private float storedGravity = 80f;

		public override float Health
		{
			get
			{
				return health;
			}
			internal set
			{
				if (health > 0f && value <= 0f)
				{
					KillEffect();
				}
				health = Mathf.Min(value, MaxHealth);
			}
		}

		public override float MaxHealth
		{
			get
			{
				return maxHealth;
			}
			internal set
			{
				maxHealth = value;
			}
		}

		protected override void Awake()
		{
			base.Awake();
			health = maxHealth;
			MortalSingleton.Instance.BotMortalities.Add(this);
		}

		protected override void OnDestroy()
		{
			base.OnDestroy();
			MortalSingleton.Instance.BotMortalities.Remove(this);
		}

		internal void SetBot(Bot newBotRef)
		{
			botRef = newBotRef;
			componentsToDeactivate = new HashSet<MonoBehaviour>();
			if (botRef == null)
			{
				playerRef = null;
				return;
			}
			playerRef = ((Component)this).gameObject.GetComponentInChildren<Player>();
			componentsToDeactivate.Add((MonoBehaviour)(object)botRef);
			MonoBehaviour[] componentsInChildren = ((Component)this).gameObject.GetComponentsInChildren<MonoBehaviour>();
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (((object)val).GetType().ToString().Contains("Bot_") || ((object)val).GetType().ToString().Contains("Attack"))
				{
					componentsToDeactivate.Add(val);
				}
			}
			foreach (MonoBehaviour item in componentsToDeactivate)
			{
				string text = ((item == null || (object)((object)item).GetType() == null || ((object)item).GetType().ToString() == null) ? "null" : ((object)item).GetType().ToString());
			}
		}

		protected override void KillEffect()
		{
			health = 0f;
			if (botRef == null || componentsToDeactivate == null)
			{
				return;
			}
			BotHandler.instance.bots.Remove(botRef);
			botRef.DoNothing();
			if (playerRef != null)
			{
				playerRef.data.dead = true;
				if (playerRef.refs.ragdoll != null)
				{
				}
				if (playerRef.refs.controller != null)
				{
					storedConstantGravity = playerRef.refs.controller.constantGravity;
					storedGravity = playerRef.refs.controller.gravity;
					playerRef.refs.controller.constantGravity = 4f;
					playerRef.refs.controller.gravity = 80f;
				}
			}
			foreach (MonoBehaviour item in componentsToDeactivate)
			{
				if (item != null)
				{
					((Behaviour)item).enabled = false;
				}
			}
		}

		protected override void ReviveEffect()
		{
			if ((Object)(object)botRef == (Object)null || componentsToDeactivate == null)
			{
				return;
			}
			BotHandler.instance.bots.Add(botRef);
			foreach (MonoBehaviour item in componentsToDeactivate)
			{
				if (item != null)
				{
					((Behaviour)item).enabled = true;
				}
			}
			if (playerRef != null)
			{
				playerRef.data.dead = false;
				if (playerRef.refs.ragdoll != null)
				{
				}
				if (playerRef.refs.controller != null)
				{
					playerRef.refs.controller.constantGravity = storedConstantGravity;
					playerRef.refs.controller.gravity = storedGravity;
				}
			}
		}
	}
	internal class Mortality_Player : Mortality
	{
		protected float nextDoTEffects;

		protected float nextDamageEffects;

		protected float nextHealEffects;

		internal bool attachedToLocalPlayer;

		internal Player? playerRef;

		internal PlayerData? playerData;

		protected float dotEffectInterval = 0.75f;

		protected float damageEffectInterval = 0.09f;

		protected float healEffectInterval = 0.09f;

		public override float Health
		{
			get
			{
				return (playerData == null) ? 100f : playerData.health;
			}
			internal set
			{
				if (playerData != null)
				{
					playerData.health = Mathf.Min(value, MaxHealth);
				}
			}
		}

		public override float MaxHealth
		{
			get
			{
				return 100f;
			}
			internal set
			{
			}
		}

		internal void SetPlayer(Player newPlayerRef)
		{
			if (!((Object)(object)newPlayerRef == (Object)(object)playerRef) && !((Object)(object)newPlayerRef == (Object)null))
			{
				attachedToLocalPlayer = (Object)(object)newPlayerRef == (Object)(object)Player.localPlayer;
				playerRef = newPlayerRef;
				playerData = playerRef.data;
			}
		}

		public override void DamageEffect()
		{
			if (Time.time > nextDamageEffects)
			{
				UI_Feedback.instance.TakeDamage(false);
				nextDamageEffects = Time.time + damageEffectInterval;
			}
		}

		public override void DoTEffect()
		{
			if (Time.time > nextDoTEffects)
			{
				UI_Feedback.instance.TakeDamage(false);
				nextDoTEffects = Time.time + dotEffectInterval;
			}
		}

		public override void HealEffect()
		{
			if (Time.time > nextHealEffects)
			{
				UI_Feedback.instance.HealFeedback();
				nextHealEffects = Time.time + healEffectInterval;
			}
		}

		public override void HoTEffect()
		{
			if (Time.time > nextDoTEffects)
			{
				UI_Feedback.instance.HealFeedback();
				nextDoTEffects = Time.time + dotEffectInterval;
			}
		}

		protected override void KillEffect()
		{
			playerData.player.Die();
		}

		protected override void ReviveEffect()
		{
			if (playerData.dead)
			{
				playerData.dead = false;
				if (attachedToLocalPlayer)
				{
					Player.justDied = false;
					NetworkVoiceHandler.TalkToAlive();
					UI_Feedback.instance.Revive();
				}
				if (!PlayerHandler.instance.playersAlive.Contains(playerData.player))
				{
					PlayerHandler.instance.playersAlive.Add(playerData.player);
				}
			}
		}
	}
	public class MortalSingleton : MonoBehaviour
	{
		private static MortalSingleton? _instance;

		private uint currentTick;

		private HashSet<Mortality> _mortalities = new HashSet<Mortality>();

		private HashSet<Mortality> _botMortalities = new HashSet<Mortality>();

		public static MortalSingleton Instance
		{
			get
			{
				if (_instance == null)
				{
					CreateMortalSingleton();
				}
				return _instance;
			}
		}

		public uint CurrentTick
		{
			get
			{
				return currentTick;
			}
			private set
			{
			}
		}

		public HashSet<Mortality> Mortalities
		{
			get
			{
				return _mortalities;
			}
			internal set
			{
				_mortalities = value;
			}
		}

		public HashSet<Mortality> BotMortalities
		{
			get
			{
				return _botMortalities;
			}
			internal set
			{
				_botMortalities = value;
			}
		}

		public static void CreateMortalSingleton()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			_instance = Object.FindFirstObjectByType<MortalSingleton>();
			if (_instance == null)
			{
				GameObject val = new GameObject("MortalSingleton", new Type[1] { typeof(MortalSingleton) });
				Object.DontDestroyOnLoad((Object)(object)val);
			}
		}

		private void Awake()
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = this;
			}
			else if ((Object)(object)_instance != (Object)(object)this)
			{
				MortalEnemies.Logger.LogWarning((object)"MortalSingleton already exists, destroying new duplicate");
				Object.Destroy((Object)(object)this);
				return;
			}
			Mortality[] array = Object.FindObjectsOfType<Mortality>();
			foreach (Mortality item in array)
			{
				_mortalities.Add(item);
			}
			Mortality_Bot[] array2 = Object.FindObjectsOfType<Mortality_Bot>();
			foreach (Mortality item2 in array2)
			{
				_botMortalities.Add(item2);
			}
		}

		private void FixedUpdate()
		{
			currentTick++;
		}
	}
	public class ScreenLogListener
	{
		private const int logLength = 52;

		public static ScreenLogListener? Instance;

		private Queue logQueue = new Queue(52);

		private Text? MyText;

		public GameObject gameObject;

		public bool outputQueue = true;

		public ScreenLogListener()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			gameObject = new GameObject("ScreenLogger");
			GameObject val = ((Component)((Component)RetrievableResourceSingleton<TransitionHandler>.Instance).transform.Find("Canvas")).gameObject;
			if ((Object)(object)val == (Object)null)
			{
				MortalEnemies.Logger.LogError((object)"Parent Canvas not found");
				return;
			}
			gameObject.transform.SetParent(val.transform);
			gameObject.transform.localPosition = Vector3.zero;
			gameObject.transform.localScale = new Vector3(1f, 1f, 1f);
			RectTransform val2 = gameObject.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0.75f, 0.05f);
			val2.anchorMax = new Vector2(0.943f, 0.95f);
			CanvasRenderer val3 = gameObject.AddComponent<CanvasRenderer>();
			val3.SetColor(new Color(1f, 1f, 1f, 1f));
			CanvasGroup val4 = gameObject.AddComponent<CanvasGroup>();
			val4.blocksRaycasts = false;
			Font font = Font.CreateDynamicFontFromOSFont("Arial", 16);
			MyText = gameObject.AddComponent<Text>();
			if (MyText != null)
			{
				MyText.font = font;
				MyText.fontSize = 16;
				MyText.supportRichText = false;
				MortalEnemies.Logger.LogEvent += Log_LogEvent;
			}
			else
			{
				MortalEnemies.Logger.LogError((object)"Text component not created");
			}
		}

		private void Log_LogEvent(object sender, LogEventArgs logEvent)
		{
			HandleLog(logEvent.Data.ToString().Replace("\n", ""));
		}

		public void HandleLog(string message)
		{
			if (logQueue.Count > 52)
			{
				logQueue.Dequeue();
			}
			logQueue.Enqueue(message);
			if (!((Object)(object)MyText == (Object)null))
			{
				RepopulateText();
			}
		}

		public void RepopulateText()
		{
			MyText.text = "";
			if (!outputQueue)
			{
				return;
			}
			foreach (string item in logQueue)
			{
				Text? myText = MyText;
				myText.text = myText.text + ">  " + item + "\n";
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "rivinwin.MortalEnemies";

		public const string PLUGIN_NAME = "MortalEnemies";

		public const string PLUGIN_VERSION = "1.1.1";
	}
}
namespace MortalEnemies.Patches
{
	public class ClassPatches
	{
		internal static void Init()
		{
			HookEndpointManager.Add((MethodBase)AccessTools.Method(typeof(Bot), "Start", (Type[])null, (Type[])null), (Delegate)new Action<Action<Bot>, Bot>(HookBotAwake));
			HookEndpointManager.Add((MethodBase)AccessTools.Method(typeof(Player), "Awake", (Type[])null, (Type[])null), (Delegate)new Action<Action<Player>, Player>(HookPlayerAwake));
		}

		public static void HookBotAwake(Action<Bot> orig, Bot self)
		{
			GameObject gameObject = ((Component)self).gameObject;
			while (!((Object)gameObject).name.Contains("(Clone)") && gameObject.transform.parent != null)
			{
				gameObject = ((Component)gameObject.transform.parent).gameObject;
			}
			orig(self);
			if (gameObject.GetComponent<Mortality>() == null)
			{
				gameObject.AddComponent<Mortality_Bot>()?.SetBot(self);
			}
		}

		public static void HookPlayerAwake(Action<Player> orig, Player self)
		{
			orig(self);
			if (!self.ai)
			{
				((Component)self).gameObject.AddComponent<Mortality_Player>()?.SetPlayer(self);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}