diff --git a/NewHorizons/Handlers/PlayerSpawnHandler.cs b/NewHorizons/Handlers/PlayerSpawnHandler.cs index 72dde2a0..8d70907b 100644 --- a/NewHorizons/Handlers/PlayerSpawnHandler.cs +++ b/NewHorizons/Handlers/PlayerSpawnHandler.cs @@ -1,6 +1,5 @@ using NewHorizons.Utility; using NewHorizons.Utility.OWML; -using System; using System.Collections; using UnityEngine; @@ -8,10 +7,6 @@ namespace NewHorizons.Handlers { public static class PlayerSpawnHandler { - private static bool _wasInvincible; - private static bool _wasDeathManagerInvincible; - private static float _impactDeathSpeed; - public static void SetUpPlayerSpawn() { var spawnPoint = Main.SystemDict[Main.Instance.CurrentStarSystem].SpawnPoint; @@ -41,22 +36,18 @@ namespace NewHorizons.Handlers { InvulnerabilityHandler.MakeInvulnerable(true); - var player = SearchUtilities.Find("Player_Body").GetAttachedOWRigidbody(); - var spawn = GetDefaultSpawn(); - // Idk why but these just don't work? - var matchInitialMotion = player.GetComponent(); + var matchInitialMotion = SearchUtilities.Find("Player_Body").GetComponent(); if (matchInitialMotion != null) UnityEngine.Object.Destroy(matchInitialMotion); - Main.Instance.StartCoroutine(SpawnCoroutine(player, spawn, 5)); + Main.Instance.StartCoroutine(SpawnCoroutine(2)); } } - private static IEnumerator SpawnCoroutine(OWRigidbody playerBody, SpawnPoint spawn, int length) + private static IEnumerator SpawnCoroutine(int length) { for(int i = 0; i < length; i++) { - playerBody.WarpToPositionRotation(spawn.transform.position, spawn.transform.rotation); FixVelocity(); yield return new WaitForEndOfFrame(); } @@ -66,16 +57,12 @@ namespace NewHorizons.Handlers private static void FixVelocity() { - var player = SearchUtilities.Find("Player_Body"); - var playerBody = player.GetAttachedOWRigidbody(); + var playerBody = SearchUtilities.Find("Player_Body").GetAttachedOWRigidbody(); var spawn = GetDefaultSpawn(); + var resources = playerBody.GetComponent(); playerBody.WarpToPositionRotation(spawn.transform.position, spawn.transform.rotation); - // Player dies during the teleport sometimes so we prevent that - var resources = player.GetComponent(); - var deathManager = Locator.GetDeathManager(); - var spawnVelocity = spawn._attachedBody.GetVelocity(); var spawnAngularVelocity = spawn._attachedBody.GetPointTangentialVelocity(playerBody.transform.position); var velocity = spawnVelocity + spawnAngularVelocity; @@ -84,10 +71,6 @@ namespace NewHorizons.Handlers NHLogger.LogVerbose($"Player spawn velocity {velocity} Player velocity {playerBody.GetVelocity()} spawn body {spawnVelocity} spawn angular vel {spawnAngularVelocity}"); resources._currentHealth = 100f; - - resources._invincible = _wasInvincible; - deathManager._invincible = _wasDeathManagerInvincible; - deathManager._impactDeathSpeed = _impactDeathSpeed; } private static Vector3 CalculateMatchVelocity(OWRigidbody owRigidbody, OWRigidbody bodyToMatch, bool ignoreAngularVelocity) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 4fcceed7..c24b4b03 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -65,6 +65,7 @@ namespace NewHorizons public bool IsWarpingFromShip { get; private set; } = false; public bool IsWarpingFromVessel { get; private set; } = false; public bool IsWarpingBackToEye { get; internal set; } = false; + public bool DidWarpFromShip { get; private set; } = false; public bool DidWarpFromVessel { get; private set; } = false; public bool WearingSuit { get; private set; } = false; @@ -75,6 +76,10 @@ namespace NewHorizons private string _defaultStarSystem = "SolarSystem"; internal string _currentStarSystem = "SolarSystem"; private bool _firstLoad = true; + + private bool _playerAwake; + public bool PlayerSpawned { get; set; } + public ShipWarpController ShipWarpController { get; private set; } // API events @@ -196,7 +201,6 @@ namespace NewHorizons SceneManager.sceneUnloaded += OnSceneUnloaded; GlobalMessenger.AddListener("PlayerDeath", OnDeath); - GlobalMessenger.AddListener("WakeUp", OnWakeUp); NHAssetBundle = ModHelper.Assets.LoadBundle("Assets/newhorizons_public"); @@ -245,15 +249,12 @@ namespace NewHorizons NHLogger.Log($"Destroying NewHorizons"); SceneManager.sceneLoaded -= OnSceneLoaded; GlobalMessenger.RemoveListener("PlayerDeath", OnDeath); - GlobalMessenger.RemoveListener("WakeUp", new Callback(OnWakeUp)); + GlobalMessenger.RemoveListener("WakeUp", OnWakeUp); AchievementHandler.OnDestroy(); } - private static void OnWakeUp() - { - IsSystemReady = true; - } + private void OnWakeUp() => _playerAwake = true; private void OnSceneUnloaded(Scene scene) { @@ -269,6 +270,8 @@ namespace NewHorizons { NHLogger.Log($"Scene Loaded: {scene.name} {mode} OWScene.{LoadManager.NameToScene(scene.name)}"); + PlayerSpawned = false; + var isTitleScreen = scene.name == LoadManager.SceneToName(OWScene.TitleScreen); var isSolarSystem = scene.name == LoadManager.SceneToName(OWScene.SolarSystem); var isEyeOfTheUniverse = scene.name == LoadManager.SceneToName(OWScene.EyeOfTheUniverse); @@ -380,6 +383,7 @@ namespace NewHorizons // EOTU fixes if (isEyeOfTheUniverse) { + _playerAwake = true; EyeSceneHandler.OnSceneLoad(); } @@ -438,10 +442,10 @@ namespace NewHorizons var shouldWarpInFromShip = IsWarpingFromShip && ShipWarpController != null; var shouldWarpInFromVessel = IsWarpingFromVessel && VesselWarpHandler.VesselSpawnPoint != null; - Delay.RunWhen(() => IsSystemReady, () => OnSystemReady(shouldWarpInFromShip, shouldWarpInFromVessel)); IsWarpingFromShip = false; IsWarpingFromVessel = false; + DidWarpFromShip = shouldWarpInFromShip; DidWarpFromVessel = shouldWarpInFromVessel; var map = FindObjectOfType(); @@ -500,16 +504,10 @@ namespace NewHorizons } else if (isEyeOfTheUniverse) { - // There is no wake up in eye scene - Delay.FireOnNextUpdate(() => - { - IsSystemReady = true; - OnSystemReady(false, false); - }); - IsWarpingFromShip = false; IsWarpingFromVessel = false; DidWarpFromVessel = false; + DidWarpFromShip = false; } //Stop starfield from disappearing when there is no lights @@ -562,11 +560,16 @@ namespace NewHorizons _currentStarSystem = _defaultStarSystem; } } + + // Wait for player to be awake and also for frames to pass + Delay.RunWhenAndInNUpdates(() => OnSystemReady(DidWarpFromShip, DidWarpFromVessel), () => _playerAwake && PlayerSpawned, 30); } // 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) { + IsSystemReady = true; + // ShipWarpController will handle the invulnerability otherwise if (!shouldWarpInFromShip) Delay.FireOnNextUpdate(() => InvulnerabilityHandler.MakeInvulnerable(false)); diff --git a/NewHorizons/Patches/PlayerPatches/PlayerSpawnerPatches.cs b/NewHorizons/Patches/PlayerPatches/PlayerSpawnerPatches.cs index 70099cce..bfd7b23e 100644 --- a/NewHorizons/Patches/PlayerPatches/PlayerSpawnerPatches.cs +++ b/NewHorizons/Patches/PlayerPatches/PlayerSpawnerPatches.cs @@ -11,6 +11,8 @@ namespace NewHorizons.Patches.PlayerPatches [HarmonyPatch(nameof(PlayerSpawner.SpawnPlayer))] public static bool PlayerSpawner_SpawnPlayer(PlayerSpawner __instance) { + Main.Instance.PlayerSpawned = true; + if (Main.Instance.IsWarpingFromVessel || Main.Instance.DidWarpFromVessel || Main.Instance.IsWarpingFromShip) { NHLogger.LogWarning("Abort player spawn. Vessel/Ship will handle it."); diff --git a/NewHorizons/Utility/OWML/Delay.cs b/NewHorizons/Utility/OWML/Delay.cs index 9e83e9bc..979712b7 100644 --- a/NewHorizons/Utility/OWML/Delay.cs +++ b/NewHorizons/Utility/OWML/Delay.cs @@ -1,4 +1,6 @@ using System; +using System.Collections; +using UnityEngine; namespace NewHorizons.Utility.OWML { @@ -7,5 +9,20 @@ namespace NewHorizons.Utility.OWML public static void RunWhen(Func predicate, Action action) => Main.Instance.ModHelper.Events.Unity.RunWhen(predicate, action); public static void FireInNUpdates(Action action, int n) => Main.Instance.ModHelper.Events.Unity.FireInNUpdates(action, n); public static void FireOnNextUpdate(Action action) => Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(action); + public static void RunWhenAndInNUpdates(Action action, Func predicate, int n) => Main.Instance.StartCoroutine(RunWhenOrInNUpdatesCoroutine(action, predicate, n)); + + private static IEnumerator RunWhenOrInNUpdatesCoroutine(Action action, Func predicate, int n) + { + for (int i = 0; i < n; i++) + { + yield return new WaitForEndOfFrame(); + } + while (!predicate.Invoke()) + { + yield return new WaitForEndOfFrame(); + } + + action.Invoke(); + } } } diff --git a/NewHorizons/manifest.json b/NewHorizons/manifest.json index 606a5f49..2e669fbc 100644 --- a/NewHorizons/manifest.json +++ b/NewHorizons/manifest.json @@ -4,7 +4,7 @@ "author": "xen, Bwc9876, clay, MegaPiggy, John, Trifid, Hawkbar, Book", "name": "New Horizons", "uniqueName": "xen.NewHorizons", - "version": "1.12.2", + "version": "1.12.3", "owmlVersion": "2.9.3", "dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ], "conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ],