diff --git a/QSB/QSB.cs b/QSB/QSB.cs index a91e92ec..62b2d8f5 100644 --- a/QSB/QSB.cs +++ b/QSB/QSB.cs @@ -23,7 +23,7 @@ namespace QSB gameObject.AddComponent(); gameObject.AddComponent(); gameObject.AddComponent(); + gameObject.AddComponent(); } - } } diff --git a/QSB/QSB.csproj b/QSB/QSB.csproj index 7e51dac3..bf6ec044 100644 --- a/QSB/QSB.csproj +++ b/QSB/QSB.csproj @@ -103,6 +103,7 @@ + diff --git a/QSB/RespawnOnDeath.cs b/QSB/RespawnOnDeath.cs new file mode 100644 index 00000000..95922155 --- /dev/null +++ b/QSB/RespawnOnDeath.cs @@ -0,0 +1,106 @@ +using OWML.ModHelper.Events; +using System.Linq; +using UnityEngine; + +namespace QSB +{ + class RespawnOnDeath : MonoBehaviour + { + static RespawnOnDeath Instance; + + SpawnPoint _shipSpawnPoint; + SpawnPoint _playerSpawnPoint; + OWRigidbody _shipBody; + PlayerSpawner _playerSpawner; + FluidDetector _fluidDetector; + PlayerResources _playerResources; + ShipComponent[] _shipComponents; + + void Awake() + { + GlobalMessenger.AddListener("WakeUp", PlayerWokeUp); + + Instance = this; + QSB.Helper.HarmonyHelper.AddPrefix("KillPlayer", typeof(Patches), nameof(Patches.PreFinishDeathSequence)); + } + + void PlayerWokeUp() + { + _playerSpawner = FindObjectOfType(); + _fluidDetector = Locator.GetPlayerCamera().GetComponentInChildren(); + _playerResources = Locator.GetPlayerTransform().GetComponent(); + + var shipTransform = Locator.GetShipTransform(); + if (shipTransform) + { + _shipComponents = Locator.GetShipTransform().GetComponentsInChildren(); + _shipBody = Locator.GetShipBody(); + _shipSpawnPoint = GetSpawnPoint(true); + + // Move debug spawn point to initial ship position. + _playerSpawnPoint = GetSpawnPoint(); + _shipSpawnPoint.transform.position = shipTransform.position; + _shipSpawnPoint.transform.rotation = shipTransform.rotation; + } + + } + + public void ResetShip() + { + if (!_shipBody) + { + return; + } + + // Reset ship position. + _shipBody.SetVelocity(_shipSpawnPoint.GetPointVelocity()); + _shipBody.WarpToPositionRotation(_shipSpawnPoint.transform.position, _shipSpawnPoint.transform.rotation); + + // Reset ship damage. + if (Locator.GetShipTransform()) + { + for (int i = 0; i < _shipComponents.Length; i++) + { + _shipComponents[i].SetDamaged(false); + } + } + } + + public void ResetPlayer() + { + // Reset player position. + OWRigidbody playerBody = Locator.GetPlayerBody(); + playerBody.WarpToPositionRotation(_playerSpawnPoint.transform.position, _playerSpawnPoint.transform.rotation); + playerBody.SetVelocity(_playerSpawnPoint.GetPointVelocity()); + _playerSpawnPoint.AddObjectToTriggerVolumes(Locator.GetPlayerDetector().gameObject); + _playerSpawnPoint.AddObjectToTriggerVolumes(_fluidDetector.gameObject); + _playerSpawnPoint.OnSpawnPlayer(); + + _playerResources.SetValue("_isSuffocating", false); + + // Reset player health and resources. + _playerResources.DebugRefillResources(); + } + + SpawnPoint GetSpawnPoint(bool isShip = false) + { + return _playerSpawner + .GetValue("_spawnList") + .FirstOrDefault(spawnPoint => + spawnPoint.GetSpawnLocation() == SpawnLocation.TimberHearth && spawnPoint.IsShipSpawn() == isShip + ); + } + + internal static class Patches + { + public static bool PreFinishDeathSequence() + { + Instance.ResetPlayer(); + Instance.ResetShip(); + + // Prevent original death method from running. + return false; + } + } + } +}