diff --git a/NewHorizons/Components/Ship/ShipWarpController.cs b/NewHorizons/Components/Ship/ShipWarpController.cs index 8917ddb0..ecae7a7c 100644 --- a/NewHorizons/Components/Ship/ShipWarpController.cs +++ b/NewHorizons/Components/Ship/ShipWarpController.cs @@ -1,4 +1,5 @@ using NewHorizons.Builder.General; +using NewHorizons.Handlers; using NewHorizons.Utility; using NewHorizons.Utility.OWML; using UnityEngine; @@ -113,10 +114,8 @@ namespace NewHorizons.Components.Ship public void WarpIn(bool wearingSuit) { NHLogger.LogVerbose("Starting warp-in"); - // Trying really hard to stop the player from dying while warping in - _impactDeathSpeed = Locator.GetDeathManager()._impactDeathSpeed; - Locator.GetDeathManager()._impactDeathSpeed = Mathf.Infinity; - Locator.GetDeathManager()._invincible = true; + + InvulnerabilityHandler.MakeInvulnerable(true); _isWarpingIn = true; _wearingSuit = wearingSuit; @@ -191,10 +190,7 @@ namespace NewHorizons.Components.Ship Delay.FireInNUpdates(() => _whitehole.Collapse(), 30); var resources = Locator.GetPlayerTransform().GetComponent(); - - Locator.GetDeathManager()._impactDeathSpeed = _impactDeathSpeed; - resources._currentHealth = 100f; - Locator.GetDeathManager()._invincible = false; + InvulnerabilityHandler.MakeInvulnerable(false); // For some reason warping into the ship makes you suffocate while in the ship if (_wearingSuit) resources.OnSuitUp(); diff --git a/NewHorizons/Handlers/FadeHandler.cs b/NewHorizons/Handlers/FadeHandler.cs new file mode 100644 index 00000000..9316030a --- /dev/null +++ b/NewHorizons/Handlers/FadeHandler.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections; +using UnityEngine; + +namespace NewHorizons.Handlers +{ + public static class FadeHandler + { + public static void FadeOut(float length) => Main.Instance.StartCoroutine(FadeOutCoroutine(length)); + + private static IEnumerator FadeOutCoroutine(float length) + { + LoadManager.s_instance._fadeCanvas.enabled = true; + float startTime = Time.unscaledTime; + float endTime = Time.unscaledTime + length; + + while (Time.unscaledTime < endTime) + { + LoadManager.s_instance._fadeImage.color = Color.Lerp(Color.clear, Color.black, (Time.unscaledTime - startTime) / length); + yield return new WaitForEndOfFrame(); + } + + LoadManager.s_instance._fadeImage.color = Color.black; + yield return new WaitForEndOfFrame(); + } + + public static void FadeThen(float length, Action action) => Main.Instance.StartCoroutine(FadeThenCoroutine(length, action)); + + private static IEnumerator FadeThenCoroutine(float length, Action action) + { + yield return FadeOutCoroutine(length); + + action?.Invoke(); + } + } +} diff --git a/NewHorizons/Handlers/InvulnerabilityHandler.cs b/NewHorizons/Handlers/InvulnerabilityHandler.cs new file mode 100644 index 00000000..9aa0e793 --- /dev/null +++ b/NewHorizons/Handlers/InvulnerabilityHandler.cs @@ -0,0 +1,36 @@ +using NewHorizons.Utility.OWML; +using UnityEngine; + +namespace NewHorizons.Handlers +{ + internal class InvulnerabilityHandler + { + private static float _defaultImpactDeathSpeed = -1f; + + public static void MakeInvulnerable(bool invulnerable) + { + NHLogger.Log($"Toggling immortality: {invulnerable}"); + + var deathManager = GetDeathManager(); + var resources = GetPlayerResouces(); + + if (invulnerable) + { + if (_defaultImpactDeathSpeed == -1f) + _defaultImpactDeathSpeed = deathManager._impactDeathSpeed; + + deathManager._impactDeathSpeed = Mathf.Infinity; + deathManager._invincible = true; + } + else + { + deathManager._impactDeathSpeed = _defaultImpactDeathSpeed; + resources._currentHealth = 100f; + deathManager._invincible = false; + } + } + + private static DeathManager GetDeathManager() => GameObject.FindObjectOfType(); + private static PlayerResources GetPlayerResouces() => GameObject.FindObjectOfType(); + } +} diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 3ef2c324..8a9129cf 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -246,7 +246,14 @@ namespace NewHorizons.Handlers { NHLogger.Log($"Creating [{body.Config.name}]"); var planetObject = GenerateBody(body, defaultPrimaryToSun); - planetObject?.SetActive(true); + try + { + planetObject?.SetActive(true); + } + catch (Exception e) + { + NHLogger.LogError($"Error when activating new planet [{body.Config.name}] - {e}"); + } if (planetObject == null) { body.UnloadCache(); diff --git a/NewHorizons/Handlers/PlanetDestructionHandler.cs b/NewHorizons/Handlers/PlanetDestructionHandler.cs index fdf15032..4a752848 100644 --- a/NewHorizons/Handlers/PlanetDestructionHandler.cs +++ b/NewHorizons/Handlers/PlanetDestructionHandler.cs @@ -86,7 +86,7 @@ namespace NewHorizons.Handlers if (ao.GetAstroObjectName() == AstroObject.Name.RingWorld) { CloakHandler.FlagStrangerDisabled = true; - if (Locator._cloakFieldController.GetComponentInParent() == ao) Locator._cloakFieldController = null; + if (Locator._cloakFieldController?.GetComponentInParent() == ao) Locator._cloakFieldController = null; } if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) diff --git a/NewHorizons/Handlers/PlayerSpawnHandler.cs b/NewHorizons/Handlers/PlayerSpawnHandler.cs index 3b85de45..72dde2a0 100644 --- a/NewHorizons/Handlers/PlayerSpawnHandler.cs +++ b/NewHorizons/Handlers/PlayerSpawnHandler.cs @@ -1,6 +1,7 @@ using NewHorizons.Utility; using NewHorizons.Utility.OWML; using System; +using System.Collections; using UnityEngine; namespace NewHorizons.Handlers @@ -27,6 +28,7 @@ namespace NewHorizons.Handlers public static void OnSystemReady(bool shouldWarpInFromShip, bool shouldWarpInFromVessel) { + NHLogger.Log($"OnSystemReady {shouldWarpInFromVessel}, {shouldWarpInFromShip}, {UsingCustomSpawn()}"); if (shouldWarpInFromShip) { Main.Instance.ShipWarpController.WarpIn(Main.Instance.WearingSuit); @@ -37,42 +39,31 @@ namespace NewHorizons.Handlers } else if (UsingCustomSpawn()) { - var player = SearchUtilities.Find("Player_Body"); - var playerBody = player.GetAttachedOWRigidbody(); + InvulnerabilityHandler.MakeInvulnerable(true); + + var player = SearchUtilities.Find("Player_Body").GetAttachedOWRigidbody(); var spawn = GetDefaultSpawn(); - // Player dies during the teleport sometimes so we prevent that - var resources = player.GetComponent(); - var deathManager = Locator.GetDeathManager(); + // Idk why but these just don't work? + var matchInitialMotion = player.GetComponent(); + if (matchInitialMotion != null) UnityEngine.Object.Destroy(matchInitialMotion); - _wasInvincible = resources._invincible; - _wasDeathManagerInvincible = deathManager._invincible; - _impactDeathSpeed = deathManager._impactDeathSpeed; - - resources._invincible = true; - deathManager._invincible = true; - deathManager._impactDeathSpeed = float.MaxValue; - - Delay.FireOnNextUpdate(() => - { - var matchInitialMotion = playerBody.GetComponent(); - - playerBody.WarpToPositionRotation(spawn.transform.position, spawn.transform.rotation); - - if (matchInitialMotion != null) - { - // Idk why but these just don't work? - UnityEngine.Object.Destroy(matchInitialMotion); - Delay.FireOnNextUpdate(FixVelocity); - } - else - { - FixVelocity(); - } - }); + Main.Instance.StartCoroutine(SpawnCoroutine(player, spawn, 5)); } } + private static IEnumerator SpawnCoroutine(OWRigidbody playerBody, SpawnPoint spawn, int length) + { + for(int i = 0; i < length; i++) + { + playerBody.WarpToPositionRotation(spawn.transform.position, spawn.transform.rotation); + FixVelocity(); + yield return new WaitForEndOfFrame(); + } + + InvulnerabilityHandler.MakeInvulnerable(false); + } + private static void FixVelocity() { var player = SearchUtilities.Find("Player_Body"); diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 40ce4684..4fcceed7 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -385,6 +385,9 @@ namespace NewHorizons if (isSolarSystem || isEyeOfTheUniverse) { + // Stop dying while spawning please + InvulnerabilityHandler.MakeInvulnerable(true); + IsSystemReady = false; NewHorizonsData.Load(); @@ -564,6 +567,10 @@ namespace NewHorizons // Had a bunch of separate unity things firing stuff when the system is ready so I moved it all to here private void OnSystemReady(bool shouldWarpInFromShip, bool shouldWarpInFromVessel) { + // ShipWarpController will handle the invulnerability otherwise + if (!shouldWarpInFromShip) + Delay.FireOnNextUpdate(() => InvulnerabilityHandler.MakeInvulnerable(false)); + Locator.GetPlayerBody().gameObject.AddComponent(); Locator.GetPlayerBody().gameObject.AddComponent(); Locator.GetPlayerBody().gameObject.AddComponent(); @@ -814,47 +821,50 @@ namespace NewHorizons return; } - if (LoadManager.GetCurrentScene() == OWScene.SolarSystem || LoadManager.GetCurrentScene() == OWScene.EyeOfTheUniverse) - { - // Slide reel unloading is tied to being removed from the sector, so we do that here to prevent a softlock - Locator.GetPlayerSectorDetector().RemoveFromAllSectors(); - } - if (IsChangingStarSystem) return; - IsWarpingFromShip = warp; - IsWarpingFromVessel = vessel; - DidWarpFromVessel = false; - OnChangeStarSystem?.Invoke(newStarSystem); - - NHLogger.Log($"Warping to {newStarSystem}"); - if (warp && ShipWarpController) ShipWarpController.WarpOut(); - IsChangingStarSystem = true; - WearingSuit = PlayerState.IsWearingSuit(); - - OWScene sceneToLoad; - - if (newStarSystem == "EyeOfTheUniverse") + if (LoadManager.GetCurrentScene() == OWScene.SolarSystem || LoadManager.GetCurrentScene() == OWScene.EyeOfTheUniverse) { - PlayerData.SaveWarpedToTheEye(TimeLoopUtilities.GetVanillaSecondsRemaining()); - sceneToLoad = OWScene.EyeOfTheUniverse; + IsWarpingFromShip = warp; + IsWarpingFromVessel = vessel; + DidWarpFromVessel = false; + OnChangeStarSystem?.Invoke(newStarSystem); + + NHLogger.Log($"Warping to {newStarSystem}"); + if (warp && ShipWarpController) ShipWarpController.WarpOut(); + IsChangingStarSystem = true; + WearingSuit = PlayerState.IsWearingSuit(); + + OWScene sceneToLoad; + + if (newStarSystem == "EyeOfTheUniverse") + { + PlayerData.SaveWarpedToTheEye(TimeLoopUtilities.GetVanillaSecondsRemaining()); + sceneToLoad = OWScene.EyeOfTheUniverse; + } + else + { + PlayerData.SaveEyeCompletion(); // So that the title screen doesn't keep warping you back to eye + + if (SystemDict[_currentStarSystem].Config.enableTimeLoop) SecondsElapsedInLoop = TimeLoop.GetSecondsElapsed(); + else SecondsElapsedInLoop = -1; + + sceneToLoad = OWScene.SolarSystem; + } + + _currentStarSystem = newStarSystem; + + // Freeze player inputs + OWInput.ChangeInputMode(InputMode.None); + + // Hide unloading + FadeHandler.FadeThen(1f, () => + { + // Slide reel unloading is tied to being removed from the sector, so we do that here to prevent a softlock + Locator.GetPlayerSectorDetector().RemoveFromAllSectors(); + LoadManager.LoadSceneImmediate(sceneToLoad); + }); } - else - { - PlayerData.SaveEyeCompletion(); // So that the title screen doesn't keep warping you back to eye - - if (SystemDict[_currentStarSystem].Config.enableTimeLoop) SecondsElapsedInLoop = TimeLoop.GetSecondsElapsed(); - else SecondsElapsedInLoop = -1; - - sceneToLoad = OWScene.SolarSystem; - } - - _currentStarSystem = newStarSystem; - - // Freeze player inputs - OWInput.ChangeInputMode(InputMode.None); - - LoadManager.LoadSceneAsync(sceneToLoad, !vessel, LoadManager.FadeType.ToBlack, vessel ? 1 : 0.1f, true); } void OnDeath(DeathType _)