265 lines
6.9 KiB
C#
Raw Normal View History

2020-11-25 09:54:52 +00:00
using QSB.DeathSync;
2020-11-03 21:42:14 +00:00
using QSB.EventsCore;
2020-11-03 17:56:48 +00:00
using QSB.TimeSync.Events;
using UnityEngine;
using UnityEngine.Networking;
namespace QSB.TimeSync
2020-02-15 20:48:02 +01:00
{
public class WakeUpSync : NetworkBehaviour
2020-02-15 20:48:02 +01:00
{
2020-08-09 20:46:02 +01:00
public static WakeUpSync LocalInstance { get; private set; }
private const float TimeThreshold = 0.5f;
private const float MaxFastForwardSpeed = 60f;
private const float MaxFastForwardDiff = 20f;
private const float MinFastForwardSpeed = 2f;
private enum State { NotLoaded, Loaded, FastForwarding, Pausing }
private State _state = State.NotLoaded;
private float _sendTimer;
private float _serverTime;
private float _timeScale;
private bool _isInputEnabled = true;
2020-08-13 22:10:25 +01:00
private bool _isFirstFastForward = true;
private int _localLoopCount;
private int _serverLoopCount;
2020-02-15 20:48:02 +01:00
2020-08-09 20:46:02 +01:00
public override void OnStartLocalPlayer()
{
LocalInstance = this;
}
2020-02-15 20:48:02 +01:00
private void Start()
{
if (!isLocalPlayer)
{
return;
}
2020-08-16 22:39:21 +02:00
if (QSBSceneManager.IsInUniverse)
{
Init();
}
else
{
2020-08-16 22:39:21 +02:00
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
2020-08-10 19:24:28 +02:00
GlobalMessenger.AddListener(EventNames.RestartTimeLoop, OnLoopStart);
2020-09-06 09:07:31 +01:00
GlobalMessenger.AddListener(EventNames.WakeUp, OnWakeUp);
}
private void OnWakeUp()
{
if (NetworkServer.active)
{
QSB.HasWokenUp = true;
}
}
2020-08-18 13:56:07 +01:00
private void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
GlobalMessenger.RemoveListener(EventNames.RestartTimeLoop, OnLoopStart);
}
2020-08-16 22:39:21 +02:00
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
2020-09-06 09:07:31 +01:00
QSB.HasWokenUp = false;
2020-08-16 22:39:21 +02:00
if (isInUniverse)
{
Init();
}
else
{
Reset();
}
}
private void OnLoopStart()
{
_localLoopCount++;
}
private void Init()
2020-02-15 20:48:02 +01:00
{
2020-08-10 19:24:28 +02:00
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
_state = State.Loaded;
gameObject.AddComponent<PreserveTimeScale>();
if (isServer)
2020-02-15 20:48:02 +01:00
{
SendServerTime();
}
else
{
WakeUpOrSleep();
}
}
private void Reset()
{
_state = State.NotLoaded;
}
private void SendServerTime()
{
2020-08-10 19:24:28 +02:00
GlobalMessenger<float, int>.FireEvent(EventNames.QSBServerTime, Time.timeSinceLevelLoad, _localLoopCount);
}
2020-08-09 21:46:51 +01:00
public void OnClientReceiveMessage(ServerTimeMessage message)
2020-02-15 20:48:02 +01:00
{
if (isServer)
2020-02-15 20:48:02 +01:00
{
return;
}
_serverTime = message.ServerTime;
_serverLoopCount = message.LoopCount;
WakeUpOrSleep();
}
private void WakeUpOrSleep()
{
if (_state == State.NotLoaded || _localLoopCount != _serverLoopCount)
{
return;
}
var myTime = Time.timeSinceLevelLoad;
var diff = myTime - _serverTime;
if (diff > TimeThreshold)
{
StartPausing();
return;
}
if (diff < -TimeThreshold)
{
2020-07-28 15:59:24 +02:00
StartFastForwarding();
}
}
2020-07-28 15:59:24 +02:00
private void StartFastForwarding()
{
if (_state == State.FastForwarding)
{
return;
}
_timeScale = MaxFastForwardSpeed;
_state = State.FastForwarding;
2020-11-25 09:54:52 +00:00
FastForwardUI.Start();
}
private void StartPausing()
{
if (_state == State.Pausing)
{
return;
}
_timeScale = 0f;
_state = State.Pausing;
2020-08-13 22:06:34 +01:00
SpinnerUI.Show();
}
private void ResetTimeScale()
{
_timeScale = 1f;
_state = State.Loaded;
if (!_isInputEnabled)
{
EnableInput();
}
2020-08-13 22:10:25 +01:00
_isFirstFastForward = false;
2020-09-06 09:07:31 +01:00
QSB.HasWokenUp = true;
2020-08-13 22:06:34 +01:00
Physics.SyncTransforms();
SpinnerUI.Hide();
2020-11-25 09:54:52 +00:00
FastForwardUI.Stop();
2020-08-13 22:06:34 +01:00
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
2020-08-23 12:48:31 +01:00
RespawnOnDeath.Instance.Init();
}
private void DisableInput()
{
_isInputEnabled = false;
OWInput.ChangeInputMode(InputMode.None);
}
private void EnableInput()
{
_isInputEnabled = true;
OWInput.ChangeInputMode(InputMode.Character);
}
private void Update()
{
if (isServer)
{
UpdateServer();
}
else if (isLocalPlayer)
{
UpdateLocal();
}
}
private void UpdateServer()
{
if (_state != State.Loaded)
{
return;
}
_sendTimer += Time.unscaledDeltaTime;
if (_sendTimer > 1)
{
SendServerTime();
_sendTimer = 0;
}
}
private void UpdateLocal()
{
_serverTime += Time.unscaledDeltaTime;
if (_state == State.NotLoaded)
{
return;
}
if (_state == State.FastForwarding)
{
var diff = _serverTime - Time.timeSinceLevelLoad;
Time.timeScale = Mathf.Lerp(MinFastForwardSpeed, MaxFastForwardSpeed, Mathf.Abs(diff) / MaxFastForwardDiff);
2020-08-13 22:10:25 +01:00
2020-08-16 22:39:21 +02:00
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem && _isFirstFastForward)
2020-08-13 22:10:25 +01:00
{
var spawnPoint = Locator.GetPlayerBody().GetComponent<PlayerSpawner>().GetInitialSpawnPoint().transform;
Locator.GetPlayerTransform().position = spawnPoint.position;
Locator.GetPlayerTransform().rotation = spawnPoint.rotation;
2020-08-13 22:10:25 +01:00
Physics.SyncTransforms();
}
}
else
{
Time.timeScale = _timeScale;
}
2020-07-28 15:59:24 +02:00
var isDoneFastForwarding = _state == State.FastForwarding && Time.timeSinceLevelLoad >= _serverTime;
var isDonePausing = _state == State.Pausing && Time.timeSinceLevelLoad < _serverTime;
if (isDoneFastForwarding || isDonePausing)
{
ResetTimeScale();
}
if (!_isInputEnabled && OWInput.GetInputMode() != InputMode.None)
{
DisableInput();
}
}
}
}