Instant respawn on death (#31)

* Instantly respawn on death

* Avoid spawning to ship spawn point

* Move debug spawn ship position to landing pad

* Separate spawn point for ship and player

* Refactor code

* Cleanup

* Check for ship existance

* Cleanup

* Reset suffocation flag

* Sexier way
This commit is contained in:
Ricardo Lopes 2020-02-28 21:32:21 +01:00 committed by GitHub
parent c804058ec5
commit d6f8112bbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 1 deletions

View File

@ -23,7 +23,7 @@ namespace QSB
gameObject.AddComponent<QSBNetworkManager>();
gameObject.AddComponent<NetworkManagerHUD>();
gameObject.AddComponent<PreserveTimeScale>();
gameObject.AddComponent<RespawnOnDeath>();
}
}
}

View File

@ -103,6 +103,7 @@
<Compile Include="Messaging\MessageHandler.cs" />
<Compile Include="Messaging\MessageType.cs" />
<Compile Include="Messaging\QSBMessage.cs" />
<Compile Include="RespawnOnDeath.cs" />
<Compile Include="TransformSync\QuaternionHelper.cs" />
<Compile Include="QSBBehaviour.cs" />
<Compile Include="TimeSync\PreserveTimeScale.cs" />

106
QSB/RespawnOnDeath.cs Normal file
View File

@ -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<DeathManager>("KillPlayer", typeof(Patches), nameof(Patches.PreFinishDeathSequence));
}
void PlayerWokeUp()
{
_playerSpawner = FindObjectOfType<PlayerSpawner>();
_fluidDetector = Locator.GetPlayerCamera().GetComponentInChildren<FluidDetector>();
_playerResources = Locator.GetPlayerTransform().GetComponent<PlayerResources>();
var shipTransform = Locator.GetShipTransform();
if (shipTransform)
{
_shipComponents = Locator.GetShipTransform().GetComponentsInChildren<ShipComponent>();
_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<SpawnPoint[]>("_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;
}
}
}
}