Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of FirstPersonDeath v1.3.6
FirstPersonDeath.dll
Decompiled 9 months agousing 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.3.6")] public class FirstPersonDeathBase : BaseUnityPlugin { private const string modGUID = "rogan.FirstPersonDeath"; private const string modName = "First Person Death"; private const string modVersion = "1.3.6"; private readonly Harmony harmony = new Harmony("rogan.FirstPersonDeath"); private static FirstPersonDeathBase Instance; internal static ManualLogSource mls; public static ConfigEntry<string> SwapKey; public static ConfigEntry<float> SwapTime; 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"); SwapTime = ((BaseUnityPlugin)this).Config.Bind<float>("FirstPersonDeath", "SwapTime", 0f, "How long to stay in first person; Set this to 0 to disable auto swap to spectate"); } } } 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; [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 bPlayerBody = true; public static bool bPlayerUnderwater = false; public static bool bPlayerDecapitated = false; public static bool bAcknowledgedLeaving = false; public static bool bAcknowledgedUnderwater = false; public static bool bSetTimer = true; public static float Timer = 0f; public static float TimerDuration = FirstPersonDeathBase.SwapTime.Value; 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_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Invalid comparison between Unknown and I4 //IL_07da: Unknown result type (might be due to invalid IL or missing references) //IL_066f: Unknown result type (might be due to invalid IL or missing references) //IL_0898: Unknown result type (might be due to invalid IL or missing references) //IL_089e: Invalid comparison between Unknown and I4 //IL_09d8: Unknown result type (might be due to invalid IL or missing references) //IL_0a70: Unknown result type (might be due to invalid IL or missing references) //IL_0a31: Unknown result type (might be due to invalid IL or missing references) //IL_0acb: Unknown result type (might be due to invalid IL or missing references) //IL_0aa3: Unknown result type (might be due to invalid IL or missing references) if ((!bPlayerBody && (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) { if (bAcknowledgedLeaving || bAcknowledgedUnderwater) { FirstPersonDeathBase.mls.LogInfo((object)("Resetting acknowledgements for " + PlayerUsername + "!")); bAcknowledgedLeaving = false; bAcknowledgedUnderwater = false; } bPlayerUnderwater = NetworkController.isUnderwater; } if (!NetworkController.isPlayerDead) { return; } if (bSetTimer && !StartOfRound.Instance.shipIsLeaving) { Timer += Time.fixedDeltaTime / 6.5f; } if (Timer > TimerDuration && bSetTimer && !StartOfRound.Instance.shipIsLeaving && TimerDuration != 0f) { Timer = 0f; bSetTimer = false; FirstPersonDeathBase.mls.LogInfo((object)("Timer for " + PlayerUsername + " expired!")); KeyDownPatch.UsePlayerCamera = false; } 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]; string[] array = AllPlayers[i].playerUsername.Split(new char[1] { ' ' }); foreach (string text in array) { FirstPersonDeathBase.mls.LogInfo((object)text); } } } } 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)(PlayerUsername + " died!")); } 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 head node of " + PlayerUsername + "!")); 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 head node of " + PlayerUsername + "!")); CameraHolder = ((Component)val4).gameObject; } } if (!Object.op_Implicit((Object)(object)CameraHolder) && (Object)(object)val3.detachedHeadObject != (Object)null) { bPlayerDecapitated = true; CameraHolder = ((Component)val3.detachedHeadObject).gameObject; FirstPersonDeathBase.mls.LogInfo((object)(PlayerUsername + " was killed by coilhead!")); } } } } if (StartOfRound.Instance.shipIsLeaving) { if (!bAcknowledgedLeaving) { FirstPersonDeathBase.mls.LogInfo((object)"Ship is leaving; reverting to normal spectate!"); bAcknowledgedLeaving = true; } PlayerNames.Clear(); bSetTimer = true; bPlayerDecapitated = 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)) { FirstPersonDeathBase.mls.LogInfo((object)"Spectating masked; disabling renderer!"); MeshRenderer[] componentsInChildren = ((Component)MaskedPlayerPatch.MaskedTransform.root).gameObject.GetComponentsInChildren<MeshRenderer>(); MeshRenderer[] array2 = componentsInChildren; foreach (MeshRenderer val5 in array2) { ((Renderer)val5).enabled = false; } SkinnedMeshRenderer[] componentsInChildren2 = ((Component)MaskedPlayerPatch.MaskedTransform.root).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(); SkinnedMeshRenderer[] array3 = componentsInChildren2; foreach (SkinnedMeshRenderer val6 in array3) { ((Renderer)val6).enabled = false; } } if (bPlayerUnderwater) { if (!bAcknowledgedUnderwater) { FirstPersonDeathBase.mls.LogInfo((object)(PlayerUsername + " is underwater!")); bAcknowledgedUnderwater = true; } 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[] array4 = componentsInChildren3; foreach (MeshRenderer val8 in array4) { ((Renderer)val8).enabled = true; } SkinnedMeshRenderer[] componentsInChildren4 = ((Component)MaskedPlayerPatch.MaskedTransform.root).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(); SkinnedMeshRenderer[] array5 = componentsInChildren4; foreach (SkinnedMeshRenderer val9 in array5) { ((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 (!bPlayerDecapitated) { SpectateCamera.transform.localRotation = Quaternion.Euler(0f, 0f, 0f); } else { SpectateCamera.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); } } else { StartOfRound.Instance.overrideSpectateCamera = false; bPlayerBody = false; } } } }