diff --git a/QSB/DeathSync/Events/PlayerDeathEvent.cs b/QSB/DeathSync/Events/PlayerDeathEvent.cs index f70e5444..452f4c91 100644 --- a/QSB/DeathSync/Events/PlayerDeathEvent.cs +++ b/QSB/DeathSync/Events/PlayerDeathEvent.cs @@ -20,11 +20,20 @@ namespace QSB.DeathSync.Events NecronomiconIndex = Necronomicon.GetRandomIndex(type) }; + public override void OnReceiveLocal(bool server, PlayerDeathMessage message) + { + var player = QSBPlayerManager.GetPlayer(message.AboutId); + RespawnManager.Instance.OnPlayerDeath(player); + } + public override void OnReceiveRemote(bool server, PlayerDeathMessage message) { - var playerName = QSBPlayerManager.GetPlayer(message.AboutId).Name; + var player = QSBPlayerManager.GetPlayer(message.AboutId); + var playerName = player.Name; var deathMessage = Necronomicon.GetPhrase(message.EnumValue, message.NecronomiconIndex); DebugLog.ToAll(string.Format(deathMessage, playerName)); + + RespawnManager.Instance.OnPlayerDeath(player); } } } \ No newline at end of file diff --git a/QSB/DeathSync/Events/PlayerRespawnEvent.cs b/QSB/DeathSync/Events/PlayerRespawnEvent.cs new file mode 100644 index 00000000..2b10616e --- /dev/null +++ b/QSB/DeathSync/Events/PlayerRespawnEvent.cs @@ -0,0 +1,37 @@ +using QSB.Events; +using QSB.Messaging; +using QSB.Player; + +namespace QSB.DeathSync.Events +{ + class PlayerRespawnEvent : QSBEvent + { + public override EventType Type => EventType.PlayerRespawn; + + public override void SetupListener() + => GlobalMessenger.AddListener(EventNames.QSBPlayerRespawn, Handler); + + public override void CloseListener() + => GlobalMessenger.RemoveListener(EventNames.QSBPlayerRespawn, Handler); + + private void Handler(uint playerId) => SendEvent(CreateMessage(playerId)); + + private PlayerMessage CreateMessage(uint playerId) => new PlayerMessage + { + AboutId = playerId + }; + + public override void OnReceiveLocal(bool server, PlayerMessage message) + => OnReceiveRemote(server, message); + + public override void OnReceiveRemote(bool server, PlayerMessage message) + { + if (message.AboutId == LocalPlayerId) + { + RespawnManager.Instance.Respawn(); + } + + RespawnManager.Instance.OnPlayerRespawn(QSBPlayerManager.GetPlayer(message.AboutId)); + } + } +} diff --git a/QSB/DeathSync/Patches/MapPatches.cs b/QSB/DeathSync/Patches/MapPatches.cs index 78e2d5fe..e1f673d7 100644 --- a/QSB/DeathSync/Patches/MapPatches.cs +++ b/QSB/DeathSync/Patches/MapPatches.cs @@ -1,12 +1,13 @@ using OWML.Utils; using QSB.Patches; +using QSB.Utility; using UnityEngine; namespace QSB.DeathSync.Patches { class MapPatches : QSBPatch { - public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; + public override QSBPatchTypes Type => QSBPatchTypes.RespawnTime; public override void DoPatches() { @@ -100,12 +101,10 @@ namespace QSB.DeathSync.Patches public static bool MapController_LateUpdate( MapController __instance, - bool ____isMapMode, ref float ____observatoryRevealTwist, ref float ____defaultPitchAngle, ref float ____initialPitchAngle, OWCamera ____mapCamera, - ReferenceFrame ____currentRFrame, ref float ____lockTimer, ref float ____revealTimer, float ____lockOnMoveLength, @@ -121,9 +120,7 @@ namespace QSB.DeathSync.Patches ref bool ____interpPosition, ref bool ____interpPitch, ref bool ____interpZoom, - ref bool ____framingPlayer, OWCamera ____activeCam, - Transform ____targetTransform, ref Vector3 ____position, float ____panSpeed, ref float ____zoom, @@ -143,135 +140,97 @@ namespace QSB.DeathSync.Patches float ____observatoryRevealDist ) { - if (!____isMapMode) + ____lockTimer = Mathf.Min(____lockTimer + Time.deltaTime, ____lockOnMoveLength); + ____revealTimer = Mathf.Min(____revealTimer + Time.deltaTime, ____revealLength); + var num = Mathf.Clamp01(____revealTimer / ____revealLength); + var t3 = Mathf.SmoothStep(0f, 1f, num); + var flag = ____revealTimer > ____observatoryInteractDelay; + if (____screenPromptsVisible && ____isPaused) { - if (OWInput.IsInputMode(InputMode.Character | InputMode.ShipCockpit) && OWInput.IsNewlyPressed(InputLibrary.map, InputMode.All)) - { - if (PlayerState.InBrambleDimension() || PlayerState.OnQuantumMoon()) - { - NotificationManager.SharedInstance.PostNotification(new NotificationData(UITextLibrary.GetString(UITextType.NotificationUnableToOpenMap)), false); - } - else - { - __instance.GetType().GetAnyMethod("EnterMapView").Invoke(__instance, new object[] { (____currentRFrame == null || !(____currentRFrame.GetOWRigidBody() != null)) ? null : ____currentRFrame.GetOWRigidBody().transform }); - } - } + ____closePrompt.SetVisibility(false); + ____panPrompt.SetVisibility(false); + ____rotatePrompt.SetVisibility(false); + ____zoomPrompt.SetVisibility(false); + ____screenPromptsVisible = false; + } + else if (!____screenPromptsVisible && flag && !____isPaused) + { + ____closePrompt.SetVisibility(false); + ____panPrompt.SetVisibility(true); + ____rotatePrompt.SetVisibility(true); + ____zoomPrompt.SetVisibility(true); + ____screenPromptsVisible = true; + } + + var vector = Vector2.zero; + var vector2 = Vector2.zero; + var num2 = 0f; + if (flag) + { + vector = OWInput.GetValue(InputLibrary.moveXZ, InputMode.All); + vector2 = InputLibrary.look.GetValue(false); + num2 = OWInput.GetValue(InputLibrary.mapZoom, InputMode.All); + vector2.y *= -1f; + num2 *= -1f; + } + + ____lockedToTargetTransform &= vector.sqrMagnitude < 0.01f; + ____interpPosition &= vector.sqrMagnitude < 0.01f; + ____interpPitch &= Mathf.Abs(vector2.y) < 0.1f; + ____interpZoom &= Mathf.Abs(num2) < 0.1f; + + if (____interpPosition) + { + var a = ____activeCam.transform.position - Locator.GetCenterOfTheUniverse().GetOffsetPosition(); + var b = Vector3.zero; + ____position = Vector3.Lerp(a, b, t3); } else { - ____lockTimer = Mathf.Min(____lockTimer + Time.deltaTime, ____lockOnMoveLength); - var t = Mathf.Clamp01(____lockTimer / ____lockOnMoveLength); - ____revealTimer = Mathf.Min(____revealTimer + Time.deltaTime, ____revealLength); - var num = Mathf.Clamp01(____revealTimer / ____revealLength); - var t3 = Mathf.SmoothStep(0f, 1f, num); - var flag = ____revealTimer > ____observatoryInteractDelay; - if (____screenPromptsVisible && ____isPaused) + var normalized = Vector3.Scale(__instance.transform.forward + __instance.transform.up, new Vector3(1f, 0f, 1f)).normalized; + var a2 = (__instance.transform.right * vector.x) + (normalized * vector.y); + ____position += a2 * ____panSpeed * ____zoom * Time.deltaTime; + ____position.y = 0f; + if (____position.sqrMagnitude > ____maxPanDistance * ____maxPanDistance) { - ____closePrompt.SetVisibility(false); - ____panPrompt.SetVisibility(false); - ____rotatePrompt.SetVisibility(false); - ____zoomPrompt.SetVisibility(false); - ____screenPromptsVisible = false; + ____position = ____position.normalized * ____maxPanDistance; } - else if (!____screenPromptsVisible && flag && !____isPaused) - { - ____closePrompt.SetVisibility(false); - ____panPrompt.SetVisibility(true); - ____rotatePrompt.SetVisibility(true); - ____zoomPrompt.SetVisibility(true); - ____screenPromptsVisible = true; - } - - var vector = Vector2.zero; - var vector2 = Vector2.zero; - var num2 = 0f; - if (flag) - { - vector = OWInput.GetValue(InputLibrary.moveXZ, InputMode.All); - vector2 = InputLibrary.look.GetValue(false); - num2 = OWInput.GetValue(InputLibrary.mapZoom, InputMode.All); - vector2.y *= -1f; - num2 *= -1f; - } - - ____lockedToTargetTransform &= vector.sqrMagnitude < 0.01f; - ____interpPosition &= vector.sqrMagnitude < 0.01f; - ____interpPitch &= Mathf.Abs(vector2.y) < 0.1f; - ____interpZoom &= Mathf.Abs(num2) < 0.1f; - ____framingPlayer &= ____lockedToTargetTransform && ____interpZoom; - if (____interpPosition) - { - var a = ____activeCam.transform.position - Locator.GetCenterOfTheUniverse().GetOffsetPosition(); - var b = Vector3.zero; - if (____lockedToTargetTransform && ____targetTransform != null) - { - b = ____targetTransform.position - Locator.GetCenterOfTheUniverse().GetOffsetPosition(); - b.y = 0f; - } - - ____position = Vector3.Lerp(a, b, t3); - } - else if (____lockedToTargetTransform && ____targetTransform != null) - { - var vector3 = ____targetTransform.position; - vector3 -= Locator.GetCenterOfTheUniverse().GetOffsetPosition(); - vector3.y = 0f; - ____position = Vector3.Lerp(____position, vector3, t); - } - else - { - var normalized = Vector3.Scale(__instance.transform.forward + __instance.transform.up, new Vector3(1f, 0f, 1f)).normalized; - var a2 = (__instance.transform.right * vector.x) + (normalized * vector.y); - ____position += a2 * ____panSpeed * ____zoom * Time.deltaTime; - ____position.y = 0f; - if (____position.sqrMagnitude > ____maxPanDistance * ____maxPanDistance) - { - ____position = ____position.normalized * ____maxPanDistance; - } - } - - ____yaw += vector2.x * ____yawSpeed * Time.deltaTime; - ____yaw = OWMath.WrapAngle(____yaw); - if (____interpPitch) - { - ____pitch = Mathf.Lerp(____initialPitchAngle, ____defaultPitchAngle, t3); - } - else - { - ____pitch += vector2.y * ____pitchSpeed * Time.deltaTime; - ____pitch = Mathf.Clamp(____pitch, ____minPitchAngle, ____maxPitchAngle); - } - - if (____interpZoom) - { - if (____framingPlayer) - { - var num3 = Vector3.Distance(____playerTransform.position, ____targetTransform.position); - var value = num3 / Mathf.Tan(0.017453292f * ____mapCamera.fieldOfView * 0.5f) * 1.33f; - ____targetZoom = Mathf.Clamp(value, ____minZoomDistance, ____maxZoomDistance); - } - - ____zoom = Mathf.Lerp(____initialZoomDist, ____targetZoom, t3); - } - else - { - ____zoom += num2 * ____zoomSpeed * Time.deltaTime; - ____zoom = Mathf.Clamp(____zoom, ____minZoomDistance, ____maxZoomDistance); - } - - ____mapCamera.nearClipPlane = Mathf.Lerp(0.1f, 1f, t3); - var quaternion = Quaternion.Euler(____pitch, ____yaw, 0f); - var num4 = num * (2f - num); - var num5 = Mathf.SmoothStep(0f, 1f, num4); - var a3 = Quaternion.LookRotation(-____playerTransform.up, Vector3.up); - var a4 = ____activeCam.transform.position; - a4 += ____playerTransform.up * num5 * ____observatoryRevealDist; - __instance.transform.rotation = Quaternion.Lerp(a3, quaternion, num5); - __instance.transform.rotation *= Quaternion.AngleAxis(Mathf.Lerp(____observatoryRevealTwist, 0f, num4), Vector3.forward); - var vector4 = ____position + (-__instance.transform.forward * ____zoom) + Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition(); - __instance.transform.position = Vector3.Lerp(a4, vector4, num5); } + ____yaw += vector2.x * ____yawSpeed * Time.deltaTime; + ____yaw = OWMath.WrapAngle(____yaw); + if (____interpPitch) + { + ____pitch = Mathf.Lerp(____initialPitchAngle, ____defaultPitchAngle, t3); + } + else + { + ____pitch += vector2.y * ____pitchSpeed * Time.deltaTime; + ____pitch = Mathf.Clamp(____pitch, ____minPitchAngle, ____maxPitchAngle); + } + + if (____interpZoom) + { + ____zoom = Mathf.Lerp(____initialZoomDist, ____targetZoom, t3); + } + else + { + ____zoom += num2 * ____zoomSpeed * Time.deltaTime; + ____zoom = Mathf.Clamp(____zoom, ____minZoomDistance, ____maxZoomDistance); + } + + ____mapCamera.nearClipPlane = Mathf.Lerp(0.1f, 1f, t3); + var quaternion = Quaternion.Euler(____pitch, ____yaw, 0f); + var num4 = num * (2f - num); + var num5 = Mathf.SmoothStep(0f, 1f, num4); + var a3 = Quaternion.LookRotation(-____playerTransform.up, Vector3.up); + var a4 = ____activeCam.transform.position; + a4 += ____playerTransform.up * num5 * ____observatoryRevealDist; + __instance.transform.rotation = Quaternion.Lerp(a3, quaternion, num5); + __instance.transform.rotation *= Quaternion.AngleAxis(Mathf.Lerp(____observatoryRevealTwist, 0f, num4), Vector3.forward); + var vector4 = ____position + (-__instance.transform.forward * ____zoom) + Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition(); + __instance.transform.position = Vector3.Lerp(a4, vector4, num5); + return false; } } diff --git a/QSB/DeathSync/Patches/RespawnPatches.cs b/QSB/DeathSync/Patches/RespawnPatches.cs new file mode 100644 index 00000000..b3b81c70 --- /dev/null +++ b/QSB/DeathSync/Patches/RespawnPatches.cs @@ -0,0 +1,166 @@ +using OWML.Utils; +using QSB.Patches; + +namespace QSB.DeathSync.Patches +{ + class RespawnPatches : QSBPatch + { + public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; + + public override void DoPatches() + { + Prefix(nameof(PlayerRecoveryPoint_OnGainFocus)); + Prefix(nameof(PlayerRecoveryPoint_OnPressInteract)); + } + + public static bool PlayerRecoveryPoint_OnGainFocus( + PlayerResources ____playerResources, + bool ____refuelsPlayer, + bool ____healsPlayer, + SingleInteractionVolume ____interactVolume + ) + { + if (____playerResources == null) + { + ____playerResources = Locator.GetPlayerTransform().GetComponent(); + } + + var isAtFullHealth = ____playerResources.GetHealthFraction() == 1f; + var isAtFullFuel = ____playerResources.GetFuelFraction() == 1f; + var canBeRefueled = false; + var canBeHealed = false; + + if (!isAtFullFuel && ____refuelsPlayer) + { + canBeRefueled = true; + } + + if (!isAtFullHealth && ____healsPlayer) + { + canBeHealed = true; + } + + var showRespawnPrompt = false; + + var uitextType = UITextType.None; + if (canBeHealed && canBeRefueled) + { + // Heal and refuel + uitextType = UITextType.RefillPrompt_0; + + ____interactVolume.SetKeyCommandVisible(true); + } + else if (canBeHealed) + { + // Heal + uitextType = UITextType.RefillPrompt_2; + + ____interactVolume.SetKeyCommandVisible(true); + } + else if (canBeRefueled) + { + // Refuel + uitextType = UITextType.RefillPrompt_4; + ____interactVolume.SetKeyCommandVisible(true); + } + else if (RespawnManager.Instance.RespawnNeeded) + { + showRespawnPrompt = true; + } + else if (____refuelsPlayer && ____healsPlayer) + { + // Fuel and health full + uitextType = UITextType.RefillPrompt_7; + ____interactVolume.SetKeyCommandVisible(false); + } + else if (____refuelsPlayer) + { + // Fuel full + uitextType = UITextType.RefillPrompt_8; + ____interactVolume.SetKeyCommandVisible(false); + } + else if (____healsPlayer) + { + // Health full + uitextType = UITextType.RefillPrompt_9; + ____interactVolume.SetKeyCommandVisible(false); + } + + if (showRespawnPrompt) + { + ____interactVolume.GetValue("_screenPrompt").SetText($" Respawn Player"); + ____interactVolume.GetValue("_noCommandIconPrompt").SetText("Respawn Player"); + } + + if (uitextType != UITextType.None) + { + ____interactVolume.ChangePrompt(uitextType); + } + + return false; + } + + public static bool PlayerRecoveryPoint_OnPressInteract( + PlayerRecoveryPoint __instance, + PlayerResources ____playerResources, + ref bool ____recovering, + bool ____refuelsPlayer, + bool ____healsPlayer, + PlayerAudioController ____playerAudioController, + SingleInteractionVolume ____interactVolume + ) + { + var playerNeedsRefueling = ____playerResources.GetFuelFraction() != 1f; + var playerNeedsHealing = ____playerResources.GetHealthFraction() != 1f; + var canBeInteractedWith = false; + + if (playerNeedsRefueling && ____refuelsPlayer) + { + canBeInteractedWith = true; + } + + if (playerNeedsHealing && ____healsPlayer) + { + canBeInteractedWith = true; + } + + if (RespawnManager.Instance.RespawnNeeded) + { + canBeInteractedWith = true; + } + + if (canBeInteractedWith) + { + if (RespawnManager.Instance.RespawnNeeded) + { + RespawnManager.Instance.RespawnSomePlayer(); + return false; + } + + ____playerResources.StartRefillResources(____refuelsPlayer, ____healsPlayer); + + if (____playerAudioController != null) + { + if (playerNeedsRefueling && ____refuelsPlayer) + { + ____playerAudioController.PlayRefuel(); + } + + if (playerNeedsHealing && ____healsPlayer) + { + ____playerAudioController.PlayMedkit(); + } + } + + ____recovering = true; + __instance.enabled = true; + } + else + { + ____interactVolume.ResetInteraction(); + } + + return false; + } + } +} diff --git a/QSB/DeathSync/RespawnManager.cs b/QSB/DeathSync/RespawnManager.cs new file mode 100644 index 00000000..31dcc942 --- /dev/null +++ b/QSB/DeathSync/RespawnManager.cs @@ -0,0 +1,93 @@ +using OWML.Utils; +using QSB.Events; +using QSB.Patches; +using QSB.Player; +using QSB.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace QSB.DeathSync +{ + class RespawnManager : MonoBehaviour + { + public static RespawnManager Instance; + + public bool RespawnNeeded => _playersPendingRespawn.Count != 0; + + private List _playersPendingRespawn = new List(); + private NotificationData _previousNotification; + + private void Start() + => Instance = this; + + public void TriggerRespawnMap() + { + QSBPatchManager.DoPatchType(QSBPatchTypes.RespawnTime); + QSBCore.UnityEvents.FireOnNextUpdate(() => GlobalMessenger.FireEvent("TriggerObservatoryMap")); + } + + public void Respawn() + { + var mapController = FindObjectOfType(); + QSBPatchManager.DoUnpatchType(QSBPatchTypes.RespawnTime); + + var playerSpawner = FindObjectOfType(); + playerSpawner.DebugWarp(playerSpawner.GetSpawnPoint(SpawnLocation.Ship)); + + mapController.GetType().GetAnyMethod("ExitMapView").Invoke(mapController, null); + + var cameraEffectController = Locator.GetPlayerCamera().GetComponent(); + cameraEffectController.OpenEyes(1f, false); + } + + public void OnPlayerDeath(PlayerInfo player) + { + if (_playersPendingRespawn.Contains(player)) + { + DebugLog.ToConsole($"Warning - Received death message for player who is already in _playersPendingRespawn!", OWML.Common.MessageType.Warning); + return; + } + + _playersPendingRespawn.Add(player); + UpdateRespawnNotification(); + + QSBPlayerManager.ChangePlayerVisibility(player.PlayerId, false); + } + + public void OnPlayerRespawn(PlayerInfo player) + { + if (!_playersPendingRespawn.Contains(player)) + { + DebugLog.ToConsole($"Warning - Received respawn message for player who is not in _playersPendingRespawn!", OWML.Common.MessageType.Warning); + return; + } + + _playersPendingRespawn.Remove(player); + UpdateRespawnNotification(); + + QSBPlayerManager.ChangePlayerVisibility(player.PlayerId, true); + } + + public void RespawnSomePlayer() + { + var playerToRespawn = _playersPendingRespawn.First(); + QSBEventManager.FireEvent(EventNames.QSBPlayerRespawn, playerToRespawn.PlayerId); + } + + private void UpdateRespawnNotification() + { + NotificationManager.SharedInstance.UnpinNotification(_previousNotification); + + if (_playersPendingRespawn.Count == 0) + { + return; + } + + var data = new NotificationData(NotificationTarget.Player, $"[{_playersPendingRespawn.Count}] PLAYER(S) AWAITING RESPAWN"); + NotificationManager.SharedInstance.PostNotification(data, true); + _previousNotification = data; + } + } +} diff --git a/QSB/DeathSync/RespawnOnDeath.cs b/QSB/DeathSync/RespawnOnDeath.cs index 3a9b2614..b9c227ec 100644 --- a/QSB/DeathSync/RespawnOnDeath.cs +++ b/QSB/DeathSync/RespawnOnDeath.cs @@ -45,6 +45,8 @@ namespace QSB.DeathSync Init(); } + RespawnManager.Instance.TriggerRespawnMap(); + // Cant use _playerSpawner.DebugWarp because that will warp the ship if the player is in it var playerBody = Locator.GetPlayerBody(); playerBody.WarpToPositionRotation(_playerSpawnPoint.transform.position, _playerSpawnPoint.transform.rotation); diff --git a/QSB/Events/EventNames.cs b/QSB/Events/EventNames.cs index e77387e4..158b17c5 100644 --- a/QSB/Events/EventNames.cs +++ b/QSB/Events/EventNames.cs @@ -77,5 +77,6 @@ public static string QSBComponentDamaged = "QSBComponentDamaged"; public static string QSBComponentRepaired = "QSBComponentRepaired"; public static string QSBComponentRepairTick = "QSBComponentRepairTick"; + public static string QSBPlayerRespawn = "QSBPlayerRespawn"; } } \ No newline at end of file diff --git a/QSB/Events/EventType.cs b/QSB/Events/EventType.cs index d7a1d1f2..9d49cb14 100644 --- a/QSB/Events/EventType.cs +++ b/QSB/Events/EventType.cs @@ -53,6 +53,7 @@ HullRepairTick, ComponentDamaged, ComponentRepaired, - ComponentRepairTick + ComponentRepairTick, + PlayerRespawn } } \ No newline at end of file diff --git a/QSB/Events/QSBEventManager.cs b/QSB/Events/QSBEventManager.cs index 9c4ad956..e59e7b87 100644 --- a/QSB/Events/QSBEventManager.cs +++ b/QSB/Events/QSBEventManager.cs @@ -55,6 +55,7 @@ namespace QSB.Events new EnterExitRoastingEvent(), new MarshmallowEventEvent(), new AnimationTriggerEvent(), + new PlayerRespawnEvent(), // World Objects new ElevatorEvent(), new GeyserEvent(), diff --git a/QSB/Patches/QSBPatchManager.cs b/QSB/Patches/QSBPatchManager.cs index 55e0bf88..9be1513b 100644 --- a/QSB/Patches/QSBPatchManager.cs +++ b/QSB/Patches/QSBPatchManager.cs @@ -60,7 +60,8 @@ namespace QSB.Patches new ShipPatches(), new InputPatches(), new TimePatches(), - new MapPatches() + new MapPatches(), + new RespawnPatches() }; DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success); diff --git a/QSB/Patches/QSBPatchTypes.cs b/QSB/Patches/QSBPatchTypes.cs index 64ebdb4a..dc2ad86f 100644 --- a/QSB/Patches/QSBPatchTypes.cs +++ b/QSB/Patches/QSBPatchTypes.cs @@ -4,6 +4,7 @@ { OnClientConnect = 0, OnNonServerClientConnect = 1, - OnServerClientConnect = 2 + OnServerClientConnect = 2, + RespawnTime = 3 } } \ No newline at end of file diff --git a/QSB/QSB.csproj b/QSB/QSB.csproj index 01a6dc64..31f2d270 100644 --- a/QSB/QSB.csproj +++ b/QSB/QSB.csproj @@ -141,9 +141,12 @@ + + + diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs index 92753e81..a251e6ae 100644 --- a/QSB/QSBCore.cs +++ b/QSB/QSBCore.cs @@ -5,6 +5,7 @@ using OWML.Utils; using QSB.Animation.NPC; using QSB.CampfireSync; using QSB.ConversationSync; +using QSB.DeathSync; using QSB.ElevatorSync; using QSB.GeyserSync; using QSB.Inputs; @@ -91,6 +92,7 @@ namespace QSB gameObject.AddComponent(); gameObject.AddComponent(); gameObject.AddComponent(); + gameObject.AddComponent(); // WorldObject managers gameObject.AddComponent();