Decompiled source of FirstPersonDeath v1.2.4

FirstPersonDeath.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FirstPersonDeath.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using TMPro;
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("FirstPersonDeath")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FirstPersonDeath")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("94edb759-c44e-4b9e-8486-12654b79b044")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FirstPersonDeath
{
	[BepInPlugin("rogan.FirstPersonDeath", "First Person Death", "1.2.4")]
	public class FirstPersonDeathBase : BaseUnityPlugin
	{
		private const string modGUID = "rogan.FirstPersonDeath";

		private const string modName = "First Person Death";

		private const string modVersion = "1.2.4";

		private readonly Harmony harmony = new Harmony("rogan.FirstPersonDeath");

		private static FirstPersonDeathBase Instance;

		internal static ManualLogSource mls;

		public static ConfigEntry<string> SwapKey;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			LoadConfigs();
			mls = Logger.CreateLogSource("rogan.FirstPersonDeath");
			mls.LogInfo((object)"FirstPersonDeath Started!");
			harmony.PatchAll(typeof(FirstPersonDeathBase));
			harmony.PatchAll(typeof(KeyDownPatch));
			harmony.PatchAll(typeof(KillPlayerPatch));
			harmony.PatchAll(typeof(HudManagerPatch));
			harmony.PatchAll(typeof(MaskedPlayerPatch));
			harmony.PatchAll(typeof(PlayerControllerPatch));
		}

		private void LoadConfigs()
		{
			SwapKey = ((BaseUnityPlugin)this).Config.Bind<string>("FirstPersonDeath", "SwapKey", "E", "Key used to toggle perspectives; Default binding may conflict with other mods!");
		}
	}
}
namespace FirstPersonDeath.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class KeyDownPatch
	{
		public static KeyCode SwapKeyCode = (KeyCode)Enum.Parse(typeof(KeyCode), FirstPersonDeathBase.SwapKey.Value);

		public static KeyboardShortcut SwapKey = new KeyboardShortcut(SwapKeyCode, Array.Empty<KeyCode>());

		public static bool SwapKeyDown = false;

		public static bool UsePlayerCamera = false;

		public static string LastSpectatedPlayer = "";

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void SwapPatch()
		{
			if (GameNetworkManager.Instance.localPlayerController.isPlayerDead)
			{
				if (((KeyboardShortcut)(ref SwapKey)).IsDown())
				{
					if (!SwapKeyDown)
					{
						UsePlayerCamera = !UsePlayerCamera;
						SwapKeyDown = true;
					}
				}
				else if (((KeyboardShortcut)(ref SwapKey)).IsUp())
				{
					SwapKeyDown = false;
				}
			}
			else
			{
				UsePlayerCamera = true;
			}
		}
	}
	internal class KillPlayerPatch
	{
		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> DeathLengthPatch(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4 && list[i].operand.ToString() == "1.5")
				{
					list[i].operand = 0f;
					FirstPersonDeathBase.mls.LogInfo((object)"Patched death camera time!");
				}
			}
			return list;
		}
	}
	internal class HudManagerPatch
	{
		[HarmonyPatch(typeof(HUDManager), "Update")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> EarlyVotePatch(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Ldstr && list[i].operand.ToString() == "Tell autopilot ship to leave early : [RMB] (Hold)")
				{
					CodeInstruction obj = list[i];
					CodeInstruction obj2 = list[i];
					obj.operand = (obj2.operand = obj2.operand?.ToString() + "\n\n\n\n\nSwitch Camera: [" + FirstPersonDeathBase.SwapKey.Value + "]");
					FirstPersonDeathBase.mls.LogInfo((object)"Patched vote leave text!");
				}
				else if (list[i].opcode == OpCodes.Ldstr && (list[i].operand.ToString() == "Voted for ship to leave early" || list[i].operand.ToString() == "Ship leaving in one hour"))
				{
					CodeInstruction obj3 = list[i];
					CodeInstruction obj4 = list[i];
					obj3.operand = (obj4.operand = obj4.operand?.ToString() + "\n\n\n\n\n\nSwitch Camera: [" + FirstPersonDeathBase.SwapKey.Value + "]");
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	internal class MaskedPlayerPatch
	{
		public static Transform MaskedTransform;

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void GetMaskedPatch(ref PlayerControllerB ___mimickingPlayer, Transform ___headTiltTarget)
		{
			if (Object.op_Implicit((Object)(object)___mimickingPlayer) && ___mimickingPlayer.playerUsername == PlayerControllerPatch.PlayerUsername)
			{
				MaskedTransform = ___headTiltTarget;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerPatch
	{
		public static PlayerControllerB RoundController;

		public static PlayerControllerB NetworkController;

		public static GameObject MeshModel;

		public static Rigidbody[] BodyParts;

		public static DeadBodyInfo[] DeadMesh;

		public static GameObject PivotCamera;

		public static GameObject CameraHolder;

		public static GameObject SpectateCamera;

		public static AudioListener AudioListener;

		public static int ClientId;

		public static string PlayerUsername;

		public static string SpectatedPlayer;

		public static PlayerControllerB[] AllPlayers;

		public static bool PlayerBody = true;

		public static bool PlayerUnderwater = false;

		public static bool PlayerDecapitated = false;

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

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void FirstPersonPatch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Invalid comparison between Unknown and I4
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Invalid comparison between Unknown and I4
			//IL_07fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0892: Unknown result type (might be due to invalid IL or missing references)
			//IL_0853: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c5: Unknown result type (might be due to invalid IL or missing references)
			if ((!PlayerBody && (int)NetworkController.causeOfDeath != 4) || !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) || !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null))
			{
				return;
			}
			RoundController = StartOfRound.Instance.localPlayerController;
			NetworkController = GameNetworkManager.Instance.localPlayerController;
			PivotCamera = ((Component)RoundController.spectateCameraPivot).gameObject;
			SpectateCamera = ((Component)StartOfRound.Instance.spectateCamera).gameObject;
			PlayerUsername = NetworkController.playerUsername;
			ClientId = (int)NetworkController.playerClientId;
			MeshModel = ((Component)NetworkController.thisPlayerModel).gameObject;
			if (!NetworkController.isPlayerDead)
			{
				PlayerUnderwater = NetworkController.isUnderwater;
			}
			if (!NetworkController.isPlayerDead)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)NetworkController.spectatedPlayerScript))
			{
				SpectatedPlayer = NetworkController.spectatedPlayerScript.playerUsername;
			}
			AllPlayers = StartOfRound.Instance.allPlayerScripts;
			if (SpectatedPlayer == PlayerUsername)
			{
				for (int i = 0; i < AllPlayers.Length; i++)
				{
					if (AllPlayers[i].playerUsername != PlayerUsername && !AllPlayers[i].playerUsername.Contains("Player #"))
					{
						NetworkController.spectatedPlayerScript = AllPlayers[i];
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)AudioListener))
			{
				AudioListener = Object.FindObjectOfType<AudioListener>();
			}
			if (!Object.op_Implicit((Object)(object)CameraHolder))
			{
				if (DeadMesh == null)
				{
					FirstPersonDeathBase.mls.LogInfo((object)"Player dead! >.<");
				}
				if ((int)NetworkController.causeOfDeath == 4)
				{
					if (Object.op_Implicit((Object)(object)MaskedPlayerPatch.MaskedTransform))
					{
						CameraHolder = ((Component)MaskedPlayerPatch.MaskedTransform).gameObject;
					}
					else
					{
						DeadMesh = Object.FindObjectsOfType<DeadBodyInfo>();
						DeadBodyInfo[] deadMesh = DeadMesh;
						foreach (DeadBodyInfo val in deadMesh)
						{
							if (val.playerObjectId != ClientId)
							{
								continue;
							}
							BodyParts = val.bodyParts;
							Rigidbody[] bodyParts = BodyParts;
							foreach (Rigidbody val2 in bodyParts)
							{
								if (((Object)val2).name == "spine.004")
								{
									FirstPersonDeathBase.mls.LogInfo((object)"Found player head! :D");
									CameraHolder = ((Component)val2).gameObject;
								}
							}
						}
					}
				}
				else
				{
					DeadMesh = Object.FindObjectsOfType<DeadBodyInfo>();
					DeadBodyInfo[] deadMesh2 = DeadMesh;
					foreach (DeadBodyInfo val3 in deadMesh2)
					{
						if (val3.playerObjectId != ClientId)
						{
							continue;
						}
						BodyParts = val3.bodyParts;
						Rigidbody[] bodyParts2 = BodyParts;
						foreach (Rigidbody val4 in bodyParts2)
						{
							if (((Object)val4).name == "spine.004")
							{
								FirstPersonDeathBase.mls.LogInfo((object)"Found player head! :D");
								CameraHolder = ((Component)val4).gameObject;
							}
						}
						if (!Object.op_Implicit((Object)(object)CameraHolder) && (Object)(object)val3.detachedHeadObject != (Object)null)
						{
							PlayerDecapitated = true;
							CameraHolder = ((Component)val3.detachedHeadObject).gameObject;
							FirstPersonDeathBase.mls.LogInfo((object)"Player died to coilhead! >.<");
						}
					}
				}
			}
			if (StartOfRound.Instance.shipIsLeaving)
			{
				PlayerNames.Clear();
				PlayerDecapitated = false;
				if (StartOfRound.Instance.allPlayersDead)
				{
					NetworkController.spectatedPlayerScript = null;
					((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = "";
				}
				else
				{
					((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = "(Spectating: " + SpectatedPlayer + ")";
				}
				HUDManager.Instance.setUnderwaterFilter = false;
				StartOfRound.Instance.overrideSpectateCamera = false;
				SpectateCamera.transform.parent = PivotCamera.transform;
				SpectateCamera.transform.position = PivotCamera.transform.position;
				return;
			}
			if (KeyDownPatch.UsePlayerCamera)
			{
				if (Object.op_Implicit((Object)(object)MaskedPlayerPatch.MaskedTransform))
				{
					MeshRenderer[] componentsInChildren = ((Component)MaskedPlayerPatch.MaskedTransform.root).gameObject.GetComponentsInChildren<MeshRenderer>();
					MeshRenderer[] array = componentsInChildren;
					foreach (MeshRenderer val5 in array)
					{
						((Renderer)val5).enabled = false;
					}
					SkinnedMeshRenderer[] componentsInChildren2 = ((Component)MaskedPlayerPatch.MaskedTransform.root).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
					SkinnedMeshRenderer[] array2 = componentsInChildren2;
					foreach (SkinnedMeshRenderer val6 in array2)
					{
						((Renderer)val6).enabled = false;
					}
				}
				if (PlayerUnderwater)
				{
					HUDManager.Instance.setUnderwaterFilter = true;
				}
				((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = "";
				StartOfRound.Instance.overrideSpectateCamera = true;
				((Component)AudioListener).gameObject.transform.parent = SpectateCamera.transform;
				((Component)AudioListener).gameObject.transform.localPosition = new Vector3(0f, 0f, 0f);
			}
			else
			{
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val7 in allPlayerScripts)
				{
					if (!val7.playerUsername.Contains("Player #") && !PlayerNames.Contains(val7.playerUsername))
					{
						FirstPersonDeathBase.mls.LogInfo((object)("Added " + val7.playerUsername + " to PlayerNames!"));
						PlayerNames.Add(val7.playerUsername);
					}
				}
				if (PlayerNames.Count == 1)
				{
					return;
				}
				if ((int)NetworkController.causeOfDeath == 4 && Object.op_Implicit((Object)(object)MaskedPlayerPatch.MaskedTransform))
				{
					MeshRenderer[] componentsInChildren3 = ((Component)MaskedPlayerPatch.MaskedTransform.root).gameObject.GetComponentsInChildren<MeshRenderer>();
					MeshRenderer[] array3 = componentsInChildren3;
					foreach (MeshRenderer val8 in array3)
					{
						((Renderer)val8).enabled = true;
					}
					SkinnedMeshRenderer[] componentsInChildren4 = ((Component)MaskedPlayerPatch.MaskedTransform.root).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
					SkinnedMeshRenderer[] array4 = componentsInChildren4;
					foreach (SkinnedMeshRenderer val9 in array4)
					{
						((Renderer)val9).enabled = true;
					}
				}
				if (((TMP_Text)HUDManager.Instance.spectatingPlayerText).text == "")
				{
					((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = "(Spectating: " + SpectatedPlayer + ")";
				}
				HUDManager.Instance.setUnderwaterFilter = false;
				StartOfRound.Instance.overrideSpectateCamera = false;
				((Component)AudioListener).gameObject.transform.parent = PivotCamera.transform;
				((Component)AudioListener).gameObject.transform.localPosition = new Vector3(0f, 0f, 0f);
			}
			if (Object.op_Implicit((Object)(object)CameraHolder))
			{
				if ((Object)(object)SpectateCamera.transform.parent != (Object)(object)CameraHolder.transform)
				{
					SpectateCamera.transform.position = CameraHolder.transform.position;
				}
				SpectateCamera.transform.parent = CameraHolder.transform;
				SpectateCamera.transform.localPosition = new Vector3(0f, 0f, 0.2f);
				if (!PlayerDecapitated)
				{
					SpectateCamera.transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
				}
				else
				{
					SpectateCamera.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
				}
			}
			else
			{
				StartOfRound.Instance.overrideSpectateCamera = false;
				PlayerBody = false;
			}
		}
	}
}