mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2024-12-28 00:19:27 +00:00
199 lines
5.4 KiB
C#
199 lines
5.4 KiB
C#
using Mirror;
|
|
using QSB.DeathSync.Messages;
|
|
using QSB.Messaging;
|
|
using QSB.Patches;
|
|
using QSB.Player;
|
|
using QSB.Player.TransformSync;
|
|
using QSB.RespawnSync.Messages;
|
|
using QSB.Utility;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace QSB.RespawnSync;
|
|
|
|
public class RespawnManager : MonoBehaviour, IAddComponentOnStart
|
|
{
|
|
public static RespawnManager Instance;
|
|
|
|
public bool RespawnNeeded => _playersPendingRespawn.Count != 0;
|
|
|
|
private readonly List<PlayerInfo> _playersPendingRespawn = new();
|
|
private NotificationData _previousNotification;
|
|
private GameObject _owRecoveryPoint;
|
|
private GameObject _qsbRecoveryPoint;
|
|
|
|
private void Awake()
|
|
{
|
|
Instance = this;
|
|
QSBSceneManager.OnSceneLoaded += (_, newScene, inUniverse)
|
|
=> Delay.RunWhen(
|
|
() => Locator.GetMarkerManager() != null,
|
|
() => Init(newScene, inUniverse));
|
|
QSBNetworkManager.singleton.OnClientConnected += OnConnected;
|
|
QSBNetworkManager.singleton.OnClientDisconnected += OnDisconnected;
|
|
|
|
QSBPlayerManager.OnRemovePlayer += player =>
|
|
{
|
|
_playersPendingRespawn.Remove(player);
|
|
};
|
|
}
|
|
|
|
private void OnConnected()
|
|
{
|
|
if (QSBSceneManager.IsInUniverse)
|
|
{
|
|
Delay.RunWhen(
|
|
() => PlayerTransformSync.LocalInstance != null,
|
|
() => Init(QSBSceneManager.CurrentScene, true));
|
|
}
|
|
}
|
|
|
|
private void OnDisconnected(TransportError error, string reason)
|
|
{
|
|
_owRecoveryPoint?.SetActive(true);
|
|
_qsbRecoveryPoint?.SetActive(false);
|
|
}
|
|
|
|
private void Init(OWScene newScene, bool inUniverse)
|
|
{
|
|
if (!QSBCore.IsInMultiplayer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (PlayerTransformSync.LocalInstance == null)
|
|
{
|
|
DebugLog.ToConsole($"Error - Tried to init when PlayerTransformSync.LocalInstance was null!", OWML.Common.MessageType.Error);
|
|
return;
|
|
}
|
|
|
|
QSBPatchManager.DoUnpatchType(QSBPatchTypes.RespawnTime);
|
|
QSBPlayerManager.ShowAllPlayers();
|
|
QSBPlayerManager.LocalPlayer.UpdateStatesFromObjects();
|
|
QSBPlayerManager.PlayerList.ForEach(x => x.IsDead = false);
|
|
_playersPendingRespawn.Clear();
|
|
|
|
if (newScene != OWScene.SolarSystem)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_owRecoveryPoint == null)
|
|
{
|
|
_owRecoveryPoint = GameObject.Find("Systems_Supplies/PlayerRecoveryPoint");
|
|
}
|
|
|
|
if (_owRecoveryPoint == null)
|
|
{
|
|
DebugLog.ToConsole($"Error - Couldn't find the ship's PlayerRecoveryPoint!", OWML.Common.MessageType.Error);
|
|
return;
|
|
}
|
|
|
|
_owRecoveryPoint.SetActive(false);
|
|
|
|
var Systems_Supplies = _owRecoveryPoint.gameObject.transform.parent;
|
|
|
|
if (_qsbRecoveryPoint == null)
|
|
{
|
|
_qsbRecoveryPoint = new GameObject("QSBPlayerRecoveryPoint");
|
|
_qsbRecoveryPoint.SetActive(false);
|
|
_qsbRecoveryPoint.transform.parent = Systems_Supplies;
|
|
_qsbRecoveryPoint.transform.localPosition = new Vector3(2.46f, 1.957f, 1.156f);
|
|
_qsbRecoveryPoint.transform.localRotation = Quaternion.Euler(0, 6.460001f, 0f);
|
|
_qsbRecoveryPoint.layer = 21;
|
|
|
|
var boxCollider = _qsbRecoveryPoint.AddComponent<BoxCollider>();
|
|
boxCollider.isTrigger = true;
|
|
boxCollider.size = new Vector3(1.3f, 1.01f, 0.47f);
|
|
|
|
var multiInteract = _qsbRecoveryPoint.AddComponent<MultiInteractReceiver>();
|
|
multiInteract._usableInShip = true;
|
|
multiInteract._interactRange = 1.5f;
|
|
|
|
_qsbRecoveryPoint.AddComponent<ShipRecoveryPoint>();
|
|
_qsbRecoveryPoint.AddComponent<RespawnHUDMarker>();
|
|
}
|
|
|
|
_qsbRecoveryPoint.SetActive(true);
|
|
}
|
|
|
|
public void TriggerRespawnMap()
|
|
{
|
|
Locator.GetPauseCommandListener().RemovePauseCommandLock();
|
|
QSBPatchManager.DoPatchType(QSBPatchTypes.RespawnTime);
|
|
Delay.RunNextFrame(() => GlobalMessenger.FireEvent("TriggerObservatoryMap"));
|
|
}
|
|
|
|
public void Respawn()
|
|
{
|
|
var mapController = FindObjectOfType<MapController>();
|
|
QSBPatchManager.DoUnpatchType(QSBPatchTypes.RespawnTime);
|
|
|
|
var playerSpawner = FindObjectOfType<PlayerSpawner>();
|
|
playerSpawner.DebugWarp(playerSpawner.GetSpawnPoint(SpawnLocation.Ship));
|
|
|
|
mapController.ExitMapView();
|
|
|
|
var cameraEffectController = Locator.GetPlayerCamera().GetComponent<PlayerCameraEffectController>();
|
|
cameraEffectController.OpenEyes(1f);
|
|
|
|
OWInput.ChangeInputMode(InputMode.Character);
|
|
|
|
var mixer = Locator.GetAudioMixer();
|
|
mixer._deathMixed = false;
|
|
mixer._nonEndTimesVolume.FadeTo(1, 0.5f);
|
|
mixer._endTimesVolume.FadeTo(1, 0.5f);
|
|
mixer.UnmixMap();
|
|
}
|
|
|
|
public void OnPlayerDeath(PlayerInfo player)
|
|
{
|
|
player.Die();
|
|
|
|
if (_playersPendingRespawn.Contains(player))
|
|
{
|
|
DebugLog.ToConsole($"Warning - Received death message for player who is already in _playersPendingRespawn!", OWML.Common.MessageType.Warning);
|
|
}
|
|
else
|
|
{
|
|
_playersPendingRespawn.Add(player);
|
|
}
|
|
|
|
var deadPlayersCount = QSBPlayerManager.PlayerList.Count(x => x.IsDead);
|
|
|
|
if (deadPlayersCount == QSBPlayerManager.PlayerList.Count && !QSBCore.DebugSettings.DisableLoopDeath)
|
|
{
|
|
new EndLoopMessage().Send();
|
|
return;
|
|
}
|
|
}
|
|
|
|
public void OnPlayerRespawn(PlayerInfo player)
|
|
{
|
|
player.Revive();
|
|
|
|
if (!_playersPendingRespawn.Contains(player))
|
|
{
|
|
DebugLog.ToConsole($"Warning - Received respawn message for player who is not in _playersPendingRespawn!", OWML.Common.MessageType.Warning);
|
|
}
|
|
else
|
|
{
|
|
_playersPendingRespawn.Remove(player);
|
|
}
|
|
}
|
|
|
|
public void RespawnSomePlayer()
|
|
{
|
|
var playerToRespawn = _playersPendingRespawn.First();
|
|
|
|
if (!playerToRespawn.IsDead)
|
|
{
|
|
DebugLog.ToConsole($"Warning - Tried to respawn player {playerToRespawn.PlayerId} who isn't dead!", OWML.Common.MessageType.Warning);
|
|
_playersPendingRespawn.Remove(playerToRespawn);
|
|
return;
|
|
}
|
|
|
|
new PlayerRespawnMessage(playerToRespawn.PlayerId).Send();
|
|
}
|
|
} |