Decompiled source of DownedAwareness v1.0.3

BepInEx/plugins/DownedAwareness/lucyddemon.downedawareness.dll

Decompiled a month ago
using System;
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.Configuration;
using BepInEx.Logging;
using DownedAwareness.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LucydDemon")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+5b37b53490661502646faf1e507e7b1ffba8b135")]
[assembly: AssemblyProduct("DownedAwareness")]
[assembly: AssemblyTitle("lucyddemon.downedawareness")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.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 DownedAwareness
{
	public class PassedOut : MonoBehaviour
	{
		public Character? character;

		private Vector3 lastPosition = Vector3.zero;

		private TextMeshProUGUI distanceText;

		private TextMeshProUGUI statusText;

		private bool isDead;

		private void Start()
		{
			distanceText = ((Component)((Component)this).transform.Find("DistanceText")).GetComponentInChildren<TextMeshProUGUI>();
			statusText = ((Component)((Component)this).transform.Find("StatusText")).GetComponentInChildren<TextMeshProUGUI>();
			((TMP_Text)statusText).text = "(@_@;)";
		}

		private void LateUpdate()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Camera.main == (Object)null) && !((Object)(object)character == (Object)null))
			{
				if (!isDead)
				{
					lastPosition = character.TorsoPos();
				}
				((Component)this).transform.position = Camera.main.WorldToScreenPoint(lastPosition);
				((Graphic)statusText).color = character.refs.customization.PlayerColor;
				float num = Mathf.Round(Vector3.Distance(lastPosition, ((Component)Camera.main).transform.position));
				int num2 = 100 - Mathf.CeilToInt(character.data.deathTimer * 100f);
				string arg = ((!isDead) ? $"{num2}%" : "DEAD");
				((TMP_Text)distanceText).text = $"{num}m | {arg}";
				float num3 = Vector3.Angle(((Component)Camera.main).transform.forward, lastPosition - ((Component)Camera.main).transform.position);
				bool active = num3 < 90f;
				((Component)statusText).gameObject.SetActive(active);
				((Component)distanceText).gameObject.SetActive(active);
			}
		}

		public void hasDied()
		{
			if (!((Object)(object)statusText == (Object)null) && !((Object)(object)distanceText == (Object)null))
			{
				((TMP_Text)statusText).text = "(x_x;)";
				isDead = true;
			}
		}
	}
	internal class DownedAwarenessConfig
	{
		public class Section
		{
			public readonly ConfigEntry<float> deadTimer;

			private List<string> _customItemsList = new List<string>();

			public IReadOnlyList<string> CustomItemsList => _customItemsList;

			internal Section(ConfigFile cfg, string sectionName)
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Expected O, but got Unknown
				deadTimer = cfg.Bind<float>(sectionName, "DeadTimer", 10f, new ConfigDescription("How long should the dead marker exists? (set 0 to turn off)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			}
		}

		public readonly Section General;

		public DownedAwarenessConfig(ConfigFile cfg)
		{
			cfg.SaveOnConfigSet = false;
			General = new Section(cfg, "General");
			ClearOrphanedEntries(cfg);
			cfg.Save();
			cfg.SaveOnConfigSet = true;
		}

		private static void ClearOrphanedEntries(ConfigFile cfg)
		{
			PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries");
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg);
			dictionary.Clear();
		}
	}
	[BepInPlugin("lucyddemon.downedawareness", "DownedAwareness", "1.0.3")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("lucyddemon.downedawareness");

		internal static Plugin instance { get; private set; }

		internal static ManualLogSource Log => instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal static DownedAwarenessConfig BoundConfig { get; private set; }

		internal static PassedOutManager POM { get; private set; }

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			BoundConfig = new DownedAwarenessConfig(((BaseUnityPlugin)this).Config);
			POM = new PassedOutManager();
			harmony.PatchAll(typeof(GUIManagerPatch));
			harmony.PatchAll(typeof(CharacterPatch));
			Log.LogInfo((object)"DownedAwareness v1.0.3 by LucydDemon initialized!");
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
			POM.OnDestroy();
		}
	}
	public class PassedOutManager
	{
		private TMP_FontAsset font;

		private Material fontMaterial;

		private Canvas passedOutCanvas;

		private GameObject template;

		private readonly Dictionary<Character, GameObject> passedOutInstances = new Dictionary<Character, GameObject>();

		public bool isInitialized
		{
			get
			{
				if ((Object)(object)Plugin.instance != (Object)null && (Object)(object)passedOutCanvas != (Object)null)
				{
					return (Object)(object)template != (Object)null;
				}
				return false;
			}
		}

		public PassedOutManager()
		{
			Plugin.Log.LogDebug((object)"PassedOutManager has started");
		}

		public void Initialize()
		{
			if (!isInitialized)
			{
				CreateCanvas();
				CreateTemplate();
				if (isInitialized)
				{
					Plugin.Log.LogDebug((object)"PassedOutManager UI initialized");
				}
			}
		}

		public void OnDestroy()
		{
			CleanupUI();
			if (!isInitialized)
			{
				Plugin.Log.LogDebug((object)"PassedOutManager UI cleaned up");
			}
		}

		private void CleanupUI()
		{
			if ((Object)(object)passedOutCanvas != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)passedOutCanvas).GetComponent<CanvasScaler>());
				Object.Destroy((Object)(object)((Component)passedOutCanvas).GetComponent<GraphicRaycaster>());
				Object.Destroy((Object)(object)((Component)passedOutCanvas).gameObject);
				passedOutCanvas = null;
			}
			template = null;
			passedOutInstances.Clear();
		}

		private void FindFont()
		{
			TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			TextMeshProUGUI[] array2 = array;
			foreach (TextMeshProUGUI val in array2)
			{
				if (((Object)val).name == "Text" && ((Object)((Graphic)val).materialForRendering).name.Contains("DarumaDropOne-Regular SDF Material"))
				{
					font = ((TMP_Text)val).font;
					fontMaterial = ((Graphic)val).materialForRendering;
					return;
				}
			}
			if ((Object)(object)font == (Object)null)
			{
				Plugin.Log.LogError((object)"Error finding game font");
			}
		}

		private void CreateCanvas()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)passedOutCanvas != (Object)null))
			{
				passedOutInstances.Clear();
				GameObject val = GameObject.Find("GAME/GUIManager");
				GameObject val2 = new GameObject("Canvas_PassedOutMarkers", new Type[3]
				{
					typeof(Canvas),
					typeof(CanvasScaler),
					typeof(GraphicRaycaster)
				});
				val2.transform.SetParent(val.transform);
				passedOutCanvas = val2.GetComponent<Canvas>();
				passedOutCanvas.renderMode = (RenderMode)0;
				passedOutCanvas.sortingOrder = 100;
				CanvasScaler component = val2.GetComponent<CanvasScaler>();
				component.uiScaleMode = (ScaleMode)1;
				component.referenceResolution = new Vector2(1920f, 1080f);
				component.screenMatchMode = (ScreenMatchMode)1;
				val2.GetComponent<GraphicRaycaster>();
				val2.layer = LayerMask.NameToLayer("UI");
				Plugin.Log.LogDebug((object)"Canvas_PassedOutMarkers created");
			}
		}

		private void CreateTemplate()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0082: 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)
			if (!((Object)(object)template != (Object)null))
			{
				template = new GameObject("PassedOutMarker", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(PassedOut)
				});
				template.transform.SetParent(((Component)passedOutCanvas).transform);
				GameObject val = AddTMPChildren("StatusText", template.transform, new Vector2(200f, 80f));
				val.transform.SetParent(template.transform, true);
				TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component).fontSize = 35f;
				((TMP_Text)component).outlineWidth = 0f;
				((TMP_Text)component).alignment = (TextAlignmentOptions)258;
				GameObject val2 = AddTMPChildren("DistanceText", template.transform, new Vector2(200f, 60f));
				TextMeshProUGUI component2 = val2.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component2).fontStyle = (FontStyles)1;
				((TMP_Text)component2).alignment = (TextAlignmentOptions)1026;
				template.SetActive(false);
				Plugin.Log.LogDebug((object)"PassedOutMarker template created");
			}
		}

		private GameObject AddTMPChildren(string name, Transform parent, Vector2 size)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0074: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00f5: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)font == (Object)null)
			{
				FindFont();
			}
			GameObject val = new GameObject(name, new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(TextMeshProUGUI),
				typeof(Shadow)
			});
			val.transform.SetParent(parent, true);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = size;
			TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component2).font = font;
			((TMP_Text)component2).fontMaterial = fontMaterial;
			((TMP_Text)component2).fontSize = 20f;
			((Graphic)component2).color = Color.white;
			((TMP_Text)component2).outlineWidth = 0.2f;
			((TMP_Text)component2).outlineColor = Color32.op_Implicit(Color.black);
			((TMP_Text)component2).enableAutoSizing = false;
			((TMP_Text)component2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)component2).horizontalAlignment = (HorizontalAlignmentOptions)2;
			((TMP_Text)component2).verticalAlignment = (VerticalAlignmentOptions)512;
			Shadow component3 = val.GetComponent<Shadow>();
			component3.effectColor = new Color(0f, 0f, 0f, 0.95f);
			component3.effectDistance = new Vector2(2f, -2f);
			return val;
		}

		public void CreateInstance(Character character)
		{
			if (!((Object)(object)passedOutCanvas == (Object)null) && !((Object)(object)template == (Object)null) && !(((Object)character).name == ((Object)Character.localCharacter).name))
			{
				UpdateInstance(character);
				GameObject val = Object.Instantiate<GameObject>(template, ((Component)passedOutCanvas).transform);
				PassedOut component = val.GetComponent<PassedOut>();
				component.character = character;
				val.SetActive(true);
				passedOutInstances[character] = val;
			}
		}

		public void UpdateInstance(Character character, bool isDead = false)
		{
			if (passedOutInstances.TryGetValue(character, out GameObject value) && (Object)(object)value != (Object)null)
			{
				if (isDead)
				{
					value.GetComponent<PassedOut>().hasDied();
					RemoveInstance(value, Plugin.BoundConfig.General.deadTimer.Value);
				}
				else
				{
					RemoveInstance(value);
				}
			}
		}

		private void RemoveInstance(GameObject instance, float delay = 0f)
		{
			Object.Destroy((Object)(object)instance, delay);
		}
	}
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "lucyddemon.downedawareness";

		public const string PLUGIN_NAME = "DownedAwareness";

		public const string PLUGIN_VERSION = "1.0.3";

		public const string PLUGIN_AUTHOR = "LucydDemon";
	}
}
namespace DownedAwareness.Patches
{
	[HarmonyPatch(typeof(Character))]
	internal static class CharacterPatch
	{
		[HarmonyPatch("RPCA_PassOut")]
		[HarmonyPostfix]
		private static void RPCA_PassOut_Postfix(Character __instance)
		{
			Plugin.POM.CreateInstance(__instance);
			Plugin.Log.LogDebug((object)("PassedOut " + ((Object)__instance).name));
		}

