Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…-horizons into dev
  • Loading branch information
xen-42 committed Feb 10, 2025
2 parents 71d6f57 + 0706b90 commit 52f164a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 8 deletions.
26 changes: 21 additions & 5 deletions NewHorizons/Handlers/InvulnerabilityHandler.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,52 @@
using HarmonyLib;
using NewHorizons.Utility.OWML;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace NewHorizons.Handlers
{
[HarmonyPatch]
internal class InvulnerabilityHandler
{
private static float _defaultImpactDeathSpeed = -1f;

Check warning on line 11 in NewHorizons/Handlers/InvulnerabilityHandler.cs

View workflow job for this annotation

GitHub Actions / Build / Build

The field 'InvulnerabilityHandler._defaultImpactDeathSpeed' is assigned but its value is never used

Check warning on line 11 in NewHorizons/Handlers/InvulnerabilityHandler.cs

View workflow job for this annotation

GitHub Actions / Build / Build

The field 'InvulnerabilityHandler._defaultImpactDeathSpeed' is assigned but its value is never used
private static bool _invulnerable;

public static void MakeInvulnerable(bool invulnerable)
{
NHLogger.Log($"Toggling immortality: {invulnerable}");

_invulnerable = 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;
}
}

[HarmonyPrefix]
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
[HarmonyPatch(typeof(PlayerResources), nameof(PlayerResources.ApplyInstantDamage))]
[HarmonyPatch(typeof(PlayerImpactAudio), nameof(PlayerImpactAudio.OnImpact))]
public static bool DeathManager_KillPlayer_Prefix()
{
// Base game _invincible is still overriden by high speed impacts
// We also are avoiding playing impact related effects by just skipping these methods
return !_invulnerable;
}

private static DeathManager GetDeathManager() => GameObject.FindObjectOfType<DeathManager>();
private static PlayerResources GetPlayerResouces() => GameObject.FindObjectOfType<PlayerResources>();

static InvulnerabilityHandler()
{
SceneManager.sceneUnloaded += (_) => _invulnerable = false;
}
}
}
18 changes: 18 additions & 0 deletions NewHorizons/Handlers/PlayerSpawnHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@ public static void OnSystemReady(bool shouldWarpInFromShip, bool shouldWarpInFro

// Spawn ship
Delay.FireInNUpdates(SpawnShip, 30);

// Have had bug reports (#1034, #975) where sometimes after spawning via vessel warp or ship warp you die from impact velocity after being flung
// Something weird must be happening with velocity.
// Try to correct it here after the ship is done spawning
Delay.FireInNUpdates(() => FixVelocity(shouldWarpInFromVessel, shouldWarpInFromShip), 31);
}

private static void FixVelocity(bool shouldWarpInFromVessel, bool shouldWarpInFromShip)
{
var spawnOWRigidBody = GetDefaultSpawn().GetAttachedOWRigidbody();
if (shouldWarpInFromVessel) spawnOWRigidBody = VesselWarpHandler.VesselSpawnPoint.GetAttachedOWRigidbody();
if (shouldWarpInFromShip) spawnOWRigidBody = Locator.GetShipBody();

var spawnVelocity = spawnOWRigidBody.GetVelocity();
var spawnAngularVelocity = spawnOWRigidBody.GetPointTangentialVelocity(Locator.GetPlayerBody().GetPosition());
var velocity = spawnVelocity + spawnAngularVelocity;

Locator.GetPlayerBody().SetVelocity(velocity);
}

public static void SpawnShip()
Expand Down
28 changes: 27 additions & 1 deletion NewHorizons/Handlers/VesselWarpHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using NewHorizons.Utility.OuterWilds;
using NewHorizons.Utility.OWML;
using UnityEngine;
using System.Collections;
using static NewHorizons.Main;
using static NewHorizons.Utility.Files.AssetBundleUtilities;

Expand Down Expand Up @@ -56,7 +57,9 @@ public static void LoadVessel()
}

if (IsVesselPresentAndActive())
{
_vesselSpawnPoint = Instance.CurrentStarSystem == "SolarSystem" ? UpdateVessel() : CreateVessel();
}
else
{
var vesselDimension = SearchUtilities.Find("DB_VesselDimension_Body/Sector_VesselDimension");
Expand Down Expand Up @@ -84,7 +87,12 @@ public static void TeleportToVessel()
if (_vesselSpawnPoint is VesselSpawnPoint vesselSpawnPoint)
{
NHLogger.LogVerbose("Relative warping into vessel");
vesselSpawnPoint.WarpPlayer();//Delay.FireOnNextUpdate(vesselSpawnPoint.WarpPlayer);
vesselSpawnPoint.WarpPlayer();

// #1034 Vessel warp sometimes has the player get flung away into space and die
// We do what we do with regular spawns where we keep resetting their position to the right one while invincible until we're relatively certain
// that the spawning sequence is done
Delay.StartCoroutine(FixPlayerSpawning(25, vesselSpawnPoint));
}
else
{
Expand All @@ -96,6 +104,24 @@ public static void TeleportToVessel()
LoadDB();
}

private static IEnumerator FixPlayerSpawning(int frameInterval, VesselSpawnPoint vesselSpawn)
{
InvulnerabilityHandler.MakeInvulnerable(true);

var frameCount = 0;
while (frameCount <= frameInterval)
{
vesselSpawn.WarpPlayer();
frameCount++;
yield return null; // Wait for the next frame
}

InvulnerabilityHandler.MakeInvulnerable(false);
var playerBody = SearchUtilities.Find("Player_Body").GetAttachedOWRigidbody();
var resources = playerBody.GetComponent<PlayerResources>();
resources._currentHealth = 100f;
}

public static void LoadDB()
{
if (Instance.CurrentStarSystem == "SolarSystem")
Expand Down
4 changes: 2 additions & 2 deletions NewHorizons/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,8 @@ private void OnSystemReady(bool shouldWarpInFromShip, bool shouldWarpInFromVesse
{
IsSystemReady = true;

// ShipWarpController will handle the invulnerability otherwise
if (!shouldWarpInFromShip)
// ShipWarpController or VesselWarpHandler will handle the invulnerability otherwise
if (!shouldWarpInFromShip && !shouldWarpInFromVessel)
{
Delay.FireOnNextUpdate(() => InvulnerabilityHandler.MakeInvulnerable(false));
}
Expand Down

0 comments on commit 52f164a

Please sign in to comment.