		[HarmonyPatch("RPCA_UnPassOut")]
		[HarmonyPostfix]
		private static void RPCA_UnPassOut_Postfix(Character __instance)
		{
			Plugin.POM.UpdateInstance(__instance);
			Plugin.Log.LogDebug((object)("UnPassedOut " + ((Object)__instance).name));
		}

		[HarmonyPatch("RPCA_Revive")]
		[HarmonyPostfix]
		private static void RPCA_Revive_Postfix(Character __instance)
		{
			Plugin.POM.UpdateInstance(__instance);
			Plugin.Log.LogDebug((object)("Revived " + ((Object)__instance).name));
		}

		[HarmonyPatch("RPCA_Die")]
		[HarmonyPostfix]
		private static void RPCA_Die_Postfix(Character __instance)
		{
			Plugin.POM.UpdateInstance(__instance, isDead: true);
			Plugin.Log.LogDebug((object)("Died " + ((Object)__instance).name));
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPostfix]
		private static void OnDestroy_Postfix(Character __instance)
		{
			Plugin.POM.UpdateInstance(__instance);
			Plugin.Log.LogDebug((object)("Destroyed " + ((Object)__instance).name));
		}
	}
	[HarmonyPatch(typeof(GUIManager))]
	internal static class GUIManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void Start_Postfix(GUIManager __instance)
		{
			Plugin.POM.Initialize();
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPostfix]
		private static void LateUpdate_Postfix(GUIManager __instance)
		{
			if (!Plugin.POM.isInitialized)
			{
				Plugin.POM.Initialize();
			}
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPostfix]
		private static void OnDestroy_Postfix(GUIManager __instance)
		{
			Plugin.POM.OnDestroy();
		}
	}
}