mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-04 03:39:55 +00:00
Merge pull request #300 from misternebula/respawn-overhaul
Respawn overhaul
This commit is contained in:
commit
9c7a09d0da
1
.gitignore
vendored
1
.gitignore
vendored
@ -361,6 +361,7 @@ QSB.csproj.user
|
||||
GameAssets/
|
||||
Chert/
|
||||
Riebeck/
|
||||
IgnoreInGithub/
|
||||
OWML.Config.json
|
||||
WeavedFiles/QSB.dll
|
||||
WeavedFiles/QSB.dll.mdb
|
||||
|
@ -3,7 +3,7 @@ CRC: 2815158869
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 81bbcd8775249928cc67d7ff90ff9047
|
||||
Hash: 5677b7876f2afae05c0920067ef29e8a
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 4d6a73cb377370ba69c96eb5da1b5028
|
||||
|
Binary file not shown.
@ -1,9 +1,9 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 1574640978
|
||||
CRC: 3621554448
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 7f0a5acd2c87eeadfd051836171b2256
|
||||
Hash: c9002a0b83220186e94179a065236b5c
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 8b6abf066340f652e25eed06e6b72102
|
||||
@ -22,10 +22,8 @@ ClassTypes:
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
Assets:
|
||||
- Assets/NetworkStickPivot.prefab
|
||||
- Assets/NetworkPlayer.prefab
|
||||
- Assets/NetworkCameraRoot.prefab
|
||||
- Assets/NetworkProbe.prefab
|
||||
- Assets/NETWORK_Player_Body.prefab
|
||||
- Assets/NetworkOrb.prefab
|
||||
- Assets/NetworkShip.prefab
|
||||
Dependencies: []
|
||||
|
@ -53,7 +53,7 @@ namespace QSB.Animation.NPC.Patches
|
||||
{
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - {__instance.name} is in conversation with a null player! Defaulting to active camera.", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - {__instance.name} is in conversation with a null player! Defaulting to active camera.", MessageType.Error);
|
||||
playerToUse = QSBPlayerManager.LocalPlayer;
|
||||
}
|
||||
else
|
||||
|
@ -1,4 +1,5 @@
|
||||
using QSB.WorldSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
@ -15,10 +16,10 @@ namespace QSB.Animation.NPC.WorldObjects
|
||||
public abstract CharacterDialogueTree GetDialogueTree();
|
||||
|
||||
public virtual void StartConversation()
|
||||
=> QSBWorldSync.RaiseEvent(GetDialogueTree(), "OnStartConversation");
|
||||
=> GetDialogueTree().RaiseEvent("OnStartConversation");
|
||||
|
||||
public virtual void EndConversation()
|
||||
=> QSBWorldSync.RaiseEvent(GetDialogueTree(), "OnEndConversation");
|
||||
=> GetDialogueTree().RaiseEvent("OnEndConversation");
|
||||
|
||||
public abstract bool InConversation();
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace QSB.Animation.Player
|
||||
QSBSceneManager.OnUniverseSceneLoaded -= OnUniverseSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnUniverseSceneLoaded(OWScene obj) => LoadControllers();
|
||||
private void OnUniverseSceneLoaded(OWScene oldScene, OWScene newScene) => LoadControllers();
|
||||
|
||||
private void LoadControllers()
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.Patches
|
||||
@ -91,24 +91,24 @@ namespace QSB.Animation.Patches
|
||||
if (!____leftFootGrounded && leftFootLift < 0.333f)
|
||||
{
|
||||
____leftFootGrounded = true;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnLeftFootGrounded");
|
||||
__instance.RaiseEvent("OnLeftFootGrounded");
|
||||
}
|
||||
else if (____leftFootGrounded && leftFootLift > 0.666f)
|
||||
{
|
||||
____leftFootGrounded = false;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnLeftFootLift");
|
||||
__instance.RaiseEvent("OnLeftFootLift");
|
||||
}
|
||||
|
||||
var rightFootLift = ____animator.GetFloat("RightFootLift");
|
||||
if (!____rightFootGrounded && rightFootLift < 0.333f)
|
||||
{
|
||||
____rightFootGrounded = true;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnRightFootGrounded");
|
||||
__instance.RaiseEvent("OnRightFootGrounded");
|
||||
}
|
||||
else if (____rightFootGrounded && rightFootLift > 0.666f)
|
||||
{
|
||||
____rightFootGrounded = false;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnRightFootLift");
|
||||
__instance.RaiseEvent("OnRightFootLift");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,9 @@ namespace QSB.Animation.Player.Thrusters
|
||||
CreateThrusterFlameController(newVfx, player);
|
||||
|
||||
newVfx.transform.parent = player.Body.transform;
|
||||
// Body isnt the actualy player body... it's the model... ;(
|
||||
newVfx.transform.localPosition = new Vector3(0, 10.24412f, 2.268939f);
|
||||
newVfx.transform.rotation = Quaternion.Euler(1.5f, 0, 0);
|
||||
newVfx.transform.localScale = new Vector3(10, 10, 10);
|
||||
newVfx.transform.localPosition = Vector3.zero;
|
||||
newVfx.transform.rotation = Quaternion.Euler(0, 0, 0);
|
||||
newVfx.transform.localScale = new Vector3(1, 1, 1);
|
||||
|
||||
// Deleted objects take 1 update to actually be deleted
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() => newVfx.SetActive(true));
|
||||
|
13
QSB/ClientServerStateSync/ClientState.cs
Normal file
13
QSB/ClientServerStateSync/ClientState.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace QSB.ClientServerStateSync
|
||||
{
|
||||
public enum ClientState
|
||||
{
|
||||
NotLoaded,
|
||||
InTitleScreen,
|
||||
AliveInSolarSystem,
|
||||
DeadInSolarSystem,
|
||||
AliveInEye,
|
||||
WaitingForOthersToDieInSolarSystem,
|
||||
WaitingForOthersToReadyInSolarSystem
|
||||
}
|
||||
}
|
125
QSB/ClientServerStateSync/ClientStateManager.cs
Normal file
125
QSB/ClientServerStateSync/ClientStateManager.cs
Normal file
@ -0,0 +1,125 @@
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ClientServerStateSync
|
||||
{
|
||||
internal class ClientStateManager : MonoBehaviour
|
||||
{
|
||||
public static ClientStateManager Instance { get; private set; }
|
||||
|
||||
public event ChangeStateEvent OnChangeState;
|
||||
public delegate void ChangeStateEvent(ClientState newState);
|
||||
|
||||
private void Awake()
|
||||
=> Instance = this;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance != null, () => QSBEventManager.FireEvent(EventNames.QSBClientState, ForceGetCurrentState()));
|
||||
}
|
||||
|
||||
public void ChangeClientState(ClientState newState)
|
||||
{
|
||||
if (QSBPlayerManager.LocalPlayer.State == newState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DebugLog.DebugWrite($"CHANGE CLIENT STATE FROM {QSBPlayerManager.LocalPlayer.State} to {newState}");
|
||||
QSBPlayerManager.LocalPlayer.State = newState;
|
||||
OnChangeState?.Invoke(newState);
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
|
||||
{
|
||||
var serverState = ServerStateManager.Instance.GetServerState();
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
if (newScene == OWScene.SolarSystem && oldScene != OWScene.SolarSystem)
|
||||
{
|
||||
DebugLog.DebugWrite($"Server is loading SolarSystem just after creating server.");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
}
|
||||
|
||||
if (newScene == OWScene.SolarSystem && oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
DebugLog.DebugWrite($"Server is reloading SolarSystem");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.WaitingForOthersToReadyInSolarSystem);
|
||||
}
|
||||
|
||||
if (newScene == OWScene.TitleScreen)
|
||||
{
|
||||
DebugLog.DebugWrite($"Server has gone back to title screen");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.InTitleScreen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newScene == OWScene.SolarSystem && oldScene != OWScene.SolarSystem && serverState != ServerState.AwaitingPlayConfirmation)
|
||||
{
|
||||
DebugLog.DebugWrite($"Client is loading SolarSystem just after connecting.");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
}
|
||||
|
||||
if (newScene == OWScene.SolarSystem && oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
DebugLog.DebugWrite($"Client is reloading SolarSystem");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.WaitingForOthersToReadyInSolarSystem);
|
||||
}
|
||||
|
||||
if (serverState == ServerState.WaitingForDeath)
|
||||
{
|
||||
DebugLog.DebugWrite($"Client loaded new scene while server is waiting for all players to die");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.WaitingForOthersToReadyInSolarSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDeath()
|
||||
{
|
||||
var currentScene = QSBSceneManager.CurrentScene;
|
||||
if (currentScene == OWScene.SolarSystem)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.DeadInSolarSystem);
|
||||
}
|
||||
else if (currentScene == OWScene.EyeOfTheUniverse)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - You died in the Eye? HOW DID YOU DO THAT?!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
// whaaaaaaaaa
|
||||
DebugLog.ToConsole($"Error - You died... in a menu? In the credits? In any case, you should never see this. :P", OWML.Common.MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientState ForceGetCurrentState()
|
||||
{
|
||||
var currentScene = LoadManager.GetCurrentScene();
|
||||
var lastScene = LoadManager.GetPreviousScene();
|
||||
|
||||
if (currentScene == OWScene.TitleScreen || currentScene == OWScene.Credits_Fast || currentScene == OWScene.Credits_Final)
|
||||
{
|
||||
return ClientState.InTitleScreen;
|
||||
}
|
||||
|
||||
// cant join while dead...
|
||||
|
||||
if (currentScene == OWScene.SolarSystem)
|
||||
{
|
||||
return ClientState.AliveInSolarSystem;
|
||||
}
|
||||
|
||||
if (currentScene == OWScene.EyeOfTheUniverse)
|
||||
{
|
||||
return ClientState.AliveInEye;
|
||||
}
|
||||
|
||||
return ClientState.NotLoaded;
|
||||
}
|
||||
}
|
||||
}
|
41
QSB/ClientServerStateSync/Events/ClientStateEvent.cs
Normal file
41
QSB/ClientServerStateSync/Events/ClientStateEvent.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.ClientServerStateSync.Events
|
||||
{
|
||||
internal class ClientStateEvent : QSBEvent<EnumMessage<ClientState>>
|
||||
{
|
||||
public override EventType Type => EventType.ClientState;
|
||||
|
||||
public override void SetupListener()
|
||||
=> GlobalMessenger<ClientState>.AddListener(EventNames.QSBClientState, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
=> GlobalMessenger<ClientState>.RemoveListener(EventNames.QSBClientState, Handler);
|
||||
|
||||
private void Handler(ClientState state) => SendEvent(CreateMessage(state));
|
||||
|
||||
private EnumMessage<ClientState> CreateMessage(ClientState state) => new EnumMessage<ClientState>
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = state
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, EnumMessage<ClientState> message)
|
||||
=> ClientStateManager.Instance.ChangeClientState(message.EnumValue);
|
||||
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<ClientState> message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Remote receive id:{message.AboutId} state:{message.EnumValue}");
|
||||
if (message.AboutId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - ID is uint.MaxValue!", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
player.State = message.EnumValue;
|
||||
}
|
||||
}
|
||||
}
|
30
QSB/ClientServerStateSync/Events/ServerStateEvent.cs
Normal file
30
QSB/ClientServerStateSync/Events/ServerStateEvent.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
|
||||
namespace QSB.ClientServerStateSync.Events
|
||||
{
|
||||
internal class ServerStateEvent : QSBEvent<EnumMessage<ServerState>>
|
||||
{
|
||||
public override EventType Type => EventType.ServerState;
|
||||
|
||||
public override void SetupListener()
|
||||
=> GlobalMessenger<ServerState>.AddListener(EventNames.QSBServerState, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
=> GlobalMessenger<ServerState>.RemoveListener(EventNames.QSBServerState, Handler);
|
||||
|
||||
private void Handler(ServerState state) => SendEvent(CreateMessage(state));
|
||||
|
||||
private EnumMessage<ServerState> CreateMessage(ServerState state) => new EnumMessage<ServerState>
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = state
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, EnumMessage<ServerState> message)
|
||||
=> OnReceiveRemote(server, message);
|
||||
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<ServerState> message)
|
||||
=> ServerStateManager.Instance.ChangeServerState(message.EnumValue);
|
||||
}
|
||||
}
|
26
QSB/ClientServerStateSync/ServerState.cs
Normal file
26
QSB/ClientServerStateSync/ServerState.cs
Normal file
@ -0,0 +1,26 @@
|
||||
namespace QSB.ClientServerStateSync
|
||||
{
|
||||
public enum ServerState
|
||||
{
|
||||
// When in menus
|
||||
NotLoaded,
|
||||
|
||||
// When in any credits
|
||||
Credits,
|
||||
|
||||
// For normal play in SolarSystem
|
||||
InSolarSystem,
|
||||
|
||||
// For normal play in EyeOfTheUniverse
|
||||
InEye,
|
||||
|
||||
// At end of loop, waiting for everyone to be ready to reload the scene
|
||||
WaitingForDeath,
|
||||
|
||||
// At start of loop, waiting for everybody to be ready to start playing
|
||||
AwaitingPlayConfirmation,
|
||||
|
||||
// When the statue has been activated
|
||||
InStatueCutscene
|
||||
}
|
||||
}
|
126
QSB/ClientServerStateSync/ServerStateManager.cs
Normal file
126
QSB/ClientServerStateSync/ServerStateManager.cs
Normal file
@ -0,0 +1,126 @@
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ClientServerStateSync
|
||||
{
|
||||
internal class ServerStateManager : MonoBehaviour
|
||||
{
|
||||
public static ServerStateManager Instance { get; private set; }
|
||||
|
||||
public event ChangeStateEvent OnChangeState;
|
||||
public delegate void ChangeStateEvent(ServerState newState);
|
||||
|
||||
private ServerState _currentState;
|
||||
|
||||
private void Awake()
|
||||
=> Instance = this;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
GlobalMessenger.AddListener("TriggerSupernova", OnTriggerSupernova);
|
||||
|
||||
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance != null, () => QSBEventManager.FireEvent(EventNames.QSBServerState, ForceGetCurrentState()));
|
||||
}
|
||||
|
||||
public void ChangeServerState(ServerState newState)
|
||||
{
|
||||
if (_currentState == newState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DebugLog.DebugWrite($"CHANGE SERVER STATE FROM {_currentState} to {newState}");
|
||||
_currentState = newState;
|
||||
OnChangeState?.Invoke(newState);
|
||||
}
|
||||
|
||||
public ServerState GetServerState()
|
||||
=> _currentState;
|
||||
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
|
||||
{
|
||||
switch (newScene)
|
||||
{
|
||||
case OWScene.Credits_Fast:
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.Credits);
|
||||
break;
|
||||
|
||||
case OWScene.TitleScreen:
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
|
||||
break;
|
||||
|
||||
case OWScene.SolarSystem:
|
||||
if (oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.AwaitingPlayConfirmation);
|
||||
}
|
||||
else
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
|
||||
}
|
||||
break;
|
||||
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.AwaitingPlayConfirmation);
|
||||
break;
|
||||
|
||||
case OWScene.None:
|
||||
case OWScene.Undefined:
|
||||
default:
|
||||
DebugLog.ToConsole($"Warning - newScene is {newScene}!", OWML.Common.MessageType.Warning);
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerSupernova()
|
||||
{
|
||||
DebugLog.DebugWrite($"TriggerSupernova");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForDeath);
|
||||
}
|
||||
|
||||
private ServerState ForceGetCurrentState()
|
||||
{
|
||||
var currentScene = LoadManager.GetCurrentScene();
|
||||
var lastScene = LoadManager.GetPreviousScene();
|
||||
|
||||
switch (currentScene)
|
||||
{
|
||||
case OWScene.SolarSystem:
|
||||
return ServerState.InSolarSystem;
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
return ServerState.InEye;
|
||||
default:
|
||||
return ServerState.NotLoaded;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentState == ServerState.AwaitingPlayConfirmation)
|
||||
{
|
||||
if (QSBPlayerManager.PlayerList.All(x => x.State == ClientState.WaitingForOthersToReadyInSolarSystem))
|
||||
{
|
||||
DebugLog.DebugWrite($"All ready!!");
|
||||
QSBEventManager.FireEvent(EventNames.QSBStartLoop);
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
QSB/DeathSync/EndLoopReason.cs
Normal file
7
QSB/DeathSync/EndLoopReason.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace QSB.DeathSync
|
||||
{
|
||||
public enum EndLoopReason
|
||||
{
|
||||
AllPlayersDead = 0
|
||||
}
|
||||
}
|
41
QSB/DeathSync/Events/EndLoopEvent.cs
Normal file
41
QSB/DeathSync/Events/EndLoopEvent.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.DeathSync.Events
|
||||
{
|
||||
internal class EndLoopEvent : QSBEvent<EnumMessage<EndLoopReason>>
|
||||
{
|
||||
public override EventType Type => EventType.EndLoop;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger<EndLoopReason>.AddListener(EventNames.QSBEndLoop, Handler);
|
||||
public override void CloseListener() => GlobalMessenger<EndLoopReason>.RemoveListener(EventNames.QSBEndLoop, Handler);
|
||||
|
||||
private void Handler(EndLoopReason type) => SendEvent(CreateMessage(type));
|
||||
|
||||
private EnumMessage<EndLoopReason> CreateMessage(EndLoopReason type) => new EnumMessage<EndLoopReason>
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = type
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, EnumMessage<EndLoopReason> message)
|
||||
=> OnReceiveRemote(server, message);
|
||||
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<EndLoopReason> message)
|
||||
{
|
||||
switch (message.EnumValue)
|
||||
{
|
||||
case EndLoopReason.AllPlayersDead:
|
||||
DebugLog.DebugWrite($"all players dead");
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForDeath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using QSB.Events;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
|
||||
@ -20,11 +21,23 @@ namespace QSB.DeathSync.Events
|
||||
NecronomiconIndex = Necronomicon.GetRandomIndex(type)
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, PlayerDeathMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"RECEIVE LOCAL PLAYER DEATH");
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
RespawnManager.Instance.OnPlayerDeath(player);
|
||||
ClientStateManager.Instance.OnDeath();
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerDeathMessage message)
|
||||
{
|
||||
var playerName = QSBPlayerManager.GetPlayer(message.AboutId).Name;
|
||||
DebugLog.DebugWrite($"RECEIVE REMOTE PLAYER DEATH");
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
var playerName = player.Name;
|
||||
var deathMessage = Necronomicon.GetPhrase(message.EnumValue, message.NecronomiconIndex);
|
||||
DebugLog.ToAll(string.Format(deathMessage, playerName));
|
||||
|
||||
RespawnManager.Instance.OnPlayerDeath(player);
|
||||
}
|
||||
}
|
||||
}
|
37
QSB/DeathSync/Events/PlayerRespawnEvent.cs
Normal file
37
QSB/DeathSync/Events/PlayerRespawnEvent.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.DeathSync.Events
|
||||
{
|
||||
internal class PlayerRespawnEvent : QSBEvent<PlayerMessage>
|
||||
{
|
||||
public override EventType Type => EventType.PlayerRespawn;
|
||||
|
||||
public override void SetupListener()
|
||||
=> GlobalMessenger<uint>.AddListener(EventNames.QSBPlayerRespawn, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
=> GlobalMessenger<uint>.RemoveListener(EventNames.QSBPlayerRespawn, Handler);
|
||||
|
||||
private void Handler(uint playerId) => SendEvent(CreateMessage(playerId));
|
||||
|
||||
private PlayerMessage CreateMessage(uint playerId) => new PlayerMessage
|
||||
{
|
||||
AboutId = playerId
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, PlayerMessage message)
|
||||
=> OnReceiveRemote(server, message);
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerMessage message)
|
||||
{
|
||||
if (message.AboutId == LocalPlayerId)
|
||||
{
|
||||
RespawnManager.Instance.Respawn();
|
||||
}
|
||||
|
||||
RespawnManager.Instance.OnPlayerRespawn(QSBPlayerManager.GetPlayer(message.AboutId));
|
||||
}
|
||||
}
|
||||
}
|
31
QSB/DeathSync/Events/StartLoopEvent.cs
Normal file
31
QSB/DeathSync/Events/StartLoopEvent.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.DeathSync.Events
|
||||
{
|
||||
internal class StartLoopEvent : QSBEvent<PlayerMessage>
|
||||
{
|
||||
public override EventType Type => EventType.StartLoop;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBStartLoop, Handler);
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBStartLoop, Handler);
|
||||
|
||||
private void Handler() => SendEvent(CreateMessage());
|
||||
|
||||
private PlayerMessage CreateMessage() => new PlayerMessage
|
||||
{
|
||||
AboutId = LocalPlayerId
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, PlayerMessage message)
|
||||
=> OnReceiveRemote(server, message);
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($" ~~~ LOOP START ~~~");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
using Harmony;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.ShipSync;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
@ -186,6 +188,7 @@ namespace QSB.DeathSync.Patches
|
||||
|
||||
public static bool DeathManager_KillPlayer_Prefix(DeathType deathType)
|
||||
{
|
||||
DebugLog.DebugWrite($"KILL PLAYER PREFIX stacetrace : \r\n {Environment.StackTrace}");
|
||||
if (RespawnOnDeath.Instance == null)
|
||||
{
|
||||
return true;
|
||||
@ -196,31 +199,26 @@ namespace QSB.DeathSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ShipManager.Instance.HasAuthority)
|
||||
{
|
||||
RespawnOnDeath.Instance.ResetPlayer();
|
||||
return false;
|
||||
}
|
||||
QSBPlayerManager.LocalPlayer.IsDead = true;
|
||||
|
||||
RespawnOnDeath.Instance.ResetShip();
|
||||
RespawnOnDeath.Instance.ResetPlayer();
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void DeathManager_KillPlayer_Postfix(DeathType deathType)
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
|
||||
{
|
||||
DebugLog.DebugWrite($"KILL PLAYER POSTFIX");
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
|
||||
}
|
||||
|
||||
public static void ShipDamageController_Awake(ref bool ____exploded)
|
||||
=> ____exploded = true;
|
||||
|
||||
public static IEnumerable<CodeInstruction> ReturnNull(IEnumerable<CodeInstruction> instructions)
|
||||
{
|
||||
return new List<CodeInstruction>
|
||||
public static IEnumerable<CodeInstruction> ReturnNull(IEnumerable<CodeInstruction> instructions) => new List<CodeInstruction>
|
||||
{
|
||||
new CodeInstruction(OpCodes.Ldnull),
|
||||
new CodeInstruction(OpCodes.Ret)
|
||||
};
|
||||
}
|
||||
|
||||
public static bool DestructionVolume_VanishShip(DeathType ____deathType)
|
||||
{
|
||||
@ -238,9 +236,8 @@ namespace QSB.DeathSync.Patches
|
||||
{
|
||||
Locator.GetDeathManager().KillPlayer(____deathType);
|
||||
}
|
||||
// Ship is being destroyed, but player isn't in it.
|
||||
RespawnOnDeath.Instance.ResetShip();
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
248
QSB/DeathSync/Patches/MapPatches.cs
Normal file
248
QSB/DeathSync/Patches/MapPatches.cs
Normal file
@ -0,0 +1,248 @@
|
||||
using QSB.Patches;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.DeathSync.Patches
|
||||
{
|
||||
internal class MapPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.RespawnTime;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(MapController_LateUpdate));
|
||||
Prefix(nameof(MapController_EnterMapView));
|
||||
}
|
||||
|
||||
public static bool MapController_EnterMapView(
|
||||
MapController __instance,
|
||||
ref bool ____isMapMode,
|
||||
OWAudioSource ____audioSource,
|
||||
MapMarkerManager ____mapMarkerManager,
|
||||
OWCamera ____mapCamera,
|
||||
OWCamera ____activeCam,
|
||||
MeshRenderer ____gridRenderer,
|
||||
ref Transform ____targetTransform,
|
||||
ref bool ____lockedToTargetTransform,
|
||||
ref Vector3 ____position,
|
||||
ref float ____yaw,
|
||||
ref float ____pitch,
|
||||
ref float ____zoom,
|
||||
ref float ____targetZoom,
|
||||
ref bool ____interpPosition,
|
||||
ref bool ____interpPitch,
|
||||
ref bool ____interpZoom,
|
||||
ref bool ____framingPlayer,
|
||||
ref float ____lockTimer,
|
||||
float ____defaultYawAngle,
|
||||
float ____initialPitchAngle,
|
||||
float ____initialZoomDist,
|
||||
float ____defaultZoomDist,
|
||||
float ____lockOnMoveLength,
|
||||
ref float ____gridOverrideSize,
|
||||
ref bool ____gridOverride,
|
||||
ref float ____gridTimer,
|
||||
ref float ____revealLength,
|
||||
ReferenceFrame ____currentRFrame,
|
||||
float ____gridLockOnLength,
|
||||
ref float ____revealTimer
|
||||
)
|
||||
{
|
||||
if (____isMapMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
____mapMarkerManager.SetVisible(true);
|
||||
GlobalMessenger.FireEvent("EnterMapView");
|
||||
GlobalMessenger<OWCamera>.FireEvent("SwitchActiveCamera", ____mapCamera);
|
||||
if (____audioSource.isPlaying)
|
||||
{
|
||||
____audioSource.Stop();
|
||||
____audioSource.SetLocalVolume(1f);
|
||||
____audioSource.Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
____audioSource.SetLocalVolume(1f);
|
||||
____audioSource.Play();
|
||||
}
|
||||
|
||||
Locator.GetAudioMixer().MixMap();
|
||||
____activeCam.enabled = false;
|
||||
____mapCamera.enabled = true;
|
||||
____gridRenderer.enabled = false;
|
||||
____targetTransform = null;
|
||||
____lockedToTargetTransform = false;
|
||||
____position = RespawnOnDeath.Instance.DeathPositionWorld - Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition();
|
||||
____position.y = 0f;
|
||||
____yaw = ____defaultYawAngle;
|
||||
____pitch = ____initialPitchAngle;
|
||||
____zoom = ____initialZoomDist;
|
||||
____targetZoom = ____defaultZoomDist;
|
||||
__instance.transform.rotation = Quaternion.LookRotation(-RespawnOnDeath.Instance.DeathPlayerUpVector, RespawnOnDeath.Instance.DeathPlayerForwardVector);
|
||||
__instance.transform.position = RespawnOnDeath.Instance.DeathPositionWorld;
|
||||
____interpPosition = true;
|
||||
____interpPitch = true;
|
||||
____interpZoom = true;
|
||||
____framingPlayer = ____lockedToTargetTransform;
|
||||
____lockTimer = ____lockOnMoveLength;
|
||||
____gridOverrideSize = (____currentRFrame == null) ? 0f : ____currentRFrame.GetAutopilotArrivalDistance();
|
||||
____gridOverride = ____gridOverrideSize > 0f;
|
||||
____gridTimer = (!____gridOverride) ? 0f : ____gridLockOnLength;
|
||||
____revealLength = 20f;
|
||||
____revealTimer = 0f;
|
||||
____isMapMode = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool MapController_LateUpdate(
|
||||
MapController __instance,
|
||||
ref float ____observatoryRevealTwist,
|
||||
ref float ____defaultPitchAngle,
|
||||
ref float ____initialPitchAngle,
|
||||
OWCamera ____mapCamera,
|
||||
ref float ____lockTimer,
|
||||
ref float ____revealTimer,
|
||||
float ____lockOnMoveLength,
|
||||
float ____revealLength,
|
||||
ref bool ____screenPromptsVisible,
|
||||
bool ____isPaused,
|
||||
ScreenPrompt ____closePrompt,
|
||||
ScreenPrompt ____panPrompt,
|
||||
ScreenPrompt ____rotatePrompt,
|
||||
ScreenPrompt ____zoomPrompt,
|
||||
ref bool ____lockedToTargetTransform,
|
||||
ref bool ____interpPosition,
|
||||
ref bool ____interpPitch,
|
||||
ref bool ____interpZoom,
|
||||
OWCamera ____activeCam,
|
||||
ref Vector3 ____position,
|
||||
float ____panSpeed,
|
||||
ref float ____zoom,
|
||||
float ____maxPanDistance,
|
||||
float ____yawSpeed,
|
||||
ref float ____yaw,
|
||||
float ____pitchSpeed,
|
||||
ref float ____pitch,
|
||||
float ____minPitchAngle,
|
||||
float ____maxPitchAngle,
|
||||
ref float ____targetZoom,
|
||||
float ____minZoomDistance,
|
||||
float ____maxZoomDistance,
|
||||
float ____initialZoomDist,
|
||||
float ____zoomSpeed,
|
||||
float ____observatoryRevealDist
|
||||
)
|
||||
{
|
||||
____lockTimer = Mathf.Min(____lockTimer + Time.deltaTime, ____lockOnMoveLength);
|
||||
____revealTimer = Mathf.Min(____revealTimer + Time.deltaTime, ____revealLength);
|
||||
|
||||
var revealFraction = Mathf.Clamp01(____revealTimer / ____revealLength);
|
||||
var smoothedRevealFraction = Mathf.SmoothStep(0f, 1f, revealFraction);
|
||||
|
||||
var canInteractWith = ____revealTimer > 18f;
|
||||
|
||||
if (____screenPromptsVisible && ____isPaused)
|
||||
{
|
||||
____closePrompt.SetVisibility(false);
|
||||
____panPrompt.SetVisibility(false);
|
||||
____rotatePrompt.SetVisibility(false);
|
||||
____zoomPrompt.SetVisibility(false);
|
||||
____screenPromptsVisible = false;
|
||||
}
|
||||
else if (!____screenPromptsVisible && canInteractWith && !____isPaused)
|
||||
{
|
||||
____closePrompt.SetVisibility(false);
|
||||
____panPrompt.SetVisibility(true);
|
||||
____rotatePrompt.SetVisibility(true);
|
||||
____zoomPrompt.SetVisibility(true);
|
||||
____screenPromptsVisible = true;
|
||||
}
|
||||
|
||||
var XZinput = Vector2.zero;
|
||||
var lookInput = Vector2.zero;
|
||||
var zoomInput = 0f;
|
||||
if (canInteractWith)
|
||||
{
|
||||
XZinput = OWInput.GetValue(InputLibrary.moveXZ, InputMode.All);
|
||||
lookInput = InputLibrary.look.GetValue(false);
|
||||
zoomInput = OWInput.GetValue(InputLibrary.mapZoom, InputMode.All);
|
||||
lookInput.y *= -1f;
|
||||
zoomInput *= -1f;
|
||||
}
|
||||
|
||||
____lockedToTargetTransform &= XZinput.sqrMagnitude < 0.01f;
|
||||
____interpPosition &= XZinput.sqrMagnitude < 0.01f;
|
||||
____interpPitch &= Mathf.Abs(lookInput.y) < 0.1f;
|
||||
____interpZoom &= Mathf.Abs(zoomInput) < 0.1f;
|
||||
|
||||
if (____interpPosition)
|
||||
{
|
||||
var a = ____activeCam.transform.position - Locator.GetCenterOfTheUniverse().GetOffsetPosition();
|
||||
var b = Vector3.zero;
|
||||
____position = Vector3.Lerp(a, b, smoothedRevealFraction);
|
||||
}
|
||||
else
|
||||
{
|
||||
var normalized = Vector3.Scale(__instance.transform.forward + __instance.transform.up, new Vector3(1f, 0f, 1f)).normalized;
|
||||
var a2 = (__instance.transform.right * XZinput.x) + (normalized * XZinput.y);
|
||||
____position += a2 * ____panSpeed * ____zoom * Time.deltaTime;
|
||||
____position.y = 0f;
|
||||
if (____position.sqrMagnitude > ____maxPanDistance * ____maxPanDistance)
|
||||
{
|
||||
____position = ____position.normalized * ____maxPanDistance;
|
||||
}
|
||||
}
|
||||
|
||||
____yaw += lookInput.x * ____yawSpeed * Time.deltaTime;
|
||||
____yaw = OWMath.WrapAngle(____yaw);
|
||||
if (____interpPitch)
|
||||
{
|
||||
____pitch = Mathf.Lerp(____initialPitchAngle, ____defaultPitchAngle, smoothedRevealFraction);
|
||||
}
|
||||
else
|
||||
{
|
||||
____pitch += lookInput.y * ____pitchSpeed * Time.deltaTime;
|
||||
____pitch = Mathf.Clamp(____pitch, ____minPitchAngle, ____maxPitchAngle);
|
||||
}
|
||||
|
||||
if (____interpZoom)
|
||||
{
|
||||
____zoom = Mathf.Lerp(____initialZoomDist, ____targetZoom, smoothedRevealFraction);
|
||||
}
|
||||
else
|
||||
{
|
||||
____zoom += zoomInput * ____zoomSpeed * Time.deltaTime;
|
||||
____zoom = Mathf.Clamp(____zoom, ____minZoomDistance, ____maxZoomDistance);
|
||||
}
|
||||
|
||||
____mapCamera.nearClipPlane = Mathf.Lerp(0.1f, 1f, smoothedRevealFraction);
|
||||
|
||||
var finalRotation = Quaternion.Euler(____pitch, ____yaw, 0f);
|
||||
|
||||
var num4 = revealFraction * (2f - revealFraction);
|
||||
|
||||
var num5 = Mathf.SmoothStep(0f, 1f, num4);
|
||||
|
||||
// Create rotation that's looking down at the player from above
|
||||
var lookingDownAtPlayer = Quaternion.LookRotation(-RespawnOnDeath.Instance.DeathPlayerUpVector, Vector3.up);
|
||||
|
||||
// Get starting position - distance above player
|
||||
var startingPosition = RespawnOnDeath.Instance.DeathPositionWorld;
|
||||
startingPosition += RespawnOnDeath.Instance.DeathPlayerUpVector * num5 * ____observatoryRevealDist;
|
||||
|
||||
// Lerp to final rotation
|
||||
__instance.transform.rotation = Quaternion.Lerp(lookingDownAtPlayer, finalRotation, num5);
|
||||
|
||||
// Lerp reveal twist
|
||||
__instance.transform.rotation *= Quaternion.AngleAxis(Mathf.Lerp(____observatoryRevealTwist, 0f, num4), Vector3.forward);
|
||||
|
||||
var endPosition = ____position + (-__instance.transform.forward * ____zoom) + Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition();
|
||||
|
||||
// Lerp to final position
|
||||
__instance.transform.position = Vector3.Lerp(startingPosition, endPosition, num5);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
166
QSB/DeathSync/Patches/RespawnPatches.cs
Normal file
166
QSB/DeathSync/Patches/RespawnPatches.cs
Normal file
@ -0,0 +1,166 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.DeathSync.Patches
|
||||
{
|
||||
internal class RespawnPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(PlayerRecoveryPoint_OnGainFocus));
|
||||
Prefix(nameof(PlayerRecoveryPoint_OnPressInteract));
|
||||
}
|
||||
|
||||
public static bool PlayerRecoveryPoint_OnGainFocus(
|
||||
PlayerResources ____playerResources,
|
||||
bool ____refuelsPlayer,
|
||||
bool ____healsPlayer,
|
||||
SingleInteractionVolume ____interactVolume
|
||||
)
|
||||
{
|
||||
if (____playerResources == null)
|
||||
{
|
||||
____playerResources = Locator.GetPlayerTransform().GetComponent<PlayerResources>();
|
||||
}
|
||||
|
||||
var isAtFullHealth = ____playerResources.GetHealthFraction() == 1f;
|
||||
var isAtFullFuel = ____playerResources.GetFuelFraction() == 1f;
|
||||
var canBeRefueled = false;
|
||||
var canBeHealed = false;
|
||||
|
||||
if (!isAtFullFuel && ____refuelsPlayer)
|
||||
{
|
||||
canBeRefueled = true;
|
||||
}
|
||||
|
||||
if (!isAtFullHealth && ____healsPlayer)
|
||||
{
|
||||
canBeHealed = true;
|
||||
}
|
||||
|
||||
var showRespawnPrompt = false;
|
||||
|
||||
var uitextType = UITextType.None;
|
||||
if (canBeHealed && canBeRefueled)
|
||||
{
|
||||
// Heal and refuel
|
||||
uitextType = UITextType.RefillPrompt_0;
|
||||
|
||||
____interactVolume.SetKeyCommandVisible(true);
|
||||
}
|
||||
else if (canBeHealed)
|
||||
{
|
||||
// Heal
|
||||
uitextType = UITextType.RefillPrompt_2;
|
||||
|
||||
____interactVolume.SetKeyCommandVisible(true);
|
||||
}
|
||||
else if (canBeRefueled)
|
||||
{
|
||||
// Refuel
|
||||
uitextType = UITextType.RefillPrompt_4;
|
||||
____interactVolume.SetKeyCommandVisible(true);
|
||||
}
|
||||
else if (RespawnManager.Instance.RespawnNeeded)
|
||||
{
|
||||
showRespawnPrompt = true;
|
||||
}
|
||||
else if (____refuelsPlayer && ____healsPlayer)
|
||||
{
|
||||
// Fuel and health full
|
||||
uitextType = UITextType.RefillPrompt_7;
|
||||
____interactVolume.SetKeyCommandVisible(false);
|
||||
}
|
||||
else if (____refuelsPlayer)
|
||||
{
|
||||
// Fuel full
|
||||
uitextType = UITextType.RefillPrompt_8;
|
||||
____interactVolume.SetKeyCommandVisible(false);
|
||||
}
|
||||
else if (____healsPlayer)
|
||||
{
|
||||
// Health full
|
||||
uitextType = UITextType.RefillPrompt_9;
|
||||
____interactVolume.SetKeyCommandVisible(false);
|
||||
}
|
||||
|
||||
if (showRespawnPrompt)
|
||||
{
|
||||
____interactVolume.GetValue<ScreenPrompt>("_screenPrompt").SetText($"<CMD> Respawn Player");
|
||||
____interactVolume.GetValue<ScreenPrompt>("_noCommandIconPrompt").SetText("Respawn Player");
|
||||
}
|
||||
|
||||
if (uitextType != UITextType.None)
|
||||
{
|
||||
____interactVolume.ChangePrompt(uitextType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool PlayerRecoveryPoint_OnPressInteract(
|
||||
PlayerRecoveryPoint __instance,
|
||||
PlayerResources ____playerResources,
|
||||
ref bool ____recovering,
|
||||
bool ____refuelsPlayer,
|
||||
bool ____healsPlayer,
|
||||
PlayerAudioController ____playerAudioController,
|
||||
SingleInteractionVolume ____interactVolume
|
||||
)
|
||||
{
|
||||
var playerNeedsRefueling = ____playerResources.GetFuelFraction() != 1f;
|
||||
var playerNeedsHealing = ____playerResources.GetHealthFraction() != 1f;
|
||||
var canBeInteractedWith = false;
|
||||
|
||||
if (playerNeedsRefueling && ____refuelsPlayer)
|
||||
{
|
||||
canBeInteractedWith = true;
|
||||
}
|
||||
|
||||
if (playerNeedsHealing && ____healsPlayer)
|
||||
{
|
||||
canBeInteractedWith = true;
|
||||
}
|
||||
|
||||
if (RespawnManager.Instance.RespawnNeeded)
|
||||
{
|
||||
canBeInteractedWith = true;
|
||||
}
|
||||
|
||||
if (canBeInteractedWith)
|
||||
{
|
||||
if (RespawnManager.Instance.RespawnNeeded && !playerNeedsRefueling && !playerNeedsHealing)
|
||||
{
|
||||
RespawnManager.Instance.RespawnSomePlayer();
|
||||
return false;
|
||||
}
|
||||
|
||||
____playerResources.StartRefillResources(____refuelsPlayer, ____healsPlayer);
|
||||
|
||||
if (____playerAudioController != null)
|
||||
{
|
||||
if (playerNeedsRefueling && ____refuelsPlayer)
|
||||
{
|
||||
____playerAudioController.PlayRefuel();
|
||||
}
|
||||
|
||||
if (playerNeedsHealing && ____healsPlayer)
|
||||
{
|
||||
____playerAudioController.PlayMedkit();
|
||||
}
|
||||
}
|
||||
|
||||
____recovering = true;
|
||||
__instance.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
____interactVolume.ResetInteraction();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
109
QSB/DeathSync/RespawnManager.cs
Normal file
109
QSB/DeathSync/RespawnManager.cs
Normal file
@ -0,0 +1,109 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.DeathSync
|
||||
{
|
||||
internal class RespawnManager : MonoBehaviour
|
||||
{
|
||||
public static RespawnManager Instance;
|
||||
|
||||
public bool RespawnNeeded => _playersPendingRespawn.Count != 0;
|
||||
|
||||
private List<PlayerInfo> _playersPendingRespawn = new List<PlayerInfo>();
|
||||
private NotificationData _previousNotification;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Instance = this;
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
|
||||
{
|
||||
QSBPlayerManager.PlayerList.ForEach(x => x.IsDead = false);
|
||||
_playersPendingRespawn.Clear();
|
||||
}
|
||||
|
||||
public void TriggerRespawnMap()
|
||||
{
|
||||
DebugLog.DebugWrite($"TRIGGER RESPAWN MAP");
|
||||
QSBPatchManager.DoPatchType(QSBPatchTypes.RespawnTime);
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() => 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.GetType().GetAnyMethod("ExitMapView").Invoke(mapController, null);
|
||||
|
||||
var cameraEffectController = Locator.GetPlayerCamera().GetComponent<PlayerCameraEffectController>();
|
||||
cameraEffectController.OpenEyes(1f, false);
|
||||
}
|
||||
|
||||
public void OnPlayerDeath(PlayerInfo player)
|
||||
{
|
||||
DebugLog.DebugWrite($"ON PLAYER DEATH");
|
||||
|
||||
if (_playersPendingRespawn.Contains(player))
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Received death message for player who is already in _playersPendingRespawn!", OWML.Common.MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"set player to be dead");
|
||||
player.IsDead = true;
|
||||
|
||||
_playersPendingRespawn.Add(player);
|
||||
UpdateRespawnNotification();
|
||||
|
||||
QSBPlayerManager.ChangePlayerVisibility(player.PlayerId, false);
|
||||
}
|
||||
|
||||
public void OnPlayerRespawn(PlayerInfo player)
|
||||
{
|
||||
if (!_playersPendingRespawn.Contains(player))
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Received respawn message for player who is not in _playersPendingRespawn!", OWML.Common.MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
player.IsDead = false;
|
||||
|
||||
_playersPendingRespawn.Remove(player);
|
||||
UpdateRespawnNotification();
|
||||
|
||||
QSBPlayerManager.ChangePlayerVisibility(player.PlayerId, true);
|
||||
}
|
||||
|
||||
public void RespawnSomePlayer()
|
||||
{
|
||||
var playerToRespawn = _playersPendingRespawn.First();
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerRespawn, playerToRespawn.PlayerId);
|
||||
}
|
||||
|
||||
private void UpdateRespawnNotification()
|
||||
{
|
||||
NotificationManager.SharedInstance.UnpinNotification(_previousNotification);
|
||||
|
||||
if (_playersPendingRespawn.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var data = new NotificationData(NotificationTarget.Player, $"[{_playersPendingRespawn.Count}] PLAYER(S) AWAITING RESPAWN");
|
||||
NotificationManager.SharedInstance.PostNotification(data, true);
|
||||
_previousNotification = data;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.ShipSync.TransformSync;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -17,21 +19,21 @@ namespace QSB.DeathSync
|
||||
DeathType.TimeLoop
|
||||
};
|
||||
|
||||
private readonly Vector3 ShipContainerOffset = new Vector3(-16.45f, -52.67f, 227.39f);
|
||||
private readonly Quaternion ShipContainerRotation = Quaternion.Euler(-76.937f, 1.062f, -185.066f);
|
||||
|
||||
private SpawnPoint _shipSpawnPoint;
|
||||
private SpawnPoint _playerSpawnPoint;
|
||||
private OWRigidbody _shipBody;
|
||||
private PlayerSpawner _playerSpawner;
|
||||
private FluidDetector _fluidDetector;
|
||||
private PlayerResources _playerResources;
|
||||
private ShipComponent[] _shipComponents;
|
||||
private HatchController _hatchController;
|
||||
private ShipCockpitController _cockpitController;
|
||||
private PlayerSpacesuit _spaceSuit;
|
||||
private ShipTractorBeamSwitch _shipTractorBeam;
|
||||
private SuitPickupVolume[] _suitPickupVolumes;
|
||||
private Vector3 _deathPositionRelative;
|
||||
|
||||
public Transform DeathClosestAstroObject { get; private set; }
|
||||
public Vector3 DeathPositionWorld
|
||||
=> DeathClosestAstroObject == null
|
||||
? Vector3.zero
|
||||
: DeathClosestAstroObject.TransformPoint(_deathPositionRelative);
|
||||
public Vector3 DeathPlayerUpVector { get; private set; }
|
||||
public Vector3 DeathPlayerForwardVector { get; private set; }
|
||||
|
||||
public void Awake() => Instance = this;
|
||||
|
||||
@ -41,49 +43,48 @@ namespace QSB.DeathSync
|
||||
_playerResources = playerTransform.GetComponent<PlayerResources>();
|
||||
_spaceSuit = Locator.GetPlayerSuit();
|
||||
_playerSpawner = FindObjectOfType<PlayerSpawner>();
|
||||
_shipTractorBeam = FindObjectOfType<ShipTractorBeamSwitch>();
|
||||
_suitPickupVolumes = FindObjectsOfType<SuitPickupVolume>();
|
||||
|
||||
_fluidDetector = Locator.GetPlayerCamera().GetComponentInChildren<FluidDetector>();
|
||||
|
||||
_playerSpawnPoint = GetSpawnPoint();
|
||||
_shipSpawnPoint = GetSpawnPoint(true);
|
||||
|
||||
var shipTransform = Locator.GetShipTransform();
|
||||
if (shipTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Init() ran when ship was null?", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
_shipComponents = shipTransform.GetComponentsInChildren<ShipComponent>();
|
||||
_hatchController = shipTransform.GetComponentInChildren<HatchController>();
|
||||
_cockpitController = shipTransform.GetComponentInChildren<ShipCockpitController>();
|
||||
_shipBody = Locator.GetShipBody();
|
||||
|
||||
if (_shipSpawnPoint == null)
|
||||
{
|
||||
DebugLog.ToConsole("Warning - _shipSpawnPoint is null in Init()!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Move debug spawn point to initial ship position (so ship doesnt spawn in space!)
|
||||
var timberHearth = Locator.GetAstroObject(AstroObject.Name.TimberHearth).transform;
|
||||
_shipSpawnPoint.transform.SetParent(timberHearth);
|
||||
_shipSpawnPoint.transform.localPosition = ShipContainerOffset;
|
||||
_shipSpawnPoint.transform.localRotation = ShipContainerRotation;
|
||||
}
|
||||
|
||||
public void ResetPlayer()
|
||||
{
|
||||
DebugLog.DebugWrite($"Trying to reset player.");
|
||||
DebugLog.DebugWrite($"RESET PLAYER");
|
||||
if (_playerSpawnPoint == null)
|
||||
{
|
||||
DebugLog.ToConsole("Warning - _playerSpawnPoint is null!", MessageType.Warning);
|
||||
Init();
|
||||
}
|
||||
|
||||
// Cant use _playerSpawner.DebugWarp because that will warp the ship if the player is in it
|
||||
var deadPlayersCount = QSBPlayerManager.PlayerList.Count(x => x.IsDead);
|
||||
|
||||
if (deadPlayersCount == QSBPlayerManager.PlayerList.Count)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBEndLoop, EndLoopReason.AllPlayersDead);
|
||||
return;
|
||||
}
|
||||
|
||||
RespawnManager.Instance.TriggerRespawnMap();
|
||||
|
||||
var inSpace = PlayerTransformSync.LocalInstance.SectorSync.SectorList.Count == 0;
|
||||
|
||||
if (inSpace)
|
||||
{
|
||||
DeathClosestAstroObject = Locator.GetAstroObject(AstroObject.Name.Sun).transform;
|
||||
}
|
||||
else
|
||||
{
|
||||
var allAstroobjects = Resources.FindObjectsOfTypeAll<AstroObject>().Where(x => x.GetAstroObjectName() != AstroObject.Name.None && x.GetAstroObjectType() != AstroObject.Type.Satellite);
|
||||
var ordered = allAstroobjects.OrderBy(x => Vector3.SqrMagnitude(x.transform.position));
|
||||
DeathClosestAstroObject = ordered.First().transform;
|
||||
}
|
||||
|
||||
var deathPosition = Locator.GetPlayerTransform().position;
|
||||
_deathPositionRelative = DeathClosestAstroObject.InverseTransformPoint(deathPosition);
|
||||
DeathPlayerUpVector = Locator.GetPlayerTransform().up;
|
||||
DeathPlayerForwardVector = Locator.GetPlayerTransform().forward;
|
||||
|
||||
var playerBody = Locator.GetPlayerBody();
|
||||
playerBody.WarpToPositionRotation(_playerSpawnPoint.transform.position, _playerSpawnPoint.transform.rotation);
|
||||
playerBody.SetVelocity(_playerSpawnPoint.GetPointVelocity());
|
||||
@ -123,49 +124,7 @@ namespace QSB.DeathSync
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetShip()
|
||||
{
|
||||
DebugLog.DebugWrite($"Trying to reset ship.");
|
||||
if (!ShipTransformSync.LocalInstance.HasAuthority)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to reset ship when not in control!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_shipSpawnPoint == null)
|
||||
{
|
||||
DebugLog.ToConsole("Warning - _shipSpawnPoint is null!", MessageType.Warning);
|
||||
Init();
|
||||
}
|
||||
|
||||
if (_shipBody == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to reset ship, but the ship is null!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
_shipBody.SetVelocity(_shipSpawnPoint.GetPointVelocity());
|
||||
_shipBody.WarpToPositionRotation(_shipSpawnPoint.transform.position, _shipSpawnPoint.transform.rotation);
|
||||
|
||||
foreach (var shipComponent in _shipComponents)
|
||||
{
|
||||
shipComponent.SetDamaged(false);
|
||||
}
|
||||
|
||||
Invoke(nameof(ExitShip), 0.01f);
|
||||
}
|
||||
|
||||
private void ExitShip()
|
||||
{
|
||||
DebugLog.DebugWrite($"Exit ship.");
|
||||
_cockpitController.Invoke("ExitFlightConsole");
|
||||
_cockpitController.Invoke("CompleteExitFlightConsole");
|
||||
_hatchController.SetValue("_isPlayerInShip", false);
|
||||
_hatchController.Invoke("OpenHatch");
|
||||
_shipTractorBeam.ActivateTractorBeam();
|
||||
}
|
||||
|
||||
private SpawnPoint GetSpawnPoint(bool isShip = false)
|
||||
private SpawnPoint GetSpawnPoint()
|
||||
{
|
||||
var spawnList = _playerSpawner.GetValue<SpawnPoint[]>("_spawnList");
|
||||
if (spawnList == null)
|
||||
@ -176,7 +135,7 @@ namespace QSB.DeathSync
|
||||
|
||||
return spawnList.FirstOrDefault(spawnPoint =>
|
||||
spawnPoint.GetSpawnLocation() == SpawnLocation.TimberHearth
|
||||
&& spawnPoint.IsShipSpawn() == isShip);
|
||||
&& spawnPoint.IsShipSpawn() == false);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,8 +5,6 @@
|
||||
// Built into Outer Wilds -- don't change unless they change in-game!
|
||||
public static string TurnOnFlashlight = "TurnOnFlashlight";
|
||||
public static string TurnOffFlashlight = "TurnOffFlashlight";
|
||||
public static string LaunchProbe = "LaunchProbe";
|
||||
public static string RetrieveProbe = "RetrieveProbe";
|
||||
public static string ProbeLauncherEquipped = "ProbeLauncherEquipped";
|
||||
public static string ProbeLauncherUnequipped = "ProbeLauncherUnequipped";
|
||||
public static string EquipSignalscope = "EquipSignalscope";
|
||||
@ -32,7 +30,7 @@
|
||||
public static string QSBPlayerDeath = "QSBPlayerDeath";
|
||||
public static string QSBPlayerJoin = "QSBPlayerJoin";
|
||||
public static string QSBPlayerReady = "QSBPlayerReady";
|
||||
public static string QSBPlayerStatesRequest = "QSBPlayerStatesRequest";
|
||||
public static string QSBRequestStateResync = "QSBPlayerStatesRequest";
|
||||
public static string QSBServerTime = "QSBServerTime";
|
||||
public static string QSBStartLift = "QSBStartLift";
|
||||
public static string QSBGeyserState = "QSBGeyserState";
|
||||
@ -41,7 +39,7 @@
|
||||
public static string QSBConversation = "QSBConversation";
|
||||
public static string QSBConversationStartEnd = "QSBConversationStartEnd";
|
||||
public static string QSBChangeAnimType = "QSBPlayInstrument";
|
||||
public static string QSBServerSendPlayerStates = "QSBServerSendPlayerStates";
|
||||
public static string QSBPlayerInformation = "QSBServerSendPlayerStates";
|
||||
public static string QSBRevealFact = "QSBRevealFact";
|
||||
public static string QSBSocketStateChange = "QSBSocketStateChange";
|
||||
public static string QSBMultiStateChange = "QSBMultiStateChange";
|
||||
@ -77,5 +75,16 @@
|
||||
public static string QSBComponentDamaged = "QSBComponentDamaged";
|
||||
public static string QSBComponentRepaired = "QSBComponentRepaired";
|
||||
public static string QSBComponentRepairTick = "QSBComponentRepairTick";
|
||||
public static string QSBPlayerRespawn = "QSBPlayerRespawn";
|
||||
public static string QSBProbeEvent = "QSBProbeEvent";
|
||||
public static string QSBProbeStartRetrieve = "QSBProbeStartRetrieve";
|
||||
public static string QSBRetrieveProbe = "QSBRetrieveProbe";
|
||||
public static string QSBPlayerRetrieveProbe = "QSBPlayerRetrieveProbe";
|
||||
public static string QSBLaunchProbe = "QSBLaunchProbe";
|
||||
public static string QSBPlayerLaunchProbe = "QSBPlayerLaunchProbe";
|
||||
public static string QSBEndLoop = "QSBEndLoop";
|
||||
public static string QSBStartLoop = "QSBStartLoop";
|
||||
public static string QSBServerState = "QSBServerState";
|
||||
public static string QSBClientState = "QSBClientState";
|
||||
}
|
||||
}
|
@ -2,57 +2,130 @@
|
||||
{
|
||||
public enum EventType
|
||||
{
|
||||
/*
|
||||
* SERVER EVENTS
|
||||
*/
|
||||
|
||||
ServerTime,
|
||||
PlayerState,
|
||||
PlayerStatesRequest,
|
||||
FlashlightActiveChange,
|
||||
SignalscopeActiveChange,
|
||||
TranslatorActiveChange,
|
||||
ProbeLauncherActiveChange,
|
||||
SuitActiveChange,
|
||||
StartStatue,
|
||||
EndLoop,
|
||||
StartLoop,
|
||||
ServerState,
|
||||
ClientState,
|
||||
|
||||
/*
|
||||
* PLAYER EVENTS
|
||||
*/
|
||||
|
||||
PlayerInformation,
|
||||
RequestStateResync,
|
||||
PlayerJoin,
|
||||
PlayerDeath,
|
||||
PlayerReady,
|
||||
ProbeActiveChange,
|
||||
Elevator,
|
||||
Geyser,
|
||||
OrbSlot,
|
||||
OrbUser,
|
||||
PlayerKick,
|
||||
PlayerRespawn,
|
||||
EnterLeave,
|
||||
|
||||
/*
|
||||
* DIALOGUE
|
||||
*/
|
||||
|
||||
Conversation,
|
||||
ConversationStartEnd,
|
||||
PlayInstrument,
|
||||
DialogueCondition,
|
||||
RevealFact,
|
||||
|
||||
/*
|
||||
* ANIMATION
|
||||
*/
|
||||
|
||||
PlayInstrument,
|
||||
AnimTrigger,
|
||||
NpcAnimEvent,
|
||||
SuitActiveChange,
|
||||
|
||||
/*
|
||||
* ORBS
|
||||
*/
|
||||
|
||||
OrbSlot,
|
||||
OrbUser,
|
||||
|
||||
/*
|
||||
* CAMPFIRES
|
||||
*/
|
||||
|
||||
CampfireState,
|
||||
Roasting,
|
||||
MarshmallowEvent,
|
||||
|
||||
/*
|
||||
* WORLD OBJECTS
|
||||
*/
|
||||
|
||||
Geyser,
|
||||
Elevator,
|
||||
|
||||
/*
|
||||
* ITEMS
|
||||
*/
|
||||
|
||||
DropItem,
|
||||
SocketItem,
|
||||
MoveToCarry,
|
||||
|
||||
/*
|
||||
* QUANTUM OBJECTS
|
||||
*/
|
||||
|
||||
SocketStateChange,
|
||||
MultiStateChange,
|
||||
QuantumShuffle,
|
||||
QuantumAuthority,
|
||||
MoonStateChange,
|
||||
IdentifyFrequency,
|
||||
IdentifySignal,
|
||||
TextTranslated,
|
||||
EnterLeave,
|
||||
PlayerEntangle,
|
||||
DropItem,
|
||||
SocketItem,
|
||||
MoveToCarry,
|
||||
StartStatue,
|
||||
PlayerKick,
|
||||
CampfireState,
|
||||
Roasting,
|
||||
MarshmallowEvent,
|
||||
AnimTrigger,
|
||||
NpcAnimEvent,
|
||||
FlyShip,
|
||||
OpenHatch,
|
||||
EnableFunnel,
|
||||
|
||||
/*
|
||||
* SHIP
|
||||
*/
|
||||
|
||||
ComponentDamaged,
|
||||
ComponentRepaired,
|
||||
ComponentRepairTick,
|
||||
HullImpact,
|
||||
HullDamaged,
|
||||
HullChangeIntegrity,
|
||||
HullRepaired,
|
||||
HullRepairTick,
|
||||
ComponentDamaged,
|
||||
ComponentRepaired,
|
||||
ComponentRepairTick
|
||||
FlyShip,
|
||||
OpenHatch,
|
||||
EnableFunnel,
|
||||
|
||||
/*
|
||||
* TOOLS
|
||||
*/
|
||||
|
||||
// Flashlight
|
||||
FlashlightActiveChange,
|
||||
|
||||
// Translator
|
||||
TranslatorActiveChange,
|
||||
TextTranslated,
|
||||
|
||||
// Signalscope
|
||||
SignalscopeActiveChange,
|
||||
IdentifyFrequency,
|
||||
IdentifySignal,
|
||||
|
||||
// Probe
|
||||
ProbeStartRetrieve,
|
||||
ProbeEvent,
|
||||
|
||||
// Probe Launcher
|
||||
ProbeLauncherActiveChange,
|
||||
RetrieveProbe,
|
||||
PlayerRetrieveProbe,
|
||||
LaunchProbe,
|
||||
PlayerLaunchProbe
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Components;
|
||||
|
||||
namespace QSB.Events
|
||||
@ -30,8 +29,8 @@ namespace QSB.Events
|
||||
public abstract void SetupListener();
|
||||
public abstract void CloseListener();
|
||||
|
||||
public virtual void OnReceiveRemote(bool server, T message) { }
|
||||
public virtual void OnReceiveLocal(bool server, T message) { }
|
||||
public virtual void OnReceiveRemote(bool isHost, T message) { }
|
||||
public virtual void OnReceiveLocal(bool isHost, T message) { }
|
||||
|
||||
public void SendEvent(T message)
|
||||
{
|
||||
@ -53,7 +52,7 @@ namespace QSB.Events
|
||||
* if <isServer> is true, this message has been received on the server *server*.
|
||||
* Therefore, we don't want to do any event handling code - that should be dealt
|
||||
* with on the server *client* and any other client. So just forward the message
|
||||
* onto all clients. This way, the server *server* just acts as the ditribution
|
||||
* onto all clients. This way, the server *server* just acts as the distribution
|
||||
* hub for all events.
|
||||
*/
|
||||
|
||||
@ -68,7 +67,7 @@ namespace QSB.Events
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.OnlySendToServer && !QNetworkServer.active)
|
||||
if (message.OnlySendToHost && !QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -82,11 +81,11 @@ namespace QSB.Events
|
||||
if (message.FromId == QSBPlayerManager.LocalPlayerId ||
|
||||
QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId))
|
||||
{
|
||||
OnReceiveLocal(QNetworkServer.active, message);
|
||||
OnReceiveLocal(QSBCore.IsHost, message);
|
||||
return;
|
||||
}
|
||||
|
||||
OnReceiveRemote(QNetworkServer.active, message);
|
||||
OnReceiveRemote(QSBCore.IsHost, message);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
using QSB.Animation.NPC.Events;
|
||||
using QSB.Animation.Player.Events;
|
||||
using QSB.CampfireSync.Events;
|
||||
using QSB.ClientServerStateSync.Events;
|
||||
using QSB.ConversationSync.Events;
|
||||
using QSB.DeathSync.Events;
|
||||
using QSB.ElevatorSync.Events;
|
||||
@ -20,6 +21,7 @@ using QSB.ShipSync.Events.Hull;
|
||||
using QSB.StatueSync.Events;
|
||||
using QSB.TimeSync.Events;
|
||||
using QSB.Tools.Events;
|
||||
using QSB.Tools.ProbeLauncherTool.Events;
|
||||
using QSB.TranslationSync.Events;
|
||||
using QSB.Utility;
|
||||
using System.Collections.Generic;
|
||||
@ -43,11 +45,11 @@ namespace QSB.Events
|
||||
new PlayerFlashlightEvent(),
|
||||
new PlayerSignalscopeEvent(),
|
||||
new PlayerTranslatorEvent(),
|
||||
new PlayerProbeLauncherEvent(),
|
||||
new EquipProbeLauncherEvent(),
|
||||
new PlayerProbeEvent(),
|
||||
new PlayerDeathEvent(),
|
||||
new PlayerStatesRequestEvent(),
|
||||
new ServerSendPlayerStatesEvent(),
|
||||
new RequestStateResyncEvent(),
|
||||
new PlayerInformationEvent(),
|
||||
new ChangeAnimTypeEvent(),
|
||||
new ServerTimeEvent(),
|
||||
new PlayerEntangledEvent(),
|
||||
@ -55,6 +57,16 @@ namespace QSB.Events
|
||||
new EnterExitRoastingEvent(),
|
||||
new MarshmallowEventEvent(),
|
||||
new AnimationTriggerEvent(),
|
||||
new PlayerRespawnEvent(),
|
||||
new ProbeStartRetrieveEvent(),
|
||||
new RetrieveProbeEvent(),
|
||||
new LaunchProbeEvent(),
|
||||
new PlayerRetrieveProbeEvent(),
|
||||
new PlayerLaunchProbeEvent(),
|
||||
new EndLoopEvent(),
|
||||
new StartLoopEvent(),
|
||||
new ServerStateEvent(),
|
||||
new ClientStateEvent(),
|
||||
// World Objects
|
||||
new ElevatorEvent(),
|
||||
new GeyserEvent(),
|
||||
|
@ -21,7 +21,7 @@ namespace QSB.GeyserSync.Events
|
||||
State = state
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, BoolWorldObjectMessage message)
|
||||
public override void OnReceiveRemote(bool isHost, BoolWorldObjectMessage message)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace QSB.Inputs.Patches
|
||||
{
|
||||
class InputPatches : QSBPatch
|
||||
internal class InputPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
|
@ -5,22 +5,34 @@ namespace QSB.Messaging
|
||||
{
|
||||
public class PlayerMessage : QMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The Player ID that is sending this message
|
||||
/// </summary>
|
||||
public uint FromId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Player ID that this message is about
|
||||
/// </summary>
|
||||
public uint AboutId { get; set; }
|
||||
public bool OnlySendToServer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, only send this message to the host of the current session
|
||||
/// (OnReceiveLocal/Remote is not called on any other client)
|
||||
/// </summary>
|
||||
public bool OnlySendToHost { get; set; }
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
FromId = reader.ReadUInt32();
|
||||
AboutId = reader.ReadUInt32();
|
||||
OnlySendToServer = reader.ReadBoolean();
|
||||
OnlySendToHost = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
writer.Write(FromId);
|
||||
writer.Write(AboutId);
|
||||
writer.Write(OnlySendToServer);
|
||||
writer.Write(OnlySendToHost);
|
||||
}
|
||||
}
|
||||
}
|
@ -70,7 +70,7 @@ namespace QSB.OrbSync.Events
|
||||
}
|
||||
|
||||
var orbSync = NomaiOrbTransformSync.OrbTransformSyncs
|
||||
.FirstOrDefault(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].gameObject);
|
||||
.FirstOrDefault(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].transform);
|
||||
if (orbSync == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No orb found for user event. (ID {message.ObjectId})", MessageType.Error);
|
||||
@ -107,14 +107,14 @@ namespace QSB.OrbSync.Events
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NomaiOrbTransformSync.OrbTransformSyncs.Any(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].gameObject))
|
||||
if (!NomaiOrbTransformSync.OrbTransformSyncs.Any(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].transform))
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No NomaiOrbTransformSync has AttachedOrb with objectId {message.ObjectId}!");
|
||||
return;
|
||||
}
|
||||
|
||||
var orb = NomaiOrbTransformSync.OrbTransformSyncs
|
||||
.First(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].gameObject);
|
||||
.First(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].transform);
|
||||
orb.enabled = true;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace QSB.OrbSync
|
||||
{
|
||||
QSBWorldSync.OldOrbList.Clear();
|
||||
QSBWorldSync.OldOrbList = Resources.FindObjectsOfTypeAll<NomaiInterfaceOrb>().ToList();
|
||||
if (QSBCore.IsServer)
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
NomaiOrbTransformSync.OrbTransformSyncs.ForEach(x => QNetworkServer.Destroy(x.gameObject));
|
||||
NomaiOrbTransformSync.OrbTransformSyncs.Clear();
|
||||
|
@ -1,5 +1,6 @@
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
@ -34,7 +35,7 @@ namespace QSB.OrbSync.Patches
|
||||
if (Time.timeSinceLevelLoad > 1f)
|
||||
{
|
||||
QSBWorldSync.HandleSlotStateChange(__instance, orb, true);
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnSlotActivated", __instance);
|
||||
__instance.RaiseEvent("OnSlotActivated", __instance);
|
||||
}
|
||||
|
||||
__result = true;
|
||||
@ -51,7 +52,7 @@ namespace QSB.OrbSync.Patches
|
||||
{
|
||||
QSBWorldSync.HandleSlotStateChange(__instance, orb, false);
|
||||
____occupyingOrb = null;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnSlotDeactivated", __instance);
|
||||
__instance.RaiseEvent("OnSlotDeactivated", __instance);
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
|
@ -23,10 +23,17 @@ namespace QSB.OrbSync.TransformSync
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
SetReferenceTransform(AttachedObject.GetAttachedOWRigidbody().GetOrigParent());
|
||||
var originalParent = AttachedObject.GetAttachedOWRigidbody().GetOrigParent();
|
||||
if (originalParent == Locator.GetRootTransform())
|
||||
{
|
||||
DebugLog.DebugWrite($"{_logName} with AttachedObject {AttachedObject.name} had it's original parent as SolarSystemRoot - Destroying...");
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
SetReferenceTransform(originalParent);
|
||||
}
|
||||
|
||||
private GameObject GetTransform()
|
||||
private Transform GetTransform()
|
||||
{
|
||||
if (_index == -1)
|
||||
{
|
||||
@ -46,11 +53,11 @@ namespace QSB.OrbSync.TransformSync
|
||||
return null;
|
||||
}
|
||||
|
||||
return QSBWorldSync.OldOrbList[_index].gameObject;
|
||||
return QSBWorldSync.OldOrbList[_index].transform;
|
||||
}
|
||||
|
||||
protected override GameObject InitLocalTransform() => GetTransform();
|
||||
protected override GameObject InitRemoteTransform() => GetTransform();
|
||||
protected override Component InitLocalTransform() => GetTransform();
|
||||
protected override Component InitRemoteTransform() => GetTransform();
|
||||
|
||||
public override bool IsReady => QSBCore.WorldObjectsReady;
|
||||
public override bool UseInterpolation => false;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Events;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.OrbSync.WorldObjects
|
||||
@ -37,7 +38,7 @@ namespace QSB.OrbSync.WorldObjects
|
||||
var occOrb = state ? QSBWorldSync.OldOrbList[orbId] : null;
|
||||
AttachedObject.SetValue("_occupyingOrb", occOrb);
|
||||
var ev = state ? "OnSlotActivated" : "OnSlotDeactivated";
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, ev, AttachedObject);
|
||||
AttachedObject.RaiseEvent(ev, AttachedObject);
|
||||
Activated = state;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace QSB.Patches
|
||||
{
|
||||
foreach (var item in _patchedMethods)
|
||||
{
|
||||
DebugLog.DebugWrite($"[Unpatch] {item.DeclaringType}.{item.Name}", MessageType.Info);
|
||||
//DebugLog.DebugWrite($"[Unpatch] {item.DeclaringType}.{item.Name}", MessageType.Info);
|
||||
Unpatch(item);
|
||||
}
|
||||
|
||||
@ -29,9 +29,10 @@ namespace QSB.Patches
|
||||
|
||||
public void Empty(string patchName)
|
||||
{
|
||||
DebugLog.DebugWrite($"[Empty] {patchName}", MessageType.Success);
|
||||
//DebugLog.DebugWrite($"[Empty] {patchName}", MessageType.Success);
|
||||
var method = GetMethodInfo(patchName);
|
||||
QSBCore.Helper.HarmonyHelper.EmptyMethod(method);
|
||||
_patchedMethods.Add(method);
|
||||
}
|
||||
|
||||
public void Prefix(string patchName)
|
||||
@ -58,7 +59,7 @@ namespace QSB.Patches
|
||||
_patchedMethods.Add(method);
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"{(isPrefix ? "[Prefix]" : "[Postfix]")} {patchName}", method == null ? MessageType.Error : MessageType.Success);
|
||||
//DebugLog.DebugWrite($"{(isPrefix ? "[Prefix]" : "[Postfix]")} {patchName}", method == null ? MessageType.Error : MessageType.Success);
|
||||
}
|
||||
|
||||
private MethodInfo GetMethodInfo(string patchName)
|
||||
@ -103,7 +104,7 @@ namespace QSB.Patches
|
||||
{
|
||||
var dictionary = typeof(HarmonySharedState).Invoke<Dictionary<MethodBase, byte[]>>("GetState", new object[0]);
|
||||
var methodBase = dictionary.Keys.First(m =>
|
||||
m.DeclaringType == method.DeclaringType
|
||||
m.DeclaringType == method.DeclaringType
|
||||
&& m.Name == method.Name);
|
||||
|
||||
var patchInfo = PatchInfoSerialization.Deserialize(dictionary.GetValueSafe(methodBase));
|
||||
|
@ -18,6 +18,7 @@ using QSB.RoastingSync.Patches;
|
||||
using QSB.ShipSync.Patches;
|
||||
using QSB.StatueSync.Patches;
|
||||
using QSB.TimeSync.Patches;
|
||||
using QSB.Tools.ProbeLauncherTool.Patches;
|
||||
using QSB.TranslationSync.Patches;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
@ -59,7 +60,10 @@ namespace QSB.Patches
|
||||
new CharacterAnimationPatches(),
|
||||
new ShipPatches(),
|
||||
new InputPatches(),
|
||||
new TimePatches()
|
||||
new TimePatches(),
|
||||
new MapPatches(),
|
||||
new RespawnPatches(),
|
||||
new LauncherPatches()
|
||||
};
|
||||
|
||||
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);
|
||||
@ -68,10 +72,10 @@ namespace QSB.Patches
|
||||
public static void DoPatchType(QSBPatchTypes type)
|
||||
{
|
||||
OnPatchType?.SafeInvoke(type);
|
||||
DebugLog.DebugWrite($"Patch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
|
||||
//DebugLog.DebugWrite($"Patch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
|
||||
foreach (var patch in _patchList.Where(x => x.Type == type))
|
||||
{
|
||||
DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info);
|
||||
//DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info);
|
||||
patch.DoPatches();
|
||||
}
|
||||
}
|
||||
@ -79,10 +83,10 @@ namespace QSB.Patches
|
||||
public static void DoUnpatchType(QSBPatchTypes type)
|
||||
{
|
||||
OnUnpatchType?.SafeInvoke(type);
|
||||
DebugLog.DebugWrite($"Unpatch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
|
||||
//DebugLog.DebugWrite($"Unpatch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
|
||||
foreach (var patch in _patchList.Where(x => x.Type == type))
|
||||
{
|
||||
DebugLog.DebugWrite($" - Unpatching in {patch.GetType().Name}", MessageType.Info);
|
||||
//DebugLog.DebugWrite($" - Unpatching in {patch.GetType().Name}", MessageType.Info);
|
||||
patch.DoUnpatches();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
{
|
||||
OnClientConnect = 0,
|
||||
OnNonServerClientConnect = 1,
|
||||
OnServerClientConnect = 2
|
||||
OnServerClientConnect = 2,
|
||||
RespawnTime = 3
|
||||
}
|
||||
}
|
37
QSB/Player/Events/PlayerInformationEvent.cs
Normal file
37
QSB/Player/Events/PlayerInformationEvent.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.Player.Events
|
||||
{
|
||||
public class PlayerInformationEvent : QSBEvent<PlayerInformationMessage>
|
||||
{
|
||||
public override EventType Type => EventType.PlayerInformation;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBPlayerInformation, Handler);
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBPlayerInformation, Handler);
|
||||
|
||||
private void Handler() => SendEvent(CreateMessage(QSBPlayerManager.LocalPlayer));
|
||||
|
||||
private PlayerInformationMessage CreateMessage(PlayerInfo player) => new PlayerInformationMessage
|
||||
{
|
||||
AboutId = player.PlayerId,
|
||||
PlayerName = player.Name,
|
||||
PlayerState = player.PlayerStates,
|
||||
ClientState = player.State
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerInformationMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Received playerstate of player ID {message.AboutId}", MessageType.Info);
|
||||
if (QSBPlayerManager.PlayerExists(message.AboutId))
|
||||
{
|
||||
QSBPlayerManager.HandleFullStateMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - got player information message about player that doesnt exist!", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Messaging;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.Player.Events
|
||||
{
|
||||
public class PlayerStateMessage : PlayerMessage
|
||||
public class PlayerInformationMessage : PlayerMessage
|
||||
{
|
||||
public string PlayerName { get; set; }
|
||||
public PlayerState PlayerState { get; set; }
|
||||
public ClientState ClientState { get; set; }
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
@ -22,6 +24,7 @@ namespace QSB.Player.Events
|
||||
TranslatorEquipped = reader.ReadBoolean(),
|
||||
ProbeActive = reader.ReadBoolean()
|
||||
};
|
||||
ClientState = (ClientState)reader.ReadInt32();
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
@ -35,6 +38,7 @@ namespace QSB.Player.Events
|
||||
writer.Write(PlayerState.SignalscopeEquipped);
|
||||
writer.Write(PlayerState.TranslatorEquipped);
|
||||
writer.Write(PlayerState.ProbeActive);
|
||||
writer.Write((int)ClientState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -41,6 +41,12 @@ namespace QSB.Player.Events
|
||||
player.Name = message.PlayerName;
|
||||
var text = $"Connected to server as {player.Name}.";
|
||||
DebugLog.ToAll(text, MessageType.Info);
|
||||
|
||||
if (QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
QSBPlayerManager.LocalPlayer.PlayerStates.IsReady = true;
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerReady, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,14 +34,14 @@ namespace QSB.Player.Events
|
||||
|
||||
private static void HandleServer(ToggleMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Get ready event from {message.FromId}", MessageType.Success);
|
||||
DebugLog.DebugWrite($"[SERVER] Get ready event from {message.FromId}", MessageType.Success);
|
||||
QSBPlayerManager.GetPlayer(message.AboutId).PlayerStates.IsReady = message.ToggleValue;
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerSendPlayerStates);
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
|
||||
}
|
||||
|
||||
private void HandleClient(ToggleMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Get ready event from {message.FromId}", MessageType.Success);
|
||||
DebugLog.DebugWrite($"[CLIENT] Get ready event from {message.FromId}", MessageType.Success);
|
||||
if (!QSBPlayerManager.PlayerExists(message.FromId))
|
||||
{
|
||||
DebugLog.ToConsole(
|
||||
|
@ -1,87 +0,0 @@
|
||||
using OWML.Utils;
|
||||
using QSB.CampfireSync.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.QuantumSync;
|
||||
using QSB.TranslationSync;
|
||||
using QSB.TranslationSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.Player.Events
|
||||
{
|
||||
public class PlayerStatesRequestEvent : QSBEvent<PlayerMessage>
|
||||
{
|
||||
public override EventType Type => EventType.PlayerStatesRequest;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBPlayerStatesRequest, Handler);
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBPlayerStatesRequest, Handler);
|
||||
|
||||
private void Handler() => SendEvent(CreateMessage());
|
||||
|
||||
private PlayerMessage CreateMessage() => new PlayerMessage
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
OnlySendToServer = true
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Get state request from {message.FromId} - isServer?{server}");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerSendPlayerStates);
|
||||
|
||||
if (!server)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO : CLEAN. THIS. SHIT.
|
||||
|
||||
foreach (var condition in QSBWorldSync.DialogueConditions)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.DialogueCondition, condition.Key, condition.Value);
|
||||
}
|
||||
|
||||
foreach (var fact in QSBWorldSync.ShipLogFacts)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBRevealFact, fact.Id, fact.SaveGame, false);
|
||||
}
|
||||
|
||||
foreach (var wallText in QSBWorldSync.GetWorldObjects<QSBWallText>().Where(x => x.AttachedObject.GetValue<bool>("_initialized") && x.AttachedObject.GetNumTextBlocks() > 0))
|
||||
{
|
||||
foreach (var id in wallText.GetTranslatedIds())
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBTextTranslated, NomaiTextType.WallText, wallText.ObjectId, id);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var computer in QSBWorldSync.GetWorldObjects<QSBComputer>().Where(x => x.AttachedObject.GetValue<bool>("_initialized") && x.AttachedObject.GetNumTextBlocks() > 0))
|
||||
{
|
||||
foreach (var id in computer.GetTranslatedIds())
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBTextTranslated, NomaiTextType.Computer, computer.ObjectId, id);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var vesselComputer in QSBWorldSync.GetWorldObjects<QSBVesselComputer>().Where(x => x.AttachedObject.GetValue<bool>("_initialized") && x.AttachedObject.GetNumTextBlocks() > 0))
|
||||
{
|
||||
foreach (var id in vesselComputer.GetTranslatedIds())
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBTextTranslated, NomaiTextType.VesselComputer, vesselComputer.ObjectId, id);
|
||||
}
|
||||
}
|
||||
|
||||
var list = QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().ToList();
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, i, list[i].ControllingPlayer);
|
||||
}
|
||||
|
||||
foreach (var campfire in QSBWorldSync.GetWorldObjects<QSBCampfire>())
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBCampfireState, campfire.ObjectId, campfire.GetState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
97
QSB/Player/Events/RequestStateResyncEvent.cs
Normal file
97
QSB/Player/Events/RequestStateResyncEvent.cs
Normal file
@ -0,0 +1,97 @@
|
||||
using OWML.Utils;
|
||||
using QSB.CampfireSync.WorldObjects;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.QuantumSync;
|
||||
using QSB.TranslationSync;
|
||||
using QSB.TranslationSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.Player.Events
|
||||
{
|
||||
// Can be sent by any client (including host) to signal they want latest worldobject, player, and server infomation
|
||||
public class RequestStateResyncEvent : QSBEvent<PlayerMessage>
|
||||
{
|
||||
public override EventType Type => EventType.RequestStateResync;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBRequestStateResync, Handler);
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBRequestStateResync, Handler);
|
||||
|
||||
private void Handler()
|
||||
{
|
||||
DebugLog.DebugWrite($"Sending QSBRequestStateResync");
|
||||
SendEvent(CreateMessage());
|
||||
}
|
||||
|
||||
private PlayerMessage CreateMessage() => new PlayerMessage
|
||||
{
|
||||
AboutId = LocalPlayerId
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, PlayerMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"OnReceiveRemote RequestStateResyncEvent");
|
||||
|
||||
// if host, send worldobject and server states
|
||||
|
||||
if (isHost)
|
||||
{
|
||||
DebugLog.DebugWrite($"SENDING SERVER STATE");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState());
|
||||
|
||||
DebugLog.DebugWrite($"SENDING PLAYER INFORMATION");
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
|
||||
|
||||
SendWorldObjectInfo();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if client, send player and client states
|
||||
|
||||
DebugLog.DebugWrite($"SENDING PLAYER INFORMATION");
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
|
||||
}
|
||||
|
||||
private void SendWorldObjectInfo()
|
||||
{
|
||||
DebugLog.DebugWrite($"SENDING WORLDOBJECT INFORMATION");
|
||||
|
||||
QSBWorldSync.DialogueConditions.ForEach(condition
|
||||
=> QSBEventManager.FireEvent(EventNames.DialogueCondition, condition.Key, condition.Value));
|
||||
|
||||
QSBWorldSync.ShipLogFacts.ForEach(fact
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBRevealFact, fact.Id, fact.SaveGame, false));
|
||||
|
||||
foreach (var wallText in QSBWorldSync.GetWorldObjects<QSBWallText>().Where(x => x.AttachedObject.GetValue<bool>("_initialized") && x.AttachedObject.GetNumTextBlocks() > 0))
|
||||
{
|
||||
wallText.GetTranslatedIds().ForEach(id
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBTextTranslated, NomaiTextType.WallText, wallText.ObjectId, id));
|
||||
}
|
||||
|
||||
foreach (var computer in QSBWorldSync.GetWorldObjects<QSBComputer>().Where(x => x.AttachedObject.GetValue<bool>("_initialized") && x.AttachedObject.GetNumTextBlocks() > 0))
|
||||
{
|
||||
computer.GetTranslatedIds().ForEach(id
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBTextTranslated, NomaiTextType.Computer, computer.ObjectId, id));
|
||||
}
|
||||
|
||||
foreach (var vesselComputer in QSBWorldSync.GetWorldObjects<QSBVesselComputer>().Where(x => x.AttachedObject.GetValue<bool>("_initialized") && x.AttachedObject.GetNumTextBlocks() > 0))
|
||||
{
|
||||
vesselComputer.GetTranslatedIds().ForEach(id
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBTextTranslated, NomaiTextType.VesselComputer, vesselComputer.ObjectId, id));
|
||||
}
|
||||
|
||||
var list = QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().ToList();
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, i, list[i].ControllingPlayer);
|
||||
}
|
||||
|
||||
QSBWorldSync.GetWorldObjects<QSBCampfire>().ForEach(campfire
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBCampfireState, campfire.ObjectId, campfire.GetState()));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.Player.Events
|
||||
{
|
||||
public class ServerSendPlayerStatesEvent : QSBEvent<PlayerStateMessage>
|
||||
{
|
||||
public override EventType Type => EventType.PlayerState;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBServerSendPlayerStates, Handler);
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBServerSendPlayerStates, Handler);
|
||||
|
||||
private void Handler()
|
||||
{
|
||||
foreach (var player in QSBPlayerManager.PlayerList)
|
||||
{
|
||||
DebugLog.DebugWrite($" - Sending playerstate of player ID {player.PlayerId}", MessageType.Info);
|
||||
SendEvent(CreateMessage(player));
|
||||
}
|
||||
}
|
||||
|
||||
private PlayerStateMessage CreateMessage(PlayerInfo player) => new PlayerStateMessage
|
||||
{
|
||||
AboutId = player.PlayerId,
|
||||
PlayerName = player.Name,
|
||||
PlayerState = player.PlayerStates
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerStateMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Received playerstate of player ID {message.AboutId}", MessageType.Info);
|
||||
if (QSBPlayerManager.PlayerExists(message.AboutId))
|
||||
{
|
||||
QSBPlayerManager.HandleFullStateMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
using UnityEngine;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Player
|
||||
{
|
||||
public class PlayerHUDMarker : HUDDistanceMarker
|
||||
{
|
||||
private PlayerInfo _player;
|
||||
private bool _needsInitializing;
|
||||
private bool _isReady;
|
||||
|
||||
protected override void InitCanvasMarker()
|
||||
@ -19,34 +21,57 @@ namespace QSB.Player
|
||||
|
||||
public void Init(PlayerInfo player)
|
||||
{
|
||||
DebugLog.DebugWrite($"Init {player.PlayerId} name:{player.Name}");
|
||||
_player = player;
|
||||
_player.HudMarker = this;
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
protected override void RefreshOwnVisibility()
|
||||
{
|
||||
if (_canvasMarker != null)
|
||||
{
|
||||
_canvasMarker.SetVisibility(true);
|
||||
}
|
||||
_needsInitializing = true;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_needsInitializing)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
if (!_isReady || !_player.PlayerStates.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_canvasMarker != null)
|
||||
{
|
||||
var isVisible = _canvasMarker.IsVisible();
|
||||
|
||||
if (_player.Visible != isVisible)
|
||||
{
|
||||
_canvasMarker.SetVisibility(_player.Visible);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"Warning - _canvasMarker for {_player.PlayerId} is null!", OWML.Common.MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
if (_player.Name == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {_player.PlayerId} has a null name!", OWML.Common.MessageType.Error);
|
||||
_player.Name = "NULL";
|
||||
}
|
||||
|
||||
_markerLabel = _player.Name.ToUpper();
|
||||
_isReady = false;
|
||||
_needsInitializing = false;
|
||||
_isReady = true;
|
||||
|
||||
base.InitCanvasMarker();
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
_isReady = false;
|
||||
// do N O T destroy the parent - it completely breaks the ENTIRE GAME
|
||||
if (_canvasMarker != null)
|
||||
{
|
||||
|
@ -1,11 +1,14 @@
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Animation.Player.Thrusters;
|
||||
using QSB.CampfireSync.WorldObjects;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.ProbeSync;
|
||||
using QSB.QuantumSync;
|
||||
using QSB.RoastingSync;
|
||||
using QSB.Tools;
|
||||
using QSB.Tools.ProbeLauncherTool;
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
@ -24,19 +27,31 @@ namespace QSB.Player
|
||||
public GameObject CameraBody { get; set; }
|
||||
public GameObject Body { get; set; }
|
||||
public GameObject RoastingStick { get; set; }
|
||||
public bool Visible { get; set; } = true;
|
||||
|
||||
// Tools
|
||||
public GameObject ProbeBody { get; set; }
|
||||
public QSBProbe Probe { get; set; }
|
||||
public QSBFlashlight FlashLight => CameraBody?.GetComponentInChildren<QSBFlashlight>();
|
||||
public QSBFlashlight FlashLight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CameraBody == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return CameraBody.GetComponentInChildren<QSBFlashlight>();
|
||||
}
|
||||
}
|
||||
public QSBTool Signalscope => GetToolByType(ToolType.Signalscope);
|
||||
public QSBTool Translator => GetToolByType(ToolType.Translator);
|
||||
public QSBTool ProbeLauncher => GetToolByType(ToolType.ProbeLauncher);
|
||||
public Transform ItemSocket => CameraBody.transform.Find("ItemSocket");
|
||||
public Transform ScrollSocket => CameraBody.transform.Find("ScrollSocket");
|
||||
public Transform SharedStoneSocket => CameraBody.transform.Find("SharedStoneSocket");
|
||||
public Transform WarpCoreSocket => CameraBody.transform.Find("WarpCoreSocket");
|
||||
public Transform VesselCoreSocket => CameraBody.transform.Find("VesselCoreSocket");
|
||||
public QSBProbeLauncherTool ProbeLauncher => (QSBProbeLauncherTool)GetToolByType(ToolType.ProbeLauncher);
|
||||
public Transform ItemSocket => CameraBody.transform.Find("REMOTE_ItemSocket");
|
||||
public Transform ScrollSocket => CameraBody.transform.Find("REMOTE_ScrollSocket");
|
||||
public Transform SharedStoneSocket => CameraBody.transform.Find("REMOTE_SharedStoneSocket");
|
||||
public Transform WarpCoreSocket => CameraBody.transform.Find("REMOTE_WarpCoreSocket");
|
||||
public Transform VesselCoreSocket => CameraBody.transform.Find("REMOTE_VesselCoreSocket");
|
||||
public QSBMarshmallow Marshmallow { get; set; }
|
||||
public QSBCampfire Campfire { get; set; }
|
||||
|
||||
@ -54,6 +69,66 @@ namespace QSB.Player
|
||||
public bool IsInMoon; // TODO : move into PlayerStates?
|
||||
public bool IsInShrine; // TODO : move into PlayerStates?
|
||||
public IQSBQuantumObject EntangledObject;
|
||||
public bool IsDead { get; set; }
|
||||
public ClientState State { get; set; }
|
||||
|
||||
// Local only
|
||||
public PlayerProbeLauncher LocalProbeLauncher
|
||||
{
|
||||
get
|
||||
{
|
||||
if (QSBPlayerManager.LocalPlayer != this)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalProbeLauncher in PlayerInfo for non local player!", OWML.Common.MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
return CameraBody.transform.Find("ProbeLauncher").GetComponent<PlayerProbeLauncher>();
|
||||
}
|
||||
}
|
||||
|
||||
public Flashlight LocalFlashlight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (QSBPlayerManager.LocalPlayer != this)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalFlashlight in PlayerInfo for non local player!", OWML.Common.MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
return Locator.GetFlashlight();
|
||||
}
|
||||
}
|
||||
|
||||
public Signalscope LocalSignalscope
|
||||
{
|
||||
get
|
||||
{
|
||||
if (QSBPlayerManager.LocalPlayer != this)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalSignalscope in PlayerInfo for non local player!", OWML.Common.MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
return CameraBody.transform.Find("Signalscope").GetComponent<Signalscope>();
|
||||
}
|
||||
}
|
||||
|
||||
public NomaiTranslator LocalTranslator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (QSBPlayerManager.LocalPlayer != this)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalTranslator in PlayerInfo for non local player!", OWML.Common.MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
return CameraBody.transform.Find("NomaiTranslatorProp").GetComponent<NomaiTranslator>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public PlayerInfo(uint id)
|
||||
{
|
||||
@ -76,10 +151,7 @@ namespace QSB.Player
|
||||
() => QSBPlayerManager.GetSyncObject<AnimationSync>(PlayerId).SetSuitState(PlayerStates.SuitedUp));
|
||||
}
|
||||
|
||||
private QSBTool GetToolByType(ToolType type)
|
||||
{
|
||||
return CameraBody?.GetComponentsInChildren<QSBTool>()
|
||||
private QSBTool GetToolByType(ToolType type) => CameraBody?.GetComponentsInChildren<QSBTool>()
|
||||
.FirstOrDefault(x => x.Type == type);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ using QSB.Tools;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
@ -20,9 +19,8 @@ namespace QSB.Player
|
||||
var localInstance = PlayerTransformSync.LocalInstance;
|
||||
if (localInstance == null)
|
||||
{
|
||||
var method = new StackTrace().GetFrame(1).GetMethod();
|
||||
DebugLog.ToConsole($"Error - Trying to get LocalPlayerId when the local PlayerTransformSync instance is null." +
|
||||
$"{Environment.NewLine} Called from {method.DeclaringType.Name}.{method.Name} ", MessageType.Error);
|
||||
$"{Environment.NewLine} Stacktrace : {Environment.StackTrace} ", MessageType.Error);
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
@ -47,9 +45,8 @@ namespace QSB.Player
|
||||
{
|
||||
if (!QSBNetworkManager.Instance.IsReady)
|
||||
{
|
||||
var method = new StackTrace().GetFrame(1).GetMethod();
|
||||
DebugLog.ToConsole($"Warning - GetPlayer() (id<{id}>) called when Network Manager not ready! Is a Player Sync Object still active? " +
|
||||
$"{Environment.NewLine} Called from {method.DeclaringType.Name}.{method.Name}", MessageType.Warning);
|
||||
$"{Environment.NewLine} Stacktrace :\r\n{Environment.StackTrace}", MessageType.Warning);
|
||||
}
|
||||
|
||||
if (id == uint.MaxValue || id == 0U)
|
||||
@ -63,8 +60,13 @@ namespace QSB.Player
|
||||
return player;
|
||||
}
|
||||
|
||||
var trace = new StackTrace().GetFrame(1).GetMethod();
|
||||
DebugLog.DebugWrite($"Create Player : id<{id}> (Called from {trace.DeclaringType.Name}.{trace.Name})", MessageType.Info);
|
||||
if (!QSBCore.IsInMultiplayer)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Tried to create player id:{id} when not in multiplayer! Stacktrace : {Environment.StackTrace}", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"Create Player : id<{id}> Stacktrace :\r\n{Environment.StackTrace}", MessageType.Info);
|
||||
player = new PlayerInfo(id);
|
||||
PlayerList.Add(player);
|
||||
return player;
|
||||
@ -72,16 +74,16 @@ namespace QSB.Player
|
||||
|
||||
public static void RemovePlayer(uint id)
|
||||
{
|
||||
var trace = new StackTrace().GetFrame(1).GetMethod();
|
||||
DebugLog.DebugWrite($"Remove Player : id<{id}> (Called from {trace.DeclaringType.Name}.{trace.Name})", MessageType.Info);
|
||||
DebugLog.DebugWrite($"Remove Player : id<{id}> Stacktrace :\r\n{Environment.StackTrace}", MessageType.Info);
|
||||
PlayerList.RemoveAll(x => x.PlayerId == id);
|
||||
}
|
||||
|
||||
public static bool PlayerExists(uint id) =>
|
||||
id != uint.MaxValue && PlayerList.Any(x => x.PlayerId == id);
|
||||
|
||||
public static void HandleFullStateMessage(PlayerStateMessage message)
|
||||
public static void HandleFullStateMessage(PlayerInformationMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Handle full state message of {message.AboutId}");
|
||||
var player = GetPlayer(message.AboutId);
|
||||
player.Name = message.PlayerName;
|
||||
player.PlayerStates = message.PlayerState;
|
||||
@ -89,6 +91,7 @@ namespace QSB.Player
|
||||
{
|
||||
player.UpdateStateObjects();
|
||||
}
|
||||
player.State = message.ClientState;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetSyncObjects<T>() where T : PlayerSyncObject =>
|
||||
@ -101,11 +104,8 @@ namespace QSB.Player
|
||||
|
||||
public static void RemoveSyncObject(PlayerSyncObject obj) => PlayerSyncObjects.Remove(obj);
|
||||
|
||||
public static bool IsBelongingToLocalPlayer(uint id)
|
||||
{
|
||||
return id == LocalPlayerId ||
|
||||
public static bool IsBelongingToLocalPlayer(uint id) => id == LocalPlayerId ||
|
||||
PlayerSyncObjects.Any(x => x != null && x.AttachedNetId == id && x.IsLocalPlayer);
|
||||
}
|
||||
|
||||
public static List<PlayerInfo> GetPlayersWithCameras(bool includeLocalCamera = true)
|
||||
{
|
||||
@ -142,20 +142,19 @@ namespace QSB.Player
|
||||
{
|
||||
renderer.enabled = visible;
|
||||
}
|
||||
|
||||
player.Visible = visible;
|
||||
}
|
||||
|
||||
public static PlayerInfo GetClosestPlayerToWorldPoint(Vector3 worldPoint, bool includeLocalPlayer)
|
||||
{
|
||||
return includeLocalPlayer
|
||||
public static PlayerInfo GetClosestPlayerToWorldPoint(Vector3 worldPoint, bool includeLocalPlayer) => includeLocalPlayer
|
||||
? GetClosestPlayerToWorldPoint(PlayerList, worldPoint)
|
||||
: GetClosestPlayerToWorldPoint(PlayerList.Where(x => x != LocalPlayer).ToList(), worldPoint);
|
||||
}
|
||||
|
||||
public static PlayerInfo GetClosestPlayerToWorldPoint(List<PlayerInfo> playerList, Vector3 worldPoint)
|
||||
{
|
||||
if (playerList.Count == 0)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - Cannot get closest player from empty player list.", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - Cannot get closest player from empty player list.", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1,56 +0,0 @@
|
||||
using QSB.Events;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.TransformSync;
|
||||
using QSB.Tools;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Player.TransformSync
|
||||
{
|
||||
public class PlayerCameraSync : SectoredTransformSync
|
||||
{
|
||||
protected override Transform InitLocalTransform()
|
||||
{
|
||||
SectorSync.Init(Locator.GetPlayerSectorDetector(), this);
|
||||
var body = Locator.GetPlayerCamera().gameObject.transform;
|
||||
|
||||
Player.Camera = Locator.GetPlayerCamera();
|
||||
Player.CameraBody = body.gameObject;
|
||||
|
||||
Player.PlayerStates.IsReady = true;
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerReady, true);
|
||||
DebugLog.DebugWrite("PlayerCameraSync init done - Request state!");
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerStatesRequest);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
protected override Transform InitRemoteTransform()
|
||||
{
|
||||
var body = new GameObject("RemotePlayerCamera");
|
||||
|
||||
PlayerToolsManager.Init(body.transform);
|
||||
|
||||
var camera = body.AddComponent<Camera>();
|
||||
camera.enabled = false;
|
||||
var owcamera = body.AddComponent<OWCamera>();
|
||||
owcamera.fieldOfView = 70;
|
||||
owcamera.nearClipPlane = 0.1f;
|
||||
owcamera.farClipPlane = 50000f;
|
||||
Player.Camera = owcamera;
|
||||
Player.CameraBody = body;
|
||||
|
||||
return body.transform;
|
||||
}
|
||||
|
||||
public override bool IsReady => Locator.GetPlayerTransform() != null
|
||||
&& Player != null
|
||||
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
|
||||
&& NetId.Value != uint.MaxValue
|
||||
&& NetId.Value != 0U;
|
||||
|
||||
public override bool UseInterpolation => true;
|
||||
|
||||
public override TargetType Type => TargetType.PlayerCamera;
|
||||
}
|
||||
}
|
@ -1,7 +1,14 @@
|
||||
using QSB.Animation.Player;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Instruments;
|
||||
using QSB.RoastingSync;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.TransformSync;
|
||||
using QSB.Tools;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Player.TransformSync
|
||||
@ -10,6 +17,31 @@ namespace QSB.Player.TransformSync
|
||||
{
|
||||
static PlayerTransformSync() => AnimControllerPatch.Init();
|
||||
|
||||
private Transform _visibleCameraRoot;
|
||||
private Transform _networkCameraRoot => gameObject.transform.GetChild(0);
|
||||
|
||||
private Transform _visibleRoastingSystem;
|
||||
private Transform _networkRoastingSystem => gameObject.transform.GetChild(1);
|
||||
private Transform _networkStickRoot => _networkRoastingSystem.GetChild(0);
|
||||
|
||||
private Transform _visibleStickPivot;
|
||||
private Transform _networkStickPivot => _networkStickRoot.GetChild(0);
|
||||
|
||||
private Transform _visibleStickTip;
|
||||
private Transform _networkStickTip => _networkStickPivot.GetChild(0);
|
||||
|
||||
protected Vector3 _cameraPositionVelocity;
|
||||
protected Quaternion _cameraRotationVelocity;
|
||||
protected Vector3 _pivotPositionVelocity;
|
||||
protected Quaternion _pivotRotationVelocity;
|
||||
protected Vector3 _tipPositionVelocity;
|
||||
protected Quaternion _tipRotationVelocity;
|
||||
protected Vector3 _roastingPositionVelocity;
|
||||
protected Quaternion _roastingRotationVelocity;
|
||||
|
||||
private Transform GetStickPivot()
|
||||
=> Resources.FindObjectsOfTypeAll<RoastingStickController>().First().transform.Find("Stick_Root/Stick_Pivot");
|
||||
|
||||
public override void OnStartLocalPlayer()
|
||||
=> LocalInstance = this;
|
||||
|
||||
@ -19,8 +51,30 @@ namespace QSB.Player.TransformSync
|
||||
Player.TransformSync = this;
|
||||
}
|
||||
|
||||
protected override void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse)
|
||||
{
|
||||
if (!HasAuthority)
|
||||
{
|
||||
base.OnSceneLoaded(oldScene, newScene, isInUniverse);
|
||||
}
|
||||
|
||||
if (isInUniverse)
|
||||
{
|
||||
Player.PlayerStates.IsReady = true;
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerReady, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.PlayerStates.IsReady = false;
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerReady, false);
|
||||
}
|
||||
|
||||
base.OnSceneLoaded(oldScene, newScene, isInUniverse);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
// TODO : Maybe move this to a leave event...? Would ensure everything could finish up before removing the player
|
||||
QSBPlayerManager.OnRemovePlayer?.Invoke(PlayerId);
|
||||
base.OnDestroy();
|
||||
if (QSBPlayerManager.PlayerExists(PlayerId))
|
||||
@ -30,44 +84,193 @@ namespace QSB.Player.TransformSync
|
||||
}
|
||||
}
|
||||
|
||||
private Transform GetPlayerModel() =>
|
||||
Locator.GetPlayerTransform().Find("Traveller_HEA_Player_v2");
|
||||
|
||||
protected override Transform InitLocalTransform()
|
||||
protected override Component InitLocalTransform()
|
||||
{
|
||||
SectorSync.Init(Locator.GetPlayerSectorDetector(), this);
|
||||
var body = GetPlayerModel();
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetPlayerSectorDetector(), this));
|
||||
|
||||
GetComponent<AnimationSync>().InitLocal(body);
|
||||
GetComponent<InstrumentsManager>().InitLocal(body);
|
||||
// player body
|
||||
var player = Locator.GetPlayerTransform();
|
||||
var playerModel = player.Find("Traveller_HEA_Player_v2");
|
||||
GetComponent<AnimationSync>().InitLocal(playerModel);
|
||||
GetComponent<InstrumentsManager>().InitLocal(player);
|
||||
Player.Body = player.gameObject;
|
||||
|
||||
Player.Body = body.gameObject;
|
||||
// camera
|
||||
var cameraBody = Locator.GetPlayerCamera().gameObject.transform;
|
||||
Player.Camera = Locator.GetPlayerCamera();
|
||||
Player.CameraBody = cameraBody.gameObject;
|
||||
_visibleCameraRoot = cameraBody;
|
||||
|
||||
return body;
|
||||
// stick
|
||||
var pivot = GetStickPivot();
|
||||
Player.RoastingStick = pivot.parent.gameObject;
|
||||
_visibleRoastingSystem = pivot.parent.parent;
|
||||
_visibleStickPivot = pivot;
|
||||
_visibleStickTip = pivot.Find("Stick_Tip");
|
||||
|
||||
DebugLog.DebugWrite("PlayerTransformSync init done - Request state!");
|
||||
QSBEventManager.FireEvent(EventNames.QSBRequestStateResync);
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
protected override Transform InitRemoteTransform()
|
||||
protected override Component InitRemoteTransform()
|
||||
{
|
||||
var body = Instantiate(GetPlayerModel());
|
||||
Player.Body = body.gameObject;
|
||||
/*
|
||||
* CREATE PLAYER STRUCTURE
|
||||
*/
|
||||
|
||||
GetComponent<AnimationSync>().InitRemote(body);
|
||||
GetComponent<InstrumentsManager>().InitRemote(body);
|
||||
// Variable naming convention is broken here to reflect OW unity project (with REMOTE_ prefixed) for readability
|
||||
|
||||
var marker = body.gameObject.AddComponent<PlayerHUDMarker>();
|
||||
var REMOTE_Player_Body = new GameObject("REMOTE_Player_Body");
|
||||
|
||||
var REMOTE_PlayerCamera = new GameObject("REMOTE_PlayerCamera");
|
||||
REMOTE_PlayerCamera.transform.parent = REMOTE_Player_Body.transform;
|
||||
REMOTE_PlayerCamera.transform.localPosition = new Vector3(0f, 0.8496093f, 0.1500003f);
|
||||
|
||||
var REMOTE_RoastingSystem = new GameObject("REMOTE_RoastingSystem");
|
||||
REMOTE_RoastingSystem.transform.parent = REMOTE_Player_Body.transform;
|
||||
REMOTE_RoastingSystem.transform.localPosition = new Vector3(0f, 0.4f, 0f);
|
||||
|
||||
var REMOTE_Stick_Root = new GameObject("REMOTE_Stick_Root");
|
||||
REMOTE_Stick_Root.transform.parent = REMOTE_RoastingSystem.transform;
|
||||
REMOTE_Stick_Root.transform.localPosition = new Vector3(0.25f, 0f, 0.08f);
|
||||
REMOTE_Stick_Root.transform.localRotation = Quaternion.Euler(0f, -10f, 0f);
|
||||
|
||||
/*
|
||||
* SET UP PLAYER BODY
|
||||
*/
|
||||
|
||||
var player = Locator.GetPlayerTransform();
|
||||
var playerModel = player.Find("Traveller_HEA_Player_v2");
|
||||
|
||||
var REMOTE_Traveller_HEA_Player_v2 = Instantiate(playerModel);
|
||||
REMOTE_Traveller_HEA_Player_v2.transform.parent = REMOTE_Player_Body.transform;
|
||||
REMOTE_Traveller_HEA_Player_v2.transform.localPosition = new Vector3(0f, -1.03f, -0.2f);
|
||||
REMOTE_Traveller_HEA_Player_v2.transform.localRotation = Quaternion.Euler(-1.500009f, 0f, 0f);
|
||||
REMOTE_Traveller_HEA_Player_v2.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
|
||||
|
||||
Player.Body = REMOTE_Player_Body;
|
||||
|
||||
GetComponent<AnimationSync>().InitRemote(REMOTE_Traveller_HEA_Player_v2);
|
||||
GetComponent<InstrumentsManager>().InitRemote(REMOTE_Player_Body.transform);
|
||||
|
||||
var marker = REMOTE_Player_Body.AddComponent<PlayerHUDMarker>();
|
||||
marker.Init(Player);
|
||||
|
||||
body.gameObject.AddComponent<PlayerMapMarker>().PlayerName = Player.Name;
|
||||
REMOTE_Player_Body.AddComponent<PlayerMapMarker>().PlayerName = Player.Name;
|
||||
|
||||
return body;
|
||||
/*
|
||||
* SET UP PLAYER CAMERA
|
||||
*/
|
||||
|
||||
PlayerToolsManager.Init(REMOTE_PlayerCamera.transform);
|
||||
|
||||
var camera = REMOTE_PlayerCamera.AddComponent<Camera>();
|
||||
camera.enabled = false;
|
||||
var owcamera = REMOTE_PlayerCamera.AddComponent<OWCamera>();
|
||||
owcamera.fieldOfView = 70;
|
||||
owcamera.nearClipPlane = 0.1f;
|
||||
owcamera.farClipPlane = 50000f;
|
||||
Player.Camera = owcamera;
|
||||
Player.CameraBody = REMOTE_PlayerCamera;
|
||||
_visibleCameraRoot = REMOTE_PlayerCamera.transform;
|
||||
|
||||
/*
|
||||
* SET UP ROASTING STICK
|
||||
*/
|
||||
|
||||
var REMOTE_Stick_Pivot = Instantiate(GetStickPivot());
|
||||
REMOTE_Stick_Pivot.name = "REMOTE_Stick_Pivot";
|
||||
REMOTE_Stick_Pivot.parent = REMOTE_Stick_Root.transform;
|
||||
REMOTE_Stick_Pivot.gameObject.SetActive(false);
|
||||
|
||||
Destroy(REMOTE_Stick_Pivot.Find("Stick_Tip/Props_HEA_RoastingStick/RoastingStick_Arm").gameObject);
|
||||
Destroy(REMOTE_Stick_Pivot.Find("Stick_Tip/Props_HEA_RoastingStick/RoastingStick_Arm_NoSuit").gameObject);
|
||||
|
||||
var mallowRoot = REMOTE_Stick_Pivot.Find("Stick_Tip/Mallow_Root");
|
||||
mallowRoot.gameObject.SetActive(false);
|
||||
var oldMarshmallow = mallowRoot.GetComponent<Marshmallow>();
|
||||
|
||||
// Recreate particle system
|
||||
Destroy(mallowRoot.Find("MallowSmoke").GetComponent<RelativisticParticleSystem>());
|
||||
var newSystem = mallowRoot.Find("MallowSmoke").gameObject.AddComponent<CustomRelativisticParticleSystem>();
|
||||
newSystem.Init(Player);
|
||||
|
||||
// Create new marshmallow
|
||||
var newMarshmallow = mallowRoot.gameObject.AddComponent<QSBMarshmallow>();
|
||||
newMarshmallow._fireRenderer = oldMarshmallow.GetValue<MeshRenderer>("_fireRenderer");
|
||||
newMarshmallow._smokeParticles = oldMarshmallow.GetValue<ParticleSystem>("_smokeParticles");
|
||||
newMarshmallow._mallowRenderer = oldMarshmallow.GetValue<MeshRenderer>("_mallowRenderer");
|
||||
newMarshmallow._rawColor = oldMarshmallow.GetValue<Color>("_rawColor");
|
||||
newMarshmallow._toastedColor = oldMarshmallow.GetValue<Color>("_toastedColor");
|
||||
newMarshmallow._burntColor = oldMarshmallow.GetValue<Color>("_burntColor");
|
||||
Destroy(oldMarshmallow);
|
||||
|
||||
Player.RoastingStick = REMOTE_Stick_Pivot.gameObject;
|
||||
Player.Marshmallow = newMarshmallow;
|
||||
mallowRoot.gameObject.SetActive(true);
|
||||
_visibleRoastingSystem = REMOTE_RoastingSystem.transform;
|
||||
_visibleStickPivot = REMOTE_Stick_Pivot;
|
||||
_visibleStickTip = REMOTE_Stick_Pivot.Find("Stick_Tip");
|
||||
|
||||
return REMOTE_Player_Body.transform;
|
||||
}
|
||||
|
||||
public override bool IsReady => Locator.GetPlayerTransform() != null
|
||||
&& Player != null
|
||||
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
|
||||
&& Player.PlayerStates.IsReady
|
||||
&& NetId.Value != uint.MaxValue
|
||||
&& NetId.Value != 0U;
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (!base.UpdateTransform())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateSpecificTransform(_visibleStickPivot, _networkStickPivot, ref _pivotPositionVelocity, ref _pivotRotationVelocity);
|
||||
UpdateSpecificTransform(_visibleStickTip, _networkStickTip, ref _tipPositionVelocity, ref _tipRotationVelocity);
|
||||
UpdateSpecificTransform(_visibleCameraRoot, _networkCameraRoot, ref _cameraPositionVelocity, ref _cameraRotationVelocity);
|
||||
UpdateSpecificTransform(_visibleRoastingSystem, _networkRoastingSystem, ref _roastingPositionVelocity, ref _roastingRotationVelocity);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateSpecificTransform(Transform visible, Transform network, ref Vector3 positionVelocity, ref Quaternion rotationVelocity)
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
network.localPosition = visible.localPosition;
|
||||
network.localRotation = visible.localRotation;
|
||||
return;
|
||||
}
|
||||
|
||||
visible.localPosition = Vector3.SmoothDamp(visible.localPosition, network.localPosition, ref positionVelocity, SmoothTime);
|
||||
visible.localRotation = QuaternionHelper.SmoothDamp(visible.localRotation, network.localRotation, ref rotationVelocity, SmoothTime);
|
||||
}
|
||||
|
||||
protected override void OnRenderObject()
|
||||
{
|
||||
base.OnRenderObject();
|
||||
|
||||
if (!QSBCore.WorldObjectsReady
|
||||
|| !QSBCore.DebugMode
|
||||
|| !QSBCore.ShowLinesInDebug
|
||||
|| !IsReady
|
||||
|| ReferenceTransform == null
|
||||
|| _intermediaryTransform.GetReferenceTransform() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Cube(ReferenceTransform.TransformPoint(_networkRoastingSystem.position), ReferenceTransform.TransformRotation(_networkRoastingSystem.rotation), Vector3.one / 4, Color.red);
|
||||
Popcron.Gizmos.Cube(ReferenceTransform.TransformPoint(_networkStickPivot.position), ReferenceTransform.TransformRotation(_networkStickPivot.rotation), Vector3.one / 4, Color.red);
|
||||
Popcron.Gizmos.Cube(ReferenceTransform.TransformPoint(_networkStickTip.position), ReferenceTransform.TransformRotation(_networkStickTip.rotation), Vector3.one / 4, Color.red);
|
||||
Popcron.Gizmos.Cube(ReferenceTransform.TransformPoint(_networkCameraRoot.position), ReferenceTransform.TransformRotation(_networkCameraRoot.rotation), Vector3.one / 4, Color.red);
|
||||
|
||||
Popcron.Gizmos.Cube(_visibleRoastingSystem.position, _visibleRoastingSystem.rotation, Vector3.one / 4, Color.magenta);
|
||||
Popcron.Gizmos.Cube(_visibleStickPivot.position, _visibleStickPivot.rotation, Vector3.one / 4, Color.blue);
|
||||
Popcron.Gizmos.Cube(_visibleStickTip.position, _visibleStickTip.rotation, Vector3.one / 4, Color.yellow);
|
||||
Popcron.Gizmos.Cube(_visibleCameraRoot.position, _visibleCameraRoot.rotation, Vector3.one / 4, Color.grey);
|
||||
}
|
||||
|
||||
public override bool IsReady
|
||||
=> Locator.GetPlayerTransform() != null;
|
||||
|
||||
public static PlayerTransformSync LocalInstance { get; private set; }
|
||||
|
||||
|
@ -4,39 +4,30 @@ using QSB.Player;
|
||||
|
||||
namespace QSB.ProbeSync.Events
|
||||
{
|
||||
public class PlayerProbeEvent : QSBEvent<ToggleMessage>
|
||||
internal class PlayerProbeEvent : QSBEvent<EnumMessage<ProbeEvent>>
|
||||
{
|
||||
public override EventType Type => EventType.ProbeActiveChange;
|
||||
public override EventType Type => EventType.ProbeEvent;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger<SurveyorProbe>.AddListener(EventNames.LaunchProbe, HandleLaunch);
|
||||
GlobalMessenger<SurveyorProbe>.AddListener(EventNames.RetrieveProbe, HandleRetrieve);
|
||||
}
|
||||
=> GlobalMessenger<ProbeEvent>.AddListener(EventNames.QSBProbeEvent, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger<SurveyorProbe>.RemoveListener(EventNames.LaunchProbe, HandleLaunch);
|
||||
GlobalMessenger<SurveyorProbe>.RemoveListener(EventNames.RetrieveProbe, HandleRetrieve);
|
||||
}
|
||||
=> GlobalMessenger<ProbeEvent>.RemoveListener(EventNames.QSBProbeEvent, Handler);
|
||||
|
||||
private void HandleLaunch(SurveyorProbe probe) => SendEvent(CreateMessage(true));
|
||||
private void HandleRetrieve(SurveyorProbe probe) => SendEvent(CreateMessage(false));
|
||||
private void Handler(ProbeEvent probeEvent) => SendEvent(CreateMessage(probeEvent));
|
||||
|
||||
private ToggleMessage CreateMessage(bool value) => new ToggleMessage
|
||||
private EnumMessage<ProbeEvent> CreateMessage(ProbeEvent probeEvent) => new EnumMessage<ProbeEvent>
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ToggleValue = value
|
||||
EnumValue = probeEvent
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, ToggleMessage message)
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<ProbeEvent> message)
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
player.PlayerStates.ProbeActive = message.ToggleValue;
|
||||
player.Probe?.SetState(message.ToggleValue);
|
||||
}
|
||||
var probe = player.Probe;
|
||||
|
||||
public override void OnReceiveLocal(bool server, ToggleMessage message) =>
|
||||
QSBPlayerManager.LocalPlayer.PlayerStates.ProbeActive = message.ToggleValue;
|
||||
probe.HandleEvent(message.EnumValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
QSB/ProbeSync/Events/ProbeStartRetrieveEvent.cs
Normal file
32
QSB/ProbeSync/Events/ProbeStartRetrieveEvent.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.ProbeSync.Events
|
||||
{
|
||||
internal class ProbeStartRetrieveEvent : QSBEvent<FloatMessage>
|
||||
{
|
||||
public override EventType Type => EventType.ProbeStartRetrieve;
|
||||
|
||||
public override void SetupListener()
|
||||
=> GlobalMessenger<float>.AddListener(EventNames.QSBProbeStartRetrieve, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
=> GlobalMessenger<float>.RemoveListener(EventNames.QSBProbeStartRetrieve, Handler);
|
||||
|
||||
private void Handler(float duration) => SendEvent(CreateMessage(duration));
|
||||
|
||||
private FloatMessage CreateMessage(float duration) => new FloatMessage
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
Value = duration
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, FloatMessage message)
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
var probe = player.Probe;
|
||||
probe.OnStartRetrieve(message.Value);
|
||||
}
|
||||
}
|
||||
}
|
12
QSB/ProbeSync/ProbeEvent.cs
Normal file
12
QSB/ProbeSync/ProbeEvent.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace QSB.ProbeSync
|
||||
{
|
||||
public enum ProbeEvent
|
||||
{
|
||||
Invalid = 0,
|
||||
Launch = 1,
|
||||
Anchor = 2,
|
||||
Unanchor = 3,
|
||||
Retrieve = 4,
|
||||
Destroy = 5
|
||||
}
|
||||
}
|
54
QSB/ProbeSync/ProbeListener.cs
Normal file
54
QSB/ProbeSync/ProbeListener.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using QSB.Events;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ProbeSync
|
||||
{
|
||||
internal class ProbeListener : MonoBehaviour
|
||||
{
|
||||
private SurveyorProbe _attachedProbe;
|
||||
|
||||
public void Init(SurveyorProbe localProbe)
|
||||
{
|
||||
_attachedProbe = localProbe;
|
||||
_attachedProbe.OnLaunchProbe += OnLaunchProbe;
|
||||
_attachedProbe.OnAnchorProbe += OnAnchorProbe;
|
||||
_attachedProbe.OnUnanchorProbe += OnUnanchorProbe;
|
||||
_attachedProbe.OnRetrieveProbe += OnRetrieveProbe;
|
||||
_attachedProbe.OnProbeDestroyed += OnProbeDestroyed;
|
||||
_attachedProbe.OnStartRetrieveProbe += OnStartRetrieveProbe;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_attachedProbe == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_attachedProbe.OnLaunchProbe -= OnLaunchProbe;
|
||||
_attachedProbe.OnAnchorProbe -= OnAnchorProbe;
|
||||
_attachedProbe.OnUnanchorProbe -= OnUnanchorProbe;
|
||||
_attachedProbe.OnRetrieveProbe -= OnRetrieveProbe;
|
||||
_attachedProbe.OnProbeDestroyed -= OnProbeDestroyed;
|
||||
_attachedProbe.OnStartRetrieveProbe -= OnStartRetrieveProbe;
|
||||
}
|
||||
|
||||
private void OnLaunchProbe()
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBProbeEvent, ProbeEvent.Launch);
|
||||
|
||||
private void OnAnchorProbe()
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBProbeEvent, ProbeEvent.Anchor);
|
||||
|
||||
private void OnUnanchorProbe()
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBProbeEvent, ProbeEvent.Unanchor);
|
||||
|
||||
private void OnRetrieveProbe()
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBProbeEvent, ProbeEvent.Retrieve);
|
||||
|
||||
private void OnProbeDestroyed()
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBProbeEvent, ProbeEvent.Destroy);
|
||||
|
||||
private void OnStartRetrieveProbe(float length)
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBProbeStartRetrieve, length);
|
||||
}
|
||||
}
|
@ -1,20 +1,143 @@
|
||||
using QSB.Utility;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ProbeSync
|
||||
{
|
||||
public class QSBProbe : MonoBehaviour
|
||||
{
|
||||
public void SetState(bool state)
|
||||
public delegate void SurveyorProbeEvent();
|
||||
public delegate void RetrieveEvent(float retrieveLength);
|
||||
|
||||
public event SurveyorProbeEvent OnLaunchProbe;
|
||||
public event SurveyorProbeEvent OnAnchorProbe;
|
||||
public event SurveyorProbeEvent OnUnanchorProbe;
|
||||
public event SurveyorProbeEvent OnRetrieveProbe;
|
||||
public event SurveyorProbeEvent OnProbeDestroyed;
|
||||
public event RetrieveEvent OnStartRetrieveProbe;
|
||||
|
||||
private GameObject _detectorObj;
|
||||
private RulesetDetector _rulesetDetector;
|
||||
private SingularityWarpEffect _warpEffect;
|
||||
private bool _isRetrieving;
|
||||
private PlayerInfo _owner;
|
||||
|
||||
public RulesetDetector GetRulesetDetector()
|
||||
=> _rulesetDetector;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (state)
|
||||
_detectorObj = GetComponentInChildren<RulesetDetector>().gameObject;
|
||||
_rulesetDetector = _detectorObj.GetComponent<RulesetDetector>();
|
||||
_warpEffect = GetComponentInChildren<SingularityWarpEffect>();
|
||||
_warpEffect.OnWarpComplete += OnWarpComplete;
|
||||
_isRetrieving = false;
|
||||
}
|
||||
|
||||
private void Start() => gameObject.SetActive(false);
|
||||
|
||||
protected void OnDestroy() => _warpEffect.OnWarpComplete -= OnWarpComplete;
|
||||
|
||||
public void SetOwner(PlayerInfo player)
|
||||
{
|
||||
if (_owner != null)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
gameObject.Show();
|
||||
DebugLog.ToConsole($"Warning - Trying to set owner of probe that already has an owner!", OWML.Common.MessageType.Warning);
|
||||
}
|
||||
|
||||
_owner = player;
|
||||
}
|
||||
|
||||
private void OnWarpComplete() => Deactivate();
|
||||
|
||||
public bool IsRetrieving()
|
||||
=> IsLaunched() && _isRetrieving;
|
||||
|
||||
public bool IsLaunched()
|
||||
=> gameObject.activeSelf;
|
||||
|
||||
public void HandleEvent(ProbeEvent probeEvent)
|
||||
{
|
||||
if (_owner == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to handle event on probe with no owner.", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
gameObject.Hide();
|
||||
switch (probeEvent)
|
||||
{
|
||||
case ProbeEvent.Launch:
|
||||
if (OnLaunchProbe == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - OnLaunchProbe is null!", OWML.Common.MessageType.Warning);
|
||||
break;
|
||||
}
|
||||
|
||||
gameObject.SetActive(true);
|
||||
transform.position = _owner.ProbeLauncher.transform.position;
|
||||
transform.rotation = _owner.ProbeLauncher.transform.rotation;
|
||||
|
||||
OnLaunchProbe();
|
||||
break;
|
||||
case ProbeEvent.Anchor:
|
||||
if (OnAnchorProbe == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - OnAnchorProbe is null!", OWML.Common.MessageType.Warning);
|
||||
break;
|
||||
}
|
||||
|
||||
OnAnchorProbe();
|
||||
break;
|
||||
case ProbeEvent.Unanchor:
|
||||
OnUnanchorProbe();
|
||||
break;
|
||||
case ProbeEvent.Retrieve:
|
||||
if (OnRetrieveProbe == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - OnRetrieveProbe is null!", OWML.Common.MessageType.Warning);
|
||||
break;
|
||||
}
|
||||
|
||||
OnRetrieveProbe();
|
||||
break;
|
||||
case ProbeEvent.Destroy:
|
||||
if (OnProbeDestroyed == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - OnProbeDestroyed is null!", OWML.Common.MessageType.Warning);
|
||||
break;
|
||||
}
|
||||
|
||||
OnProbeDestroyed();
|
||||
break;
|
||||
case ProbeEvent.Invalid:
|
||||
default:
|
||||
DebugLog.DebugWrite($"Warning - Unknown/Invalid probe event.", OWML.Common.MessageType.Warning);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Deactivate()
|
||||
{
|
||||
transform.localScale = Vector3.one;
|
||||
gameObject.SetActive(false);
|
||||
_isRetrieving = false;
|
||||
}
|
||||
|
||||
public void OnStartRetrieve(float duration)
|
||||
{
|
||||
if (!_isRetrieving)
|
||||
{
|
||||
_isRetrieving = true;
|
||||
_warpEffect.WarpObjectOut(duration);
|
||||
|
||||
if (OnStartRetrieveProbe == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - OnStartRetrieveProbe is null!", OWML.Common.MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
OnStartRetrieveProbe(duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
QSB/ProbeSync/QSBProbeEffects.cs
Normal file
62
QSB/ProbeSync/QSBProbeEffects.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ProbeSync
|
||||
{
|
||||
internal class QSBProbeEffects : MonoBehaviour
|
||||
{
|
||||
public OWAudioSource _flightLoopAudio;
|
||||
public OWAudioSource _anchorAudio;
|
||||
public ParticleSystem _anchorParticles;
|
||||
public ParticleSystem _underwaterAnchorParticles;
|
||||
|
||||
private QSBProbe _probe;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_probe = Resources.FindObjectsOfTypeAll<QSBProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
|
||||
if (_probe == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Couldn't find QSBProbe!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
|
||||
_probe.OnLaunchProbe += OnLaunch;
|
||||
_probe.OnAnchorProbe += OnAnchor;
|
||||
_probe.OnUnanchorProbe += OnUnanchor;
|
||||
_probe.OnStartRetrieveProbe += OnStartRetrieve;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_probe.OnLaunchProbe -= OnLaunch;
|
||||
_probe.OnAnchorProbe -= OnAnchor;
|
||||
_probe.OnUnanchorProbe -= OnUnanchor;
|
||||
_probe.OnStartRetrieveProbe -= OnStartRetrieve;
|
||||
}
|
||||
|
||||
private void OnLaunch() => _flightLoopAudio.FadeIn(0.1f, true, true, 1f);
|
||||
|
||||
private void OnAnchor()
|
||||
{
|
||||
// TODO : Come up with some other way of doing this
|
||||
|
||||
//if (this._fluidDetector.InFluidType(FluidVolume.Type.WATER))
|
||||
//{
|
||||
// this._underwaterAnchorParticles.Play();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
_anchorParticles.Play();
|
||||
//}
|
||||
_flightLoopAudio.FadeOut(0.5f, OWAudioSource.FadeOutCompleteAction.STOP, 0f);
|
||||
_anchorAudio.PlayOneShot(AudioType.ToolProbeAttach, 1f);
|
||||
}
|
||||
|
||||
private void OnUnanchor()
|
||||
=> _flightLoopAudio.FadeIn(0.5f, false, false, 1f);
|
||||
|
||||
private void OnStartRetrieve(float retrieveLength)
|
||||
=> _flightLoopAudio.FadeOut(retrieveLength, OWAudioSource.FadeOutCompleteAction.STOP, 0f);
|
||||
}
|
||||
}
|
114
QSB/ProbeSync/QSBProbeLantern.cs
Normal file
114
QSB/ProbeSync/QSBProbeLantern.cs
Normal file
@ -0,0 +1,114 @@
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ProbeSync
|
||||
{
|
||||
internal class QSBProbeLantern : MonoBehaviour
|
||||
{
|
||||
public float _fadeInDuration;
|
||||
public AnimationCurve _fadeInCurve;
|
||||
public AnimationCurve _fadeOutCurve;
|
||||
public OWEmissiveRenderer _emissiveRenderer;
|
||||
public float _originalRange;
|
||||
|
||||
private QSBProbe _probe;
|
||||
private OWLight2 _light;
|
||||
private float _fadeFraction;
|
||||
private float _targetFade;
|
||||
private float _startFade;
|
||||
private float _startFadeTime;
|
||||
private float _fadeDuration;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_probe = Resources.FindObjectsOfTypeAll<QSBProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
|
||||
if (_probe == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Couldn't find QSBProbe!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
|
||||
_light = GetComponent<OWLight2>();
|
||||
_probe.OnAnchorProbe += OnProbeAnchorToSurface;
|
||||
_probe.OnStartRetrieveProbe += OnStartRetrieveProbe;
|
||||
_probe.OnRetrieveProbe += OnFinishRetrieveProbe;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (_emissiveRenderer != null)
|
||||
{
|
||||
_emissiveRenderer.SetEmissiveScale(0f);
|
||||
}
|
||||
|
||||
_light.GetLight().enabled = false;
|
||||
//_originalRange = _light.range;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_probe.OnAnchorProbe -= OnProbeAnchorToSurface;
|
||||
_probe.OnStartRetrieveProbe -= OnStartRetrieveProbe;
|
||||
_probe.OnRetrieveProbe -= OnFinishRetrieveProbe;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var animationCurve = (_targetFade <= 0f)
|
||||
? _fadeOutCurve
|
||||
: _fadeInCurve;
|
||||
|
||||
var fadeTime = Mathf.InverseLerp(_startFadeTime, _startFadeTime + _fadeDuration, Time.time);
|
||||
_fadeFraction = Mathf.Lerp(_startFade, _targetFade, animationCurve.Evaluate(fadeTime));
|
||||
|
||||
var probeRuleSet = _probe.GetRulesetDetector().GetProbeRuleSet();
|
||||
|
||||
var lanternRange = (!(probeRuleSet != null) || !probeRuleSet.GetOverrideLanternRange())
|
||||
? _originalRange
|
||||
: probeRuleSet.GetLanternRange();
|
||||
|
||||
_light.range = lanternRange * _fadeFraction;
|
||||
|
||||
if (_emissiveRenderer != null)
|
||||
{
|
||||
_emissiveRenderer.SetEmissiveScale(_fadeFraction);
|
||||
}
|
||||
|
||||
if (fadeTime >= 1f)
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void FadeTo(float fade, float duration)
|
||||
{
|
||||
_startFadeTime = Time.time;
|
||||
_fadeDuration = duration;
|
||||
_startFade = _fadeFraction;
|
||||
_targetFade = fade;
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
private void OnProbeAnchorToSurface()
|
||||
{
|
||||
if (!_probe.IsRetrieving())
|
||||
{
|
||||
_light.GetLight().enabled = true;
|
||||
_light.range = 0f;
|
||||
FadeTo(1f, _fadeInDuration);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStartRetrieveProbe(float retrieveLength)
|
||||
=> FadeTo(0f, retrieveLength);
|
||||
|
||||
private void OnFinishRetrieveProbe()
|
||||
{
|
||||
_light.GetLight().enabled = false;
|
||||
_light.range = 0f;
|
||||
_fadeFraction = 0f;
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
78
QSB/ProbeSync/QSBProbeSpotlight.cs
Normal file
78
QSB/ProbeSync/QSBProbeSpotlight.cs
Normal file
@ -0,0 +1,78 @@
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ProbeSync
|
||||
{
|
||||
internal class QSBProbeSpotlight : MonoBehaviour
|
||||
{
|
||||
public ProbeCamera.ID _id;
|
||||
public float _fadeInLength = 1f;
|
||||
public float _intensity;
|
||||
|
||||
private QSBProbe _probe;
|
||||
private OWLight2 _light;
|
||||
private bool _inFlight;
|
||||
private float _timer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_probe = Resources.FindObjectsOfTypeAll<QSBProbe>().First(x => gameObject.transform.IsChildOf(x.transform));
|
||||
if (_probe == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Couldn't find QSBProbe!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
|
||||
_light = GetComponent<OWLight2>();
|
||||
//_intensity = _light.GetLight().intensity;
|
||||
_light.GetLight().enabled = false;
|
||||
enabled = false;
|
||||
_probe.OnLaunchProbe += OnLaunch;
|
||||
_probe.OnAnchorProbe += OnAnchorOrRetrieve;
|
||||
_probe.OnRetrieveProbe += OnAnchorOrRetrieve;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_probe.OnLaunchProbe -= OnLaunch;
|
||||
_probe.OnAnchorProbe -= OnAnchorOrRetrieve;
|
||||
_probe.OnRetrieveProbe -= OnAnchorOrRetrieve;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
_timer += Time.deltaTime;
|
||||
var num = Mathf.Clamp01(_timer / _fadeInLength);
|
||||
var intensityScale = (2f - num) * num * _intensity;
|
||||
_light.SetIntensityScale(intensityScale);
|
||||
}
|
||||
|
||||
private void StartFadeIn()
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
_light.GetLight().enabled = true;
|
||||
_light.SetIntensityScale(0f);
|
||||
_timer = 0f;
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLaunch()
|
||||
{
|
||||
if (_id == ProbeCamera.ID.Forward)
|
||||
{
|
||||
StartFadeIn();
|
||||
}
|
||||
|
||||
_inFlight = true;
|
||||
}
|
||||
|
||||
private void OnAnchorOrRetrieve()
|
||||
{
|
||||
_light.GetLight().enabled = false;
|
||||
enabled = false;
|
||||
_inFlight = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +1,51 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using OWML.Utils;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.TransformSync;
|
||||
using QSB.Tools;
|
||||
using QSB.Tools.ProbeLauncherTool;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ProbeSync.TransformSync
|
||||
{
|
||||
public class PlayerProbeSync : SectoredTransformSync
|
||||
{
|
||||
protected override float DistanceLeeway => 10f;
|
||||
public override bool UseInterpolation => true;
|
||||
public override TargetType Type => TargetType.Probe;
|
||||
public override bool IgnoreDisabledAttachedObject => true;
|
||||
|
||||
public static PlayerProbeSync LocalInstance { get; private set; }
|
||||
|
||||
public override void OnStartAuthority()
|
||||
public override void OnStartAuthority() => LocalInstance = this;
|
||||
|
||||
protected override Component InitLocalTransform()
|
||||
{
|
||||
DebugLog.DebugWrite($"OnStartAuthority probe");
|
||||
LocalInstance = this;
|
||||
}
|
||||
|
||||
private Transform GetProbe() =>
|
||||
Locator.GetProbe().transform.Find("CameraPivot").Find("Geometry");
|
||||
|
||||
protected override Transform InitLocalTransform()
|
||||
{
|
||||
SectorSync.Init(Locator.GetProbe().GetSectorDetector(), this);
|
||||
var body = GetProbe();
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetProbe().GetSectorDetector(), this));
|
||||
|
||||
var body = Locator.GetProbe().transform;
|
||||
Player.ProbeBody = body.gameObject;
|
||||
|
||||
if (Player.Body == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Player.Body is null!", MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
var listener = Player.Body.AddComponent<ProbeListener>();
|
||||
listener.Init(Locator.GetProbe());
|
||||
|
||||
var launcherListener = Player.Body.AddComponent<ProbeLauncherListener>();
|
||||
launcherListener.Init(Player.LocalProbeLauncher);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
protected override Transform InitRemoteTransform()
|
||||
protected override Component InitRemoteTransform()
|
||||
{
|
||||
var probe = GetProbe();
|
||||
var probe = Locator.GetProbe().transform;
|
||||
|
||||
if (probe == null)
|
||||
{
|
||||
@ -41,10 +53,11 @@ namespace QSB.ProbeSync.TransformSync
|
||||
return default;
|
||||
}
|
||||
|
||||
var body = probe.InstantiateInactive();
|
||||
body.name = "RemoteProbeTransform";
|
||||
var body = probe.gameObject.activeSelf
|
||||
? probe.InstantiateInactive()
|
||||
: Instantiate(probe);
|
||||
|
||||
Destroy(body.GetComponentInChildren<ProbeAnimatorController>());
|
||||
body.name = "RemoteProbeTransform";
|
||||
|
||||
PlayerToolsManager.CreateProbe(body, Player);
|
||||
|
||||
@ -53,17 +66,45 @@ namespace QSB.ProbeSync.TransformSync
|
||||
return body;
|
||||
}
|
||||
|
||||
public override bool IsReady => Locator.GetProbe() != null
|
||||
&& Player != null
|
||||
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
|
||||
&& Player.PlayerStates.IsReady
|
||||
&& NetId.Value != uint.MaxValue
|
||||
&& NetId.Value != 0U;
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (!base.UpdateTransform())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override float DistanceLeeway => 10f;
|
||||
if (HasAuthority)
|
||||
{
|
||||
if (!AttachedObject.gameObject.activeInHierarchy)
|
||||
{
|
||||
var probeOWRigidbody = Locator.GetProbe().GetComponent<SurveyorProbe>().GetOWRigidbody();
|
||||
if (probeOWRigidbody == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Could not find OWRigidbody of local probe.", MessageType.Warning);
|
||||
}
|
||||
|
||||
public override bool UseInterpolation => true;
|
||||
var probeLauncher = Player.LocalProbeLauncher;
|
||||
// TODO : make this sync to the *active* probe launcher's _launcherTransform
|
||||
var launcherTransform = probeLauncher.GetValue<Transform>("_launcherTransform");
|
||||
probeOWRigidbody.SetPosition(launcherTransform.position);
|
||||
probeOWRigidbody.SetRotation(launcherTransform.rotation);
|
||||
|
||||
public override TargetType Type => TargetType.Probe;
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
|
||||
var currentReferenceSector = ReferenceSector;
|
||||
var playerReferenceSector = Player.TransformSync.ReferenceSector;
|
||||
|
||||
if (currentReferenceSector != playerReferenceSector)
|
||||
{
|
||||
SetReferenceSector(playerReferenceSector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsReady => Locator.GetProbe() != null;
|
||||
}
|
||||
}
|
@ -132,6 +132,8 @@
|
||||
<Compile Include="CampfireSync\Events\CampfireStateEvent.cs" />
|
||||
<Compile Include="CampfireSync\Patches\CampfirePatches.cs" />
|
||||
<Compile Include="CampfireSync\WorldObjects\QSBCampfire.cs" />
|
||||
<Compile Include="ClientServerStateSync\ClientStateManager.cs" />
|
||||
<Compile Include="ClientServerStateSync\Events\ClientStateEvent.cs" />
|
||||
<Compile Include="ConversationSync\Events\DialogueConditionEvent.cs" />
|
||||
<Compile Include="ConversationSync\Events\DialogueConditionMessage.cs" />
|
||||
<Compile Include="ConversationSync\Events\ConversationEvent.cs" />
|
||||
@ -141,8 +143,15 @@
|
||||
<Compile Include="ConversationSync\Events\ConversationStartEndMessage.cs" />
|
||||
<Compile Include="ConversationSync\ConversationType.cs" />
|
||||
<Compile Include="ConversationSync\ConversationManager.cs" />
|
||||
<Compile Include="DeathSync\EndLoopReason.cs" />
|
||||
<Compile Include="DeathSync\Events\EndLoopEvent.cs" />
|
||||
<Compile Include="DeathSync\Events\PlayerRespawnEvent.cs" />
|
||||
<Compile Include="DeathSync\Events\StartLoopEvent.cs" />
|
||||
<Compile Include="DeathSync\Patches\MapPatches.cs" />
|
||||
<Compile Include="DeathSync\Events\PlayerDeathMessage.cs" />
|
||||
<Compile Include="DeathSync\Patches\DeathPatches.cs" />
|
||||
<Compile Include="DeathSync\Patches\RespawnPatches.cs" />
|
||||
<Compile Include="DeathSync\RespawnManager.cs" />
|
||||
<Compile Include="ElevatorSync\WorldObjects\QSBElevator.cs" />
|
||||
<Compile Include="ElevatorSync\Events\ElevatorEvent.cs" />
|
||||
<Compile Include="ElevatorSync\ElevatorManager.cs" />
|
||||
@ -154,6 +163,7 @@
|
||||
<Compile Include="FrequencySync\Events\IdentifyFrequencyEvent.cs" />
|
||||
<Compile Include="FrequencySync\Events\IdentifySignalEvent.cs" />
|
||||
<Compile Include="FrequencySync\Patches\FrequencyPatches.cs" />
|
||||
<Compile Include="ClientServerStateSync\ClientState.cs" />
|
||||
<Compile Include="GeyserSync\Patches\GeyserPatches.cs" />
|
||||
<Compile Include="Inputs\Patches\InputPatches.cs" />
|
||||
<Compile Include="Instruments\QSBCamera\CameraController.cs" />
|
||||
@ -162,6 +172,9 @@
|
||||
<Compile Include="Instruments\InstrumentsManager.cs" />
|
||||
<Compile Include="Messaging\BoolMessage.cs" />
|
||||
<Compile Include="OrbSync\TransformSync\NomaiOrbTransformSync.cs" />
|
||||
<Compile Include="Player\Events\PlayerInformationEvent.cs" />
|
||||
<Compile Include="Player\Events\PlayerInformationMessage.cs" />
|
||||
<Compile Include="Player\Events\RequestStateResyncEvent.cs" />
|
||||
<Compile Include="Player\Patches\PlayerPatches.cs" />
|
||||
<Compile Include="Player\PlayerState.cs" />
|
||||
<Compile Include="PoolSync\CustomNomaiRemoteCameraPlatform.cs" />
|
||||
@ -201,7 +214,6 @@
|
||||
<Compile Include="Patches\QSBPatchManager.cs" />
|
||||
<Compile Include="Player\Events\PlayerEntangledEvent.cs" />
|
||||
<Compile Include="Player\Events\PlayerKickEvent.cs" />
|
||||
<Compile Include="Player\Events\ServerSendPlayerStatesEvent.cs" />
|
||||
<Compile Include="Player\KickReason.cs" />
|
||||
<Compile Include="Player\PlayerEntanglementWatcher.cs" />
|
||||
<Compile Include="Player\PlayerMapMarker.cs" />
|
||||
@ -209,6 +221,13 @@
|
||||
<Compile Include="PoolSync\Patches\PoolPatches.cs" />
|
||||
<Compile Include="PoolSync\PoolManager.cs" />
|
||||
<Compile Include="Inputs\QSBInputManager.cs" />
|
||||
<Compile Include="ProbeSync\Events\PlayerProbeEvent.cs" />
|
||||
<Compile Include="ProbeSync\Events\ProbeStartRetrieveEvent.cs" />
|
||||
<Compile Include="ProbeSync\ProbeEvent.cs" />
|
||||
<Compile Include="ProbeSync\ProbeListener.cs" />
|
||||
<Compile Include="ProbeSync\QSBProbeEffects.cs" />
|
||||
<Compile Include="ProbeSync\QSBProbeLantern.cs" />
|
||||
<Compile Include="ProbeSync\QSBProbeSpotlight.cs" />
|
||||
<Compile Include="QSBNetworkLobby.cs" />
|
||||
<Compile Include="Patches\QSBPatch.cs" />
|
||||
<Compile Include="Patches\QSBPatchTypes.cs" />
|
||||
@ -240,6 +259,9 @@
|
||||
<Compile Include="QuantumSync\Patches\QuantumVisibilityPatches.cs" />
|
||||
<Compile Include="QuantumSync\Patches\ServerQuantumPatches.cs" />
|
||||
<Compile Include="SectorSync\TargetType.cs" />
|
||||
<Compile Include="ClientServerStateSync\Events\ServerStateEvent.cs" />
|
||||
<Compile Include="ClientServerStateSync\ServerState.cs" />
|
||||
<Compile Include="ClientServerStateSync\ServerStateManager.cs" />
|
||||
<Compile Include="ShipSync\ComponentType.cs" />
|
||||
<Compile Include="ShipSync\Events\Component\ComponentDamagedEvent.cs" />
|
||||
<Compile Include="ShipSync\Events\Component\ComponentRepairedEvent.cs" />
|
||||
@ -257,10 +279,21 @@
|
||||
<Compile Include="ShipSync\WorldObjects\QSBShipComponent.cs" />
|
||||
<Compile Include="ShipSync\WorldObjects\QSBShipHull.cs" />
|
||||
<Compile Include="Syncs\ISectoredSync.cs" />
|
||||
<Compile Include="Syncs\ISync.cs" />
|
||||
<Compile Include="Syncs\RigidbodySync\UnparentedBaseRigidbodySync.cs" />
|
||||
<Compile Include="Syncs\RigidbodySync\SectoredRigidbodySync.cs" />
|
||||
<Compile Include="Syncs\SyncBase.cs" />
|
||||
<Compile Include="TimeSync\FastForwardReason.cs" />
|
||||
<Compile Include="TimeSync\Patches\TimePatches.cs" />
|
||||
<Compile Include="TimeSync\PauseReason.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\Events\LaunchProbeEvent.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\Events\PlayerLaunchProbeEvent.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\Events\PlayerRetrieveProbeEvent.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\Events\RetrieveProbeEvent.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\Patches\LauncherPatches.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\ProbeLauncherListener.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\ProbeLauncherManager.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\QSBProbeLauncherTool.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\WorldObjects\QSBProbeLauncher.cs" />
|
||||
<Compile Include="Utility\CustomRelativisticParticleSystem.cs" />
|
||||
<Compile Include="RoastingSync\QSBMarshmallow.cs" />
|
||||
<Compile Include="RoastingSync\Events\EnterExitRoastingEvent.cs" />
|
||||
@ -276,7 +309,6 @@
|
||||
<Compile Include="StatueSync\Events\StartStatueMessage.cs" />
|
||||
<Compile Include="StatueSync\Patches\StatuePatches.cs" />
|
||||
<Compile Include="StatueSync\StatueManager.cs" />
|
||||
<Compile Include="RoastingSync\TransformSync\RoastingStickTransformSync.cs" />
|
||||
<Compile Include="Syncs\TransformSync\BaseTransformSync.cs" />
|
||||
<Compile Include="Syncs\IntermediaryTransform.cs" />
|
||||
<Compile Include="Syncs\TransformSync\SectoredTransformSync.cs" />
|
||||
@ -293,15 +325,13 @@
|
||||
<Compile Include="TimeSync\TimeSyncUI.cs" />
|
||||
<Compile Include="Tools\Events\PlayerFlashlightEvent.cs" />
|
||||
<Compile Include="Player\Events\PlayerJoinEvent.cs" />
|
||||
<Compile Include="ProbeSync\Events\PlayerProbeEvent.cs" />
|
||||
<Compile Include="Player\Events\PlayerReadyEvent.cs" />
|
||||
<Compile Include="Player\Events\PlayerStatesRequestEvent.cs" />
|
||||
<Compile Include="Animation\Player\Events\PlayerSuitEvent.cs" />
|
||||
<Compile Include="TimeSync\Events\ServerTimeEvent.cs" />
|
||||
<Compile Include="GeyserSync\Events\GeyserEvent.cs" />
|
||||
<Compile Include="GeyserSync\GeyserManager.cs" />
|
||||
<Compile Include="GeyserSync\WorldObjects\QSBGeyser.cs" />
|
||||
<Compile Include="ProbeSync\Events\PlayerProbeLauncherEvent.cs" />
|
||||
<Compile Include="Tools\ProbeLauncherTool\Events\EquipProbeLauncherEvent.cs" />
|
||||
<Compile Include="Tools\Events\PlayerSignalscopeEvent.cs" />
|
||||
<Compile Include="Tools\Events\PlayerTranslatorEvent.cs" />
|
||||
<Compile Include="Events\QSBEvent.cs" />
|
||||
@ -341,7 +371,6 @@
|
||||
<Compile Include="ProbeSync\TransformSync\PlayerProbeSync.cs" />
|
||||
<Compile Include="Utility\DebugActions.cs" />
|
||||
<Compile Include="Events\QSBEventManager.cs" />
|
||||
<Compile Include="Player\Events\PlayerStateMessage.cs" />
|
||||
<Compile Include="DeathSync\Necronomicon.cs" />
|
||||
<Compile Include="Utility\DebugLog.cs" />
|
||||
<Compile Include="Messaging\PlayerMessage.cs" />
|
||||
@ -350,7 +379,6 @@
|
||||
<Compile Include="Player\PlayerInfo.cs" />
|
||||
<Compile Include="DeathSync\RespawnOnDeath.cs" />
|
||||
<Compile Include="Player\QSBPlayerManager.cs" />
|
||||
<Compile Include="Player\TransformSync\PlayerCameraSync.cs" />
|
||||
<Compile Include="Player\PlayerHUDMarker.cs" />
|
||||
<Compile Include="Tools\PlayerToolsManager.cs" />
|
||||
<Compile Include="Utility\QuaternionHelper.cs" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<GameDir>D:\EpicGames\OuterWilds</GameDir>
|
||||
<GameDir>E:\Epic\Epic Games\OuterWilds</GameDir>
|
||||
<OwmlDir>C:\Users\Henry\AppData\Roaming\OuterWildsModManager\OWML</OwmlDir>
|
||||
<ProjectView>ShowAllFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
|
@ -5,6 +5,7 @@ using OWML.Utils;
|
||||
using QSB.Animation.NPC;
|
||||
using QSB.CampfireSync;
|
||||
using QSB.ConversationSync;
|
||||
using QSB.DeathSync;
|
||||
using QSB.ElevatorSync;
|
||||
using QSB.GeyserSync;
|
||||
using QSB.Inputs;
|
||||
@ -19,6 +20,7 @@ using QSB.SectorSync;
|
||||
using QSB.ShipSync;
|
||||
using QSB.StatueSync;
|
||||
using QSB.TimeSync;
|
||||
using QSB.Tools.ProbeLauncherTool;
|
||||
using QSB.TranslationSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
@ -58,14 +60,12 @@ namespace QSB
|
||||
public static AssetBundle InstrumentAssetBundle { get; private set; }
|
||||
public static AssetBundle ConversationAssetBundle { get; private set; }
|
||||
public static bool WorldObjectsReady => WorldObjectManager.AllReady && IsInMultiplayer && PlayerTransformSync.LocalInstance != null;
|
||||
public static bool IsServer => QNetworkServer.active;
|
||||
public static bool IsHost => QNetworkServer.active;
|
||||
public static bool IsInMultiplayer => QNetworkManager.singleton.isNetworkActive;
|
||||
public static string QSBVersion => Helper.Manifest.Version;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Application.runInBackground = true;
|
||||
|
||||
var instance = TextTranslation.Get().GetValue<TextTranslation.TranslationTable>("m_table");
|
||||
instance.theUITable[(int)UITextType.PleaseUseController] =
|
||||
"<color=orange>Quantum Space Buddies</color> is best experienced with friends...";
|
||||
@ -91,6 +91,7 @@ namespace QSB
|
||||
gameObject.AddComponent<RepeatingManager>();
|
||||
gameObject.AddComponent<PlayerEntanglementWatcher>();
|
||||
gameObject.AddComponent<DebugGUI>();
|
||||
gameObject.AddComponent<RespawnManager>();
|
||||
|
||||
// WorldObject managers
|
||||
gameObject.AddComponent<QuantumManager>();
|
||||
@ -105,6 +106,7 @@ namespace QSB
|
||||
gameObject.AddComponent<CampfireManager>();
|
||||
gameObject.AddComponent<CharacterAnimManager>();
|
||||
gameObject.AddComponent<ShipManager>();
|
||||
gameObject.AddComponent<ProbeLauncherManager>();
|
||||
|
||||
DebugBoxManager.Init();
|
||||
|
||||
@ -112,6 +114,25 @@ namespace QSB
|
||||
|
||||
// Stop players being able to pause
|
||||
Helper.HarmonyHelper.EmptyMethod(typeof(OWTime).GetMethod("Pause"));
|
||||
|
||||
QSBPatchManager.OnPatchType += OnPatchType;
|
||||
QSBPatchManager.OnUnpatchType += OnUnpatchType;
|
||||
}
|
||||
|
||||
private void OnPatchType(QSBPatchTypes type)
|
||||
{
|
||||
if (type == QSBPatchTypes.OnClientConnect)
|
||||
{
|
||||
Application.runInBackground = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnpatchType(QSBPatchTypes type)
|
||||
{
|
||||
if (type == QSBPatchTypes.OnClientConnect)
|
||||
{
|
||||
Application.runInBackground = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update() =>
|
||||
@ -154,4 +175,6 @@ namespace QSB
|
||||
* Jake Chudnow
|
||||
* Murray Gold
|
||||
* Teleskärm
|
||||
* Daft Punk
|
||||
* Natalie Holt
|
||||
*/
|
@ -2,6 +2,7 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Animation.Player.Thrusters;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.DeathSync;
|
||||
using QSB.Events;
|
||||
using QSB.Instruments;
|
||||
@ -11,7 +12,6 @@ using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.PoolSync;
|
||||
using QSB.ProbeSync.TransformSync;
|
||||
using QSB.RoastingSync.TransformSync;
|
||||
using QSB.ShipSync.TransformSync;
|
||||
using QSB.TimeSync;
|
||||
using QSB.Utility;
|
||||
@ -40,9 +40,7 @@ namespace QSB
|
||||
|
||||
private QSBNetworkLobby _lobby;
|
||||
private AssetBundle _assetBundle;
|
||||
private GameObject _cameraPrefab;
|
||||
private GameObject _probePrefab;
|
||||
private GameObject _stickPrefab;
|
||||
private bool _everConnected;
|
||||
|
||||
public new void Awake()
|
||||
@ -53,7 +51,7 @@ namespace QSB
|
||||
_lobby = gameObject.AddComponent<QSBNetworkLobby>();
|
||||
_assetBundle = QSBCore.NetworkAssetBundle;
|
||||
|
||||
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkplayer.prefab");
|
||||
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/NETWORK_Player_Body.prefab");
|
||||
SetupNetworkId(playerPrefab);
|
||||
SetupNetworkTransform(playerPrefab);
|
||||
playerPrefab.AddComponent<PlayerTransformSync>();
|
||||
@ -63,15 +61,9 @@ namespace QSB
|
||||
playerPrefab.AddComponent<JetpackAccelerationSync>();
|
||||
playerPrefab.AddComponent<InstrumentsManager>();
|
||||
|
||||
_cameraPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkcameraroot.prefab");
|
||||
SetupNetworkId(_cameraPrefab);
|
||||
SetupNetworkTransform(_cameraPrefab);
|
||||
_cameraPrefab.AddComponent<PlayerCameraSync>();
|
||||
spawnPrefabs.Add(_cameraPrefab);
|
||||
|
||||
ShipPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkship.prefab");
|
||||
SetupNetworkId(ShipPrefab);
|
||||
SetupNetworkTransform(_cameraPrefab);
|
||||
SetupNetworkTransform(ShipPrefab);
|
||||
ShipPrefab.AddComponent<ShipTransformSync>();
|
||||
spawnPrefabs.Add(ShipPrefab);
|
||||
|
||||
@ -87,12 +79,6 @@ namespace QSB
|
||||
OrbPrefab.AddComponent<NomaiOrbTransformSync>();
|
||||
spawnPrefabs.Add(OrbPrefab);
|
||||
|
||||
_stickPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkstickpivot.prefab");
|
||||
SetupNetworkId(_stickPrefab);
|
||||
SetupNetworkTransform(_stickPrefab);
|
||||
_stickPrefab.AddComponent<RoastingStickTransformSync>();
|
||||
spawnPrefabs.Add(_stickPrefab);
|
||||
|
||||
ConfigureNetworkManager();
|
||||
}
|
||||
|
||||
@ -110,6 +96,7 @@ namespace QSB
|
||||
{
|
||||
var child = go.AddComponent<QNetworkTransformChild>();
|
||||
child.Target = item.target;
|
||||
child.m_ChildIndex = item.childIndex;
|
||||
Destroy(item);
|
||||
}
|
||||
|
||||
@ -146,9 +133,7 @@ namespace QSB
|
||||
DebugLog.DebugWrite($"OnServerAddPlayer {playerControllerId}", MessageType.Info);
|
||||
base.OnServerAddPlayer(connection, playerControllerId);
|
||||
|
||||
QNetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
|
||||
QNetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
|
||||
QNetworkServer.SpawnWithClientAuthority(Instantiate(_stickPrefab), connection);
|
||||
}
|
||||
|
||||
public override void OnStartClient(QNetworkClient _)
|
||||
@ -167,6 +152,8 @@ namespace QSB
|
||||
QSBEventManager.Init();
|
||||
|
||||
gameObject.AddComponent<RespawnOnDeath>();
|
||||
gameObject.AddComponent<ServerStateManager>();
|
||||
gameObject.AddComponent<ClientStateManager>();
|
||||
|
||||
if (QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
@ -185,10 +172,10 @@ namespace QSB
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBEventManager.Ready && PlayerTransformSync.LocalInstance != null,
|
||||
() => QSBEventManager.FireEvent(EventNames.QSBPlayerJoin, _lobby.PlayerName));
|
||||
|
||||
if (!QSBCore.IsServer)
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBEventManager.Ready && PlayerTransformSync.LocalInstance != null,
|
||||
() => QSBEventManager.FireEvent(EventNames.QSBPlayerStatesRequest));
|
||||
() => QSBEventManager.FireEvent(EventNames.QSBRequestStateResync));
|
||||
}
|
||||
|
||||
_everConnected = true;
|
||||
@ -199,6 +186,8 @@ namespace QSB
|
||||
DebugLog.DebugWrite("OnStopClient", MessageType.Info);
|
||||
DebugLog.ToConsole("Disconnecting from server...", MessageType.Info);
|
||||
Destroy(GetComponent<RespawnOnDeath>());
|
||||
Destroy(GetComponent<ServerStateManager>());
|
||||
Destroy(GetComponent<ClientStateManager>());
|
||||
QSBEventManager.Reset();
|
||||
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
|
||||
|
||||
@ -263,6 +252,8 @@ namespace QSB
|
||||
{
|
||||
Destroy(streaming);
|
||||
}
|
||||
|
||||
WorldObjectManager.SetNotReady();
|
||||
}
|
||||
}
|
||||
}
|
@ -11,8 +11,8 @@ namespace QSB
|
||||
|
||||
public static bool IsInUniverse => InUniverse(CurrentScene);
|
||||
|
||||
public static event Action<OWScene, bool> OnSceneLoaded;
|
||||
public static event Action<OWScene> OnUniverseSceneLoaded;
|
||||
public static event Action<OWScene, OWScene, bool> OnSceneLoaded;
|
||||
public static event Action<OWScene, OWScene> OnUniverseSceneLoaded;
|
||||
|
||||
static QSBSceneManager()
|
||||
{
|
||||
@ -30,10 +30,10 @@ namespace QSB
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() => WorldObjectManager.Rebuild(newScene));
|
||||
}
|
||||
|
||||
OnSceneLoaded?.SafeInvoke(newScene, universe);
|
||||
OnSceneLoaded?.SafeInvoke(oldScene, newScene, universe);
|
||||
if (universe)
|
||||
{
|
||||
OnUniverseSceneLoaded?.SafeInvoke(newScene);
|
||||
OnUniverseSceneLoaded?.SafeInvoke(oldScene, newScene);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
@ -22,10 +22,10 @@ namespace QSB.QuantumSync.Patches
|
||||
}
|
||||
|
||||
public static void Shape_OnEnable(Shape __instance)
|
||||
=> QSBWorldSync.RaiseEvent(__instance, "OnShapeActivated", __instance);
|
||||
=> __instance.RaiseEvent("OnShapeActivated", __instance);
|
||||
|
||||
public static void Shape_OnDisable(Shape __instance)
|
||||
=> QSBWorldSync.RaiseEvent(__instance, "OnShapeDeactivated", __instance);
|
||||
=> __instance.RaiseEvent("OnShapeDeactivated", __instance);
|
||||
|
||||
// ShapeVisibilityTracker patches
|
||||
|
||||
|
@ -47,7 +47,7 @@ namespace QSB.QuantumSync
|
||||
|
||||
public void PlayerLeave(uint playerId)
|
||||
{
|
||||
if (!QSBCore.IsServer)
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -79,16 +79,21 @@ namespace QSB.QuantumSync
|
||||
|
||||
public static Tuple<bool, List<PlayerInfo>> IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
|
||||
{
|
||||
if (!AllReady)
|
||||
{
|
||||
return new Tuple<bool, List<PlayerInfo>>(false, new List<PlayerInfo>());
|
||||
}
|
||||
|
||||
var playersWithCameras = QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera);
|
||||
if (playersWithCameras.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Trying to run IsVisibleUsingCameraFrustum when there are no players!", MessageType.Warning);
|
||||
return new Tuple<bool, List<PlayerInfo>>(false, null);
|
||||
return new Tuple<bool, List<PlayerInfo>>(false, new List<PlayerInfo>());
|
||||
}
|
||||
|
||||
if (!tracker.gameObject.activeInHierarchy)
|
||||
{
|
||||
return new Tuple<bool, List<PlayerInfo>>(false, null);
|
||||
return new Tuple<bool, List<PlayerInfo>>(false, new List<PlayerInfo>());
|
||||
}
|
||||
|
||||
var frustumMethod = tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
@ -114,13 +119,10 @@ namespace QSB.QuantumSync
|
||||
return new Tuple<bool, List<PlayerInfo>>(foundPlayers, playersWhoCanSee);
|
||||
}
|
||||
|
||||
public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
|
||||
{
|
||||
return tracker.gameObject.activeInHierarchy
|
||||
public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera) => tracker.gameObject.activeInHierarchy
|
||||
&& IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera).First
|
||||
&& QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera)
|
||||
.Any(x => VisibilityOccluder.CanYouSee(tracker, x.Camera.mainCamera.transform.position));
|
||||
}
|
||||
|
||||
public static IEnumerable<PlayerInfo> GetEntangledPlayers(QuantumObject obj)
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
private void OnEnable(Shape s)
|
||||
{
|
||||
IsEnabled = true;
|
||||
if (!QSBCore.WorldObjectsReady && !QSBCore.IsServer)
|
||||
if (!QSBCore.WorldObjectsReady && !QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -116,7 +116,7 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
}
|
||||
|
||||
IsEnabled = false;
|
||||
if (!QSBCore.WorldObjectsReady && !QSBCore.IsServer)
|
||||
if (!QSBCore.WorldObjectsReady && !QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ namespace QSB.RoastingSync.Events
|
||||
var rigidbody = tossedMallow.GetComponent<OWRigidbody>();
|
||||
if (player.Campfire == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - Campfire for {playerId} is null.", OWML.Common.MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - Campfire for {playerId} is null.", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ namespace QSB.RoastingSync.Events
|
||||
rigidbody.SetAngularVelocity(stickTip.right * 10f);
|
||||
if (player.Marshmallow == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - Marshmallow for {playerId} is null.", OWML.Common.MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - Marshmallow for {playerId} is null.", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Player;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.TransformSync;
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.RoastingSync.TransformSync
|
||||
{
|
||||
internal class RoastingStickTransformSync : SectoredTransformSync
|
||||
{
|
||||
private Transform _stickTip;
|
||||
private Transform _networkStickTip => gameObject.transform.GetChild(0);
|
||||
private const float SmoothTime = 0.1f;
|
||||
private Vector3 _positionSmoothVelocity;
|
||||
private Quaternion _rotationSmoothVelocity;
|
||||
|
||||
private Transform GetPivot()
|
||||
=> Resources.FindObjectsOfTypeAll<RoastingStickController>().First().transform.Find("Stick_Root/Stick_Pivot");
|
||||
|
||||
protected override Transform InitLocalTransform()
|
||||
{
|
||||
var pivot = GetPivot();
|
||||
Player.RoastingStick = pivot.gameObject;
|
||||
_stickTip = pivot.Find("Stick_Tip");
|
||||
return pivot;
|
||||
}
|
||||
|
||||
protected override Transform InitRemoteTransform()
|
||||
{
|
||||
var newPivot = Instantiate(GetPivot());
|
||||
newPivot.parent = null;
|
||||
newPivot.gameObject.SetActive(false);
|
||||
Destroy(newPivot.Find("Stick_Tip/Props_HEA_RoastingStick/RoastingStick_Arm").gameObject);
|
||||
Destroy(newPivot.Find("Stick_Tip/Props_HEA_RoastingStick/RoastingStick_Arm_NoSuit").gameObject);
|
||||
var mallowRoot = newPivot.Find("Stick_Tip/Mallow_Root");
|
||||
mallowRoot.gameObject.SetActive(false);
|
||||
var oldMarshmallow = mallowRoot.GetComponent<Marshmallow>();
|
||||
|
||||
// Recreate particle system
|
||||
Destroy(mallowRoot.Find("MallowSmoke").GetComponent<RelativisticParticleSystem>());
|
||||
var newSystem = mallowRoot.Find("MallowSmoke").gameObject.AddComponent<CustomRelativisticParticleSystem>();
|
||||
newSystem.Init(Player);
|
||||
|
||||
// Create new marshmallow
|
||||
var newMarshmallow = mallowRoot.gameObject.AddComponent<QSBMarshmallow>();
|
||||
newMarshmallow._fireRenderer = oldMarshmallow.GetValue<MeshRenderer>("_fireRenderer");
|
||||
newMarshmallow._smokeParticles = oldMarshmallow.GetValue<ParticleSystem>("_smokeParticles");
|
||||
newMarshmallow._mallowRenderer = oldMarshmallow.GetValue<MeshRenderer>("_mallowRenderer");
|
||||
newMarshmallow._rawColor = oldMarshmallow.GetValue<Color>("_rawColor");
|
||||
newMarshmallow._toastedColor = oldMarshmallow.GetValue<Color>("_toastedColor");
|
||||
newMarshmallow._burntColor = oldMarshmallow.GetValue<Color>("_burntColor");
|
||||
Destroy(oldMarshmallow);
|
||||
|
||||
Player.RoastingStick = newPivot.gameObject;
|
||||
Player.Marshmallow = newMarshmallow;
|
||||
mallowRoot.gameObject.SetActive(true);
|
||||
_stickTip = newPivot.Find("Stick_Tip");
|
||||
return newPivot;
|
||||
}
|
||||
|
||||
protected override void UpdateTransform()
|
||||
{
|
||||
base.UpdateTransform();
|
||||
if (_stickTip == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - _stickTip is null for player {PlayerId}", OWML.Common.MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
_networkStickTip.localPosition = _stickTip.localPosition;
|
||||
_networkStickTip.localRotation = _stickTip.localRotation;
|
||||
return;
|
||||
}
|
||||
|
||||
_stickTip.localPosition = Vector3.SmoothDamp(_stickTip.localPosition, _networkStickTip.localPosition, ref _positionSmoothVelocity, SmoothTime);
|
||||
_stickTip.localRotation = QuaternionHelper.SmoothDamp(_stickTip.localRotation, _networkStickTip.localRotation, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
|
||||
public override bool IsReady => Locator.GetPlayerTransform() != null
|
||||
&& Player != null
|
||||
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
|
||||
&& Player.PlayerStates.IsReady
|
||||
&& NetId.Value != uint.MaxValue
|
||||
&& NetId.Value != 0U;
|
||||
|
||||
public override bool UseInterpolation => true;
|
||||
|
||||
public override TargetType Type => TargetType.RoastingStick;
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Syncs;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -19,11 +18,16 @@ namespace QSB.SectorSync
|
||||
private void OnEnable() => RepeatingManager.Repeatings.Add(this);
|
||||
private void OnDisable() => RepeatingManager.Repeatings.Remove(this);
|
||||
|
||||
public List<ISectoredSync<Transform>> SectoredTransformSyncs = new List<ISectoredSync<Transform>>();
|
||||
public List<ISectoredSync<OWRigidbody>> SectoredRigidbodySyncs = new List<ISectoredSync<OWRigidbody>>();
|
||||
public List<SyncBase> SectoredTransformSyncs = new List<SyncBase>();
|
||||
public List<SyncBase> SectoredRigidbodySyncs = new List<SyncBase>();
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
if (!Instance.IsReady || !AllReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var sync in SectoredTransformSyncs)
|
||||
{
|
||||
if (sync.AttachedObject == null)
|
||||
@ -31,11 +35,11 @@ namespace QSB.SectorSync
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((sync as QNetworkBehaviour).HasAuthority
|
||||
if (sync.HasAuthority
|
||||
&& sync.AttachedObject.gameObject.activeInHierarchy
|
||||
&& sync.IsReady)
|
||||
{
|
||||
CheckTransformSyncSector(sync);
|
||||
CheckTransformSyncSector(sync as ISectoredSync<Transform>);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,11 +50,11 @@ namespace QSB.SectorSync
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((sync as QNetworkBehaviour).HasAuthority
|
||||
if (sync.HasAuthority
|
||||
&& sync.AttachedObject.gameObject.activeInHierarchy
|
||||
&& sync.IsReady)
|
||||
{
|
||||
CheckTransformSyncSector(sync);
|
||||
CheckTransformSyncSector(sync as ISectoredSync<OWRigidbody>);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,7 +92,7 @@ namespace QSB.SectorSync
|
||||
private void CheckTransformSyncSector<T>(ISectoredSync<T> transformSync)
|
||||
where T : Component
|
||||
{
|
||||
var attachedObject = transformSync.AttachedObject;
|
||||
var attachedObject = (transformSync as SyncBase).AttachedObject;
|
||||
var closestSector = transformSync.SectorSync.GetClosestSector(attachedObject.transform);
|
||||
if (closestSector == default(QSBSector))
|
||||
{
|
||||
|
@ -17,6 +17,7 @@ namespace QSB.SectorSync
|
||||
private OWRigidbody _attachedOWRigidbody;
|
||||
private SectorDetector _sectorDetector;
|
||||
private TargetType _targetType;
|
||||
private bool _isReady;
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
@ -25,6 +26,7 @@ namespace QSB.SectorSync
|
||||
_sectorDetector.OnEnterSector -= AddSector;
|
||||
_sectorDetector.OnExitSector -= RemoveSector;
|
||||
}
|
||||
_isReady = false;
|
||||
}
|
||||
|
||||
public void Init<T>(SectorDetector detector, ISectoredSync<T> sectoredSync)
|
||||
@ -35,6 +37,12 @@ namespace QSB.SectorSync
|
||||
_sectorDetector.OnExitSector -= RemoveSector;
|
||||
}
|
||||
|
||||
if (detector == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to init SectorSync with null SectorDetector.", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
_sectorDetector = detector;
|
||||
_sectorDetector.OnEnterSector += AddSector;
|
||||
_sectorDetector.OnExitSector += RemoveSector;
|
||||
@ -45,7 +53,26 @@ namespace QSB.SectorSync
|
||||
DebugLog.ToConsole($"Warning - OWRigidbody for {_sectorDetector.name} is null!", MessageType.Warning);
|
||||
}
|
||||
|
||||
PopulateSectorList();
|
||||
|
||||
_targetType = sectoredSync.Type;
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
private void PopulateSectorList()
|
||||
{
|
||||
var currentList = _sectorDetector.GetValue<List<Sector>>("_sectorList");
|
||||
|
||||
SectorList.Clear();
|
||||
foreach (var sector in currentList)
|
||||
{
|
||||
if (sector == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AddSector(sector);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSector(Sector sector)
|
||||
@ -85,9 +112,21 @@ namespace QSB.SectorSync
|
||||
|
||||
public QSBSector GetClosestSector(Transform trans) // trans rights \o/
|
||||
{
|
||||
if (!QSBSectorManager.Instance.IsReady)
|
||||
if (QSBSectorManager.Instance == null || !QSBSectorManager.Instance.IsReady)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to get closest sector to {trans.name} before QSBSectorManager was ready.", MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_isReady)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to use GetClosestSector before it was initialized. Transform:{trans.name}", MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_sectorDetector == null || _attachedOWRigidbody == null || _targetType == TargetType.None)
|
||||
{
|
||||
_isReady = false;
|
||||
DebugLog.ToConsole($"Error - SectorSync is no longer ready. Detector Null : {_sectorDetector == null}, OWRigidbody Null : {_attachedOWRigidbody == null}, None TargetType : {_targetType == TargetType.None}", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,7 @@
|
||||
None = 0,
|
||||
Player = 1,
|
||||
Probe = 2,
|
||||
PlayerCamera = 3,
|
||||
RoastingStick = 4,
|
||||
Ship = 5,
|
||||
Other = 6
|
||||
Ship = 3,
|
||||
Other = 4
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
using QSB.Events;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync.Events;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
|
||||
namespace QSB.ShipSync.Events.Component
|
||||
{
|
||||
class ComponentDamagedEvent : QSBEvent<WorldObjectMessage>
|
||||
internal class ComponentDamagedEvent : QSBEvent<WorldObjectMessage>
|
||||
{
|
||||
public override EventType Type => EventType.ComponentDamaged;
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
using QSB.Events;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.ShipSync.Events.Component
|
||||
{
|
||||
class ComponentRepairTickEvent : QSBEvent<RepairTickMessage>
|
||||
internal class ComponentRepairTickEvent : QSBEvent<RepairTickMessage>
|
||||
{
|
||||
public override EventType Type => EventType.ComponentRepairTick;
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
using QSB.Events;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync.Events;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
|
||||
namespace QSB.ShipSync.Events.Component
|
||||
{
|
||||
class ComponentRepairedEvent : QSBEvent<WorldObjectMessage>
|
||||
internal class ComponentRepairedEvent : QSBEvent<WorldObjectMessage>
|
||||
{
|
||||
public override EventType Type => EventType.ComponentRepaired;
|
||||
|
||||
|
@ -57,7 +57,7 @@ namespace QSB.ShipSync.Events
|
||||
? id
|
||||
: uint.MaxValue;
|
||||
|
||||
if (QSBCore.IsServer)
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
var newAuthority = ShipManager.Instance.CurrentFlyer == uint.MaxValue
|
||||
? QNetworkServer.connections.First(x => x.GetPlayerId() == QSBPlayerManager.LocalPlayerId)
|
||||
|
@ -3,7 +3,7 @@ using QSB.Messaging;
|
||||
|
||||
namespace QSB.ShipSync.Events
|
||||
{
|
||||
class FunnelEnableEvent : QSBEvent<PlayerMessage>
|
||||
internal class FunnelEnableEvent : QSBEvent<PlayerMessage>
|
||||
{
|
||||
public override EventType Type => EventType.EnableFunnel;
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
using QSB.Events;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.ShipSync.Events.Hull
|
||||
{
|
||||
class HullChangeIntegrityEvent : QSBEvent<HullChangeIntegrityMessage>
|
||||
internal class HullChangeIntegrityEvent : QSBEvent<HullChangeIntegrityMessage>
|
||||
{
|
||||
public override EventType Type => EventType.HullChangeIntegrity;
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
using QSB.Events;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
|
||||
namespace QSB.ShipSync.Events.Hull
|
||||
{
|
||||
class HullDamagedEvent : QSBEvent<WorldObjectMessage>
|
||||
internal class HullDamagedEvent : QSBEvent<WorldObjectMessage>
|
||||
{
|
||||
public override EventType Type => EventType.HullDamaged;
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
using QSB.Events;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.ShipSync.Events.Hull
|
||||
{
|
||||
class HullImpactEvent : QSBEvent<HullImpactMessage>
|
||||
internal class HullImpactEvent : QSBEvent<HullImpactMessage>
|
||||
{
|
||||
public override EventType Type => EventType.HullImpact;
|
||||
|
||||
|
@ -4,7 +4,7 @@ using QSB.WorldSync;
|
||||
|
||||
namespace QSB.ShipSync.Events.Hull
|
||||
{
|
||||
class HullRepairTickEvent : QSBEvent<RepairTickMessage>
|
||||
internal class HullRepairTickEvent : QSBEvent<RepairTickMessage>
|
||||
{
|
||||
public override EventType Type => EventType.HullRepairTick;
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
using QSB.Events;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync.Events;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
|
||||
namespace QSB.ShipSync.Events.Hull
|
||||
{
|
||||
class HullRepairedEvent : QSBEvent<WorldObjectMessage>
|
||||
internal class HullRepairedEvent : QSBEvent<WorldObjectMessage>
|
||||
{
|
||||
public override EventType Type => EventType.HullRepaired;
|
||||
|
||||
|
@ -3,7 +3,7 @@ using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.ShipSync.Events
|
||||
{
|
||||
class RepairTickMessage : WorldObjectMessage
|
||||
internal class RepairTickMessage : WorldObjectMessage
|
||||
{
|
||||
public float RepairNumber { get; set; }
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ShipSync.Patches
|
||||
@ -116,7 +115,7 @@ namespace QSB.ShipSync.Patches
|
||||
____damaged = true;
|
||||
____repairFraction = 0f;
|
||||
__instance.GetType().GetAnyMethod("OnComponentDamaged").Invoke(__instance, null);
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnDamaged", __instance);
|
||||
__instance.RaiseEvent("OnDamaged", __instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBComponentDamaged, __instance);
|
||||
}
|
||||
else
|
||||
@ -124,7 +123,7 @@ namespace QSB.ShipSync.Patches
|
||||
____damaged = false;
|
||||
____repairFraction = 1f;
|
||||
__instance.GetType().GetAnyMethod("OnComponentRepaired").Invoke(__instance, null);
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnRepaired", __instance);
|
||||
__instance.RaiseEvent("OnRepaired", __instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBComponentRepaired, __instance);
|
||||
}
|
||||
|
||||
@ -154,7 +153,7 @@ namespace QSB.ShipSync.Patches
|
||||
if (!____damaged)
|
||||
{
|
||||
____damaged = true;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnDamaged", __instance);
|
||||
__instance.RaiseEvent("OnDamaged", __instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBHullDamaged, __instance);
|
||||
}
|
||||
|
||||
@ -177,7 +176,7 @@ namespace QSB.ShipSync.Patches
|
||||
}
|
||||
}
|
||||
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnImpact", ____dominantImpact, damage);
|
||||
__instance.RaiseEvent("OnImpact", ____dominantImpact, damage);
|
||||
QSBEventManager.FireEvent(EventNames.QSBHullImpact, __instance, ____dominantImpact, damage);
|
||||
|
||||
____dominantImpact = null;
|
||||
@ -187,7 +186,7 @@ namespace QSB.ShipSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ShipDamageController_OnImpact()
|
||||
public static bool ShipDamageController_OnImpact()
|
||||
=> ShipManager.Instance.HasAuthority;
|
||||
|
||||
public static void ShipComponent_RepairTick(ShipComponent __instance, float ____repairFraction)
|
||||
@ -209,7 +208,7 @@ namespace QSB.ShipSync.Patches
|
||||
if (____integrity >= 1f)
|
||||
{
|
||||
____damaged = false;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnRepaired", __instance);
|
||||
__instance.RaiseEvent("OnRepaired", __instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBHullRepaired, __instance);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -48,7 +47,19 @@ namespace QSB.ShipSync
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
var shipTransform = GameObject.Find("Ship_Body");
|
||||
if (shipTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Couldn't find ship!", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
HatchController = shipTransform.GetComponentInChildren<HatchController>();
|
||||
if (HatchController == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Couldn't find hatch controller!", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
HatchInteractZone = HatchController.GetComponent<InteractZone>();
|
||||
ShipTractorBeam = Resources.FindObjectsOfTypeAll<ShipTractorBeamSwitch>().First();
|
||||
CockpitController = Resources.FindObjectsOfTypeAll<ShipCockpitController>().First();
|
||||
@ -58,14 +69,23 @@ namespace QSB.ShipSync
|
||||
sphereShape.radius = 2.5f;
|
||||
sphereShape.center = new Vector3(0, 0, 1);
|
||||
|
||||
if (QSBCore.IsServer)
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
if (ShipTransformSync.LocalInstance != null)
|
||||
{
|
||||
if (ShipTransformSync.LocalInstance.gameObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - ShipTransformSync's LocalInstance is not null, but it's gameobject is null!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
QNetworkServer.Destroy(ShipTransformSync.LocalInstance.gameObject);
|
||||
}
|
||||
|
||||
QNetworkServer.Spawn(Instantiate(QSBNetworkManager.Instance.ShipPrefab));
|
||||
if (QSBPlayerManager.LocalPlayer.TransformSync == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Tried to spawn ship, but LocalPlayer's TransformSync is null!", MessageType.Error);
|
||||
}
|
||||
QNetworkServer.SpawnWithClientAuthority(Instantiate(QSBNetworkManager.Instance.ShipPrefab), QSBPlayerManager.LocalPlayer.TransformSync.gameObject);
|
||||
}
|
||||
|
||||
QSBWorldSync.Init<QSBShipComponent, ShipComponent>();
|
||||
|
@ -2,6 +2,8 @@ using QSB.Player;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.RigidbodySync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ShipSync.TransformSync
|
||||
{
|
||||
@ -14,32 +16,34 @@ namespace QSB.ShipSync.TransformSync
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
DebugLog.DebugWrite($"START!");
|
||||
base.Start();
|
||||
LocalInstance = this;
|
||||
}
|
||||
|
||||
protected override Component InitLocalTransform() => throw new System.NotImplementedException();
|
||||
protected override Component InitRemoteTransform() => throw new System.NotImplementedException();
|
||||
|
||||
protected override OWRigidbody GetRigidbody()
|
||||
{
|
||||
SectorSync.Init(Locator.GetShipDetector().GetComponent<SectorDetector>(), this);
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetShipDetector().GetComponent<SectorDetector>(), this));
|
||||
return Locator.GetShipBody();
|
||||
}
|
||||
|
||||
protected override void UpdateTransform()
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority && ShipManager.Instance.CurrentFlyer != QSBPlayerManager.LocalPlayerId && ShipManager.Instance.CurrentFlyer != uint.MaxValue)
|
||||
{
|
||||
DebugLog.ToConsole("Warning - Has authority, but is not current flyer!", OWML.Common.MessageType.Warning);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasAuthority && ShipManager.Instance.CurrentFlyer == QSBPlayerManager.LocalPlayerId)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Doesn't have authority, but is current flyer!", OWML.Common.MessageType.Warning);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
base.UpdateTransform();
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
public override TargetType Type => TargetType.Ship;
|
||||
|
@ -4,7 +4,7 @@ using QSB.WorldSync;
|
||||
|
||||
namespace QSB.ShipSync.WorldObjects
|
||||
{
|
||||
class QSBShipComponent : WorldObject<ShipComponent>
|
||||
internal class QSBShipComponent : WorldObject<ShipComponent>
|
||||
{
|
||||
public override void Init(ShipComponent component, int id)
|
||||
{
|
||||
@ -18,7 +18,7 @@ namespace QSB.ShipSync.WorldObjects
|
||||
AttachedObject.SetValue("_damaged", true);
|
||||
AttachedObject.SetValue("_repairFraction", 0f);
|
||||
AttachedObject.GetType().GetAnyMethod("OnComponentDamaged").Invoke(AttachedObject, null);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnDamaged", AttachedObject);
|
||||
AttachedObject.RaiseEvent("OnDamaged", AttachedObject);
|
||||
AttachedObject.GetType().GetAnyMethod("UpdateColliderState").Invoke(AttachedObject, null);
|
||||
var damageEffect = AttachedObject.GetValue<DamageEffect>("_damageEffect");
|
||||
damageEffect.SetEffectBlend(1f);
|
||||
@ -30,7 +30,7 @@ namespace QSB.ShipSync.WorldObjects
|
||||
AttachedObject.SetValue("_damaged", false);
|
||||
AttachedObject.SetValue("_repairFraction", 1f);
|
||||
AttachedObject.GetType().GetAnyMethod("OnComponentRepaired").Invoke(AttachedObject, null);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnRepaired", AttachedObject);
|
||||
AttachedObject.RaiseEvent("OnRepaired", AttachedObject);
|
||||
AttachedObject.GetType().GetAnyMethod("UpdateColliderState").Invoke(AttachedObject, null);
|
||||
var damageEffect = AttachedObject.GetValue<DamageEffect>("_damageEffect");
|
||||
damageEffect.SetEffectBlend(0f);
|
||||
|
@ -4,7 +4,7 @@ using QSB.WorldSync;
|
||||
|
||||
namespace QSB.ShipSync.WorldObjects
|
||||
{
|
||||
class QSBShipHull : WorldObject<ShipHull>
|
||||
internal class QSBShipHull : WorldObject<ShipHull>
|
||||
{
|
||||
public override void Init(ShipHull hull, int id)
|
||||
{
|
||||
@ -16,14 +16,14 @@ namespace QSB.ShipSync.WorldObjects
|
||||
{
|
||||
DebugLog.DebugWrite($"[HULL] {AttachedObject} Set damaged.");
|
||||
AttachedObject.SetValue("_damaged", true);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnDamaged", AttachedObject);
|
||||
AttachedObject.RaiseEvent("OnDamaged", AttachedObject);
|
||||
}
|
||||
|
||||
public void SetRepaired()
|
||||
{
|
||||
DebugLog.DebugWrite($"[HULL] {AttachedObject} Set repaired.");
|
||||
AttachedObject.SetValue("_damaged", false);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnRepaired", AttachedObject);
|
||||
AttachedObject.RaiseEvent("OnRepaired", AttachedObject);
|
||||
var damageEffect = AttachedObject.GetValue<DamageEffect>("_damageEffect");
|
||||
damageEffect.SetEffectBlend(0f);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using QSB.Events;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.StatueSync.Events
|
||||
@ -24,6 +25,15 @@ namespace QSB.StatueSync.Events
|
||||
CameraDegrees = degrees
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, StartStatueMessage message)
|
||||
{
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InStatueCutscene);
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote(bool server, StartStatueMessage message)
|
||||
=> StatueManager.Instance.BeginSequence(message.PlayerPosition, message.PlayerRotation, message.CameraDegrees);
|
||||
}
|
||||
|
@ -12,11 +12,11 @@ namespace QSB.StatueSync
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
QSBSceneManager.OnUniverseSceneLoaded += (OWScene scene) => QSBPlayerManager.ShowAllPlayers();
|
||||
QSBSceneManager.OnUniverseSceneLoaded += (OWScene oldScene, OWScene newScene) => QSBPlayerManager.ShowAllPlayers();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
=> QSBSceneManager.OnUniverseSceneLoaded -= (OWScene scene) => QSBPlayerManager.ShowAllPlayers();
|
||||
=> QSBSceneManager.OnUniverseSceneLoaded -= (OWScene oldScene, OWScene newScene) => QSBPlayerManager.ShowAllPlayers();
|
||||
|
||||
public void BeginSequence(Vector3 position, Quaternion rotation, float cameraDegrees)
|
||||
=> StartCoroutine(BeginRemoteUplinkSequence(position, rotation, cameraDegrees));
|
||||
|
@ -3,7 +3,7 @@ using QSB.SectorSync.WorldObjects;
|
||||
|
||||
namespace QSB.Syncs
|
||||
{
|
||||
public interface ISectoredSync<T> : ISync<T>
|
||||
public interface ISectoredSync<T>
|
||||
{
|
||||
SectorSync.SectorSync SectorSync { get; }
|
||||
QSBSector ReferenceSector { get; }
|
||||
|
@ -1,13 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs
|
||||
{
|
||||
public interface ISync<T>
|
||||
{
|
||||
Transform ReferenceTransform { get; }
|
||||
T AttachedObject { get; }
|
||||
|
||||
bool IsReady { get; }
|
||||
bool UseInterpolation { get; }
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using OWML.Common;
|
||||
using QSB.Utility;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs
|
||||
@ -43,6 +44,12 @@ namespace QSB.Syncs
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
=> _referenceTransform = transform;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the reference transform - what transform this transform is syncing to.
|
||||
/// </summary>
|
||||
public Transform GetReferenceTransform()
|
||||
=> _referenceTransform;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position of the INVISIBLE transform to be correct, according to the reference sector and the position of the VISIBLE transform.
|
||||
/// </summary>
|
||||
@ -51,7 +58,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - _referenceTransform has not been set for {_attachedTransform.name}", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -66,7 +73,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - _referenceTransform has not been set for {_attachedTransform.name}", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -92,7 +99,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - _referenceTransform has not been set for {_attachedTransform.name}", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
@ -106,7 +113,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - _referenceTransform has not been set for {_attachedTransform.name}", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
return Quaternion.identity;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@ namespace QSB.Syncs.RigidbodySync
|
||||
public SectorSync.SectorSync SectorSync { get; private set; }
|
||||
public abstract TargetType Type { get; }
|
||||
|
||||
public override bool IgnoreDisabledAttachedObject => false;
|
||||
public override bool IgnoreNullReferenceTransform => true;
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
|
||||
@ -36,6 +39,11 @@ namespace QSB.Syncs.RigidbodySync
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
{
|
||||
@ -43,7 +51,7 @@ namespace QSB.Syncs.RigidbodySync
|
||||
}
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
@ -59,10 +67,10 @@ namespace QSB.Syncs.RigidbodySync
|
||||
writer.Write(-1);
|
||||
}
|
||||
|
||||
base.SerializeTransform(writer);
|
||||
base.SerializeTransform(writer, initialState);
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
@ -82,12 +90,12 @@ namespace QSB.Syncs.RigidbodySync
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
base.DeserializeTransform(reader);
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
}
|
||||
|
||||
protected override void UpdateTransform()
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if ((ReferenceTransform == null || ReferenceSector == null) && QSBSectorManager.Instance.IsReady)
|
||||
if ((ReferenceTransform == null || ReferenceSector == null || _intermediaryTransform.GetReferenceTransform() == null) && QSBSectorManager.Instance.IsReady && HasAuthority)
|
||||
{
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
@ -96,11 +104,11 @@ namespace QSB.Syncs.RigidbodySync
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
base.UpdateTransform();
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
public void SetReferenceSector(QSBSector sector)
|
||||
@ -109,4 +117,4 @@ namespace QSB.Syncs.RigidbodySync
|
||||
SetReferenceTransform(sector?.Transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,38 +1,28 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.RigidbodySync
|
||||
{
|
||||
public abstract class UnparentedBaseRigidbodySync : QNetworkTransform, ISync<OWRigidbody>
|
||||
public abstract class UnparentedBaseRigidbodySync : SyncBase
|
||||
{
|
||||
public Transform ReferenceTransform { get; set; }
|
||||
public OWRigidbody AttachedObject { get; set; }
|
||||
|
||||
public abstract bool IsReady { get; }
|
||||
public abstract bool UseInterpolation { get; }
|
||||
|
||||
protected virtual float DistanceLeeway { get; } = 5f;
|
||||
private float _previousDistance;
|
||||
private const float SmoothTime = 0.1f;
|
||||
|
||||
protected bool _isInitialized;
|
||||
protected IntermediaryTransform _intermediaryTransform;
|
||||
protected Vector3 _relativeVelocity;
|
||||
protected Vector3 _relativeAngularVelocity;
|
||||
protected Vector3 _prevVelocity;
|
||||
protected Vector3 _prevAngularVelocity;
|
||||
private string _logName => $"{NetId}:{GetType().Name}";
|
||||
private Vector3 _positionSmoothVelocity;
|
||||
private Quaternion _rotationSmoothVelocity;
|
||||
|
||||
protected abstract OWRigidbody GetRigidbody();
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
@ -40,10 +30,10 @@ namespace QSB.Syncs.RigidbodySync
|
||||
|
||||
protected virtual void OnDestroy() => QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse)
|
||||
=> _isInitialized = false;
|
||||
|
||||
protected virtual void Init()
|
||||
protected override void Init()
|
||||
{
|
||||
if (!QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
@ -54,7 +44,7 @@ namespace QSB.Syncs.RigidbodySync
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
@ -85,7 +75,7 @@ namespace QSB.Syncs.RigidbodySync
|
||||
_prevAngularVelocity = relativeAngularVelocity;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
@ -122,53 +112,15 @@ namespace QSB.Syncs.RigidbodySync
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (!_isInitialized && IsReady)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else if (_isInitialized && !IsReady)
|
||||
{
|
||||
_isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedRigidbody {_logName} is null.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AttachedObject.gameObject.activeInHierarchy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReferenceTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTransform();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected virtual void UpdateTransform()
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
_relativeVelocity = GetRelativeVelocity();
|
||||
_relativeAngularVelocity = AttachedObject.GetRelativeAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody());
|
||||
return;
|
||||
_relativeAngularVelocity = (AttachedObject as OWRigidbody).GetRelativeAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody());
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
@ -176,26 +128,28 @@ namespace QSB.Syncs.RigidbodySync
|
||||
|
||||
if (targetPos == Vector3.zero || _intermediaryTransform.GetTargetPosition_ParentedToReference() == Vector3.zero)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UseInterpolation)
|
||||
{
|
||||
AttachedObject.SetPosition(SmartPositionSmoothDamp(AttachedObject.transform.position, targetPos));
|
||||
AttachedObject.SetRotation(QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime));
|
||||
(AttachedObject as OWRigidbody).SetPosition(SmartSmoothDamp(AttachedObject.transform.position, targetPos));
|
||||
(AttachedObject as OWRigidbody).SetRotation(QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.SetPosition(targetPos);
|
||||
AttachedObject.SetRotation(targetRot);
|
||||
(AttachedObject as OWRigidbody).SetPosition(targetPos);
|
||||
(AttachedObject as OWRigidbody).SetRotation(targetRot);
|
||||
}
|
||||
|
||||
var currentVelocity = GetRelativeVelocity();
|
||||
var targetVelocity = ReferenceTransform.GetAttachedOWRigidbody().GetPointVelocity(targetPos) + _relativeVelocity;
|
||||
var adjustedTarget = targetVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameWorldVelocity();
|
||||
|
||||
SetVelocity(AttachedObject, targetVelocity);
|
||||
AttachedObject.SetAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody().GetAngularVelocity() + _relativeAngularVelocity);
|
||||
SetVelocity((AttachedObject as OWRigidbody), targetVelocity);
|
||||
(AttachedObject as OWRigidbody).SetAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody().GetAngularVelocity() + _relativeAngularVelocity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetVelocity(OWRigidbody rigidbody, Vector3 relativeVelocity)
|
||||
@ -227,21 +181,12 @@ namespace QSB.Syncs.RigidbodySync
|
||||
|
||||
ReferenceTransform = transform;
|
||||
_intermediaryTransform.SetReferenceTransform(transform);
|
||||
}
|
||||
|
||||
// TODO : remove .Distance
|
||||
private Vector3 SmartPositionSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
|
||||
{
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
if (HasAuthority)
|
||||
{
|
||||
DebugLog.DebugWrite($"Warning - {AttachedObject.name} moved too far!", MessageType.Warning);
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
|
||||
_previousDistance = distance;
|
||||
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
|
||||
}
|
||||
|
||||
// TODO : optimize by using sqrMagnitude
|
||||
@ -299,27 +244,7 @@ namespace QSB.Syncs.RigidbodySync
|
||||
}
|
||||
|
||||
var pointVelocity = attachedRigid.GetPointVelocity(AttachedObject.transform.position);
|
||||
return AttachedObject.GetVelocity() - pointVelocity;
|
||||
}
|
||||
|
||||
private void OnRenderObject()
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady
|
||||
|| !QSBCore.DebugMode
|
||||
|| !QSBCore.ShowLinesInDebug
|
||||
|| !IsReady
|
||||
|| ReferenceTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Cube(_intermediaryTransform.GetTargetPosition_Unparented(), _intermediaryTransform.GetTargetRotation_Unparented(), Vector3.one / 2, Color.red);
|
||||
Popcron.Gizmos.Line(_intermediaryTransform.GetTargetPosition_Unparented(), AttachedObject.transform.position, Color.red);
|
||||
var color = HasMoved() ? Color.green : Color.yellow;
|
||||
Popcron.Gizmos.Cube(AttachedObject.transform.position, AttachedObject.transform.rotation, Vector3.one / 2, color);
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceTransform.position, Color.cyan);
|
||||
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, AttachedObject.transform.position + GetRelativeVelocity(), Color.blue);
|
||||
return (AttachedObject as OWRigidbody).GetVelocity() - pointVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
191
QSB/Syncs/SyncBase.cs
Normal file
191
QSB/Syncs/SyncBase.cs
Normal file
@ -0,0 +1,191 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Components;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs
|
||||
{
|
||||
public abstract class SyncBase : QNetworkTransform
|
||||
{
|
||||
public uint AttachedNetId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (NetIdentity == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to get AttachedNetId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
return NetIdentity.NetId.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public uint PlayerId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (NetIdentity == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to get PlayerId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
return NetIdentity.RootIdentity != null
|
||||
? NetIdentity.RootIdentity.NetId.Value
|
||||
: AttachedNetId;
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
|
||||
private bool _baseIsReady => QSBPlayerManager.PlayerExists(PlayerId)
|
||||
&& Player != null
|
||||
&& Player.PlayerStates.IsReady
|
||||
&& NetId.Value != uint.MaxValue
|
||||
&& NetId.Value != 0U
|
||||
&& WorldObjectManager.AllReady;
|
||||
public abstract bool IsReady { get; }
|
||||
public abstract bool UseInterpolation { get; }
|
||||
public abstract bool IgnoreDisabledAttachedObject { get; }
|
||||
public abstract bool IgnoreNullReferenceTransform { get; }
|
||||
|
||||
public Component AttachedObject { get; set; }
|
||||
public Transform ReferenceTransform { get; set; }
|
||||
|
||||
protected string _logName => $"{PlayerId}.{GetType().Name}";
|
||||
protected virtual float DistanceLeeway { get; } = 5f;
|
||||
private float _previousDistance;
|
||||
protected const float SmoothTime = 0.1f;
|
||||
protected Vector3 _positionSmoothVelocity;
|
||||
protected Quaternion _rotationSmoothVelocity;
|
||||
protected IntermediaryTransform _intermediaryTransform;
|
||||
protected bool _isInitialized;
|
||||
|
||||
protected abstract Component InitLocalTransform();
|
||||
protected abstract Component InitRemoteTransform();
|
||||
protected abstract bool UpdateTransform();
|
||||
protected abstract void Init();
|
||||
|
||||
protected Vector3 SmartSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
|
||||
{
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
{
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
_previousDistance = distance;
|
||||
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (!_isInitialized && IsReady && _baseIsReady)
|
||||
{
|
||||
Init();
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
else if (_isInitialized && (!IsReady || !_baseIsReady))
|
||||
{
|
||||
_isInitialized = false;
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isInitialized)
|
||||
{
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedObject {_logName} is null.", MessageType.Warning);
|
||||
_isInitialized = false;
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReferenceTransform != null && ReferenceTransform.position == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {_logName}'s ReferenceTransform is at (0,0,0). ReferenceTransform:{ReferenceTransform.name}, AttachedObject:{AttachedObject.name}", MessageType.Warning);
|
||||
}
|
||||
|
||||
if (!AttachedObject.gameObject.activeInHierarchy && !IgnoreDisabledAttachedObject)
|
||||
{
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReferenceTransform == null && !IgnoreNullReferenceTransform)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {_logName}'s ReferenceTransform is null. AttachedObject:{AttachedObject.name}", MessageType.Warning);
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReferenceTransform != _intermediaryTransform.GetReferenceTransform())
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {_logName}'s ReferenceTransform does not match the reference transform set for the intermediary. ReferenceTransform null : {ReferenceTransform == null}, Intermediary reference null : {_intermediaryTransform.GetReferenceTransform() == null}");
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
var state = UpdateTransform();
|
||||
if (!state)
|
||||
{
|
||||
DebugLog.ToConsole($"{_logName} UpdateTransform() fail.", MessageType.Error);
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
var expectedPosition = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
var actualPosition = AttachedObject.transform.position;
|
||||
var distance = Vector3.Distance(expectedPosition, actualPosition);
|
||||
if (distance > 20)
|
||||
{
|
||||
var intermediaryReference = _intermediaryTransform.GetReferenceTransform();
|
||||
DebugLog.ToConsole($"Warning - {_logName}'s AttachedObject ({AttachedObject?.name}) is far away from it's expected position! Info:" +
|
||||
$"\r\n AttachedObject's parent : {AttachedObject?.transform.parent?.name}" +
|
||||
$"\r\n Distance : {distance}" +
|
||||
$"\r\n ReferenceTransform : {(ReferenceTransform == null ? "NULL" : ReferenceTransform.name)}" +
|
||||
$"\r\n Intermediary's ReferenceTransform : {(intermediaryReference == null ? "NULL" : intermediaryReference.name)}", MessageType.Warning);
|
||||
}
|
||||
*/
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected virtual void OnRenderObject()
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady
|
||||
|| !QSBCore.DebugMode
|
||||
|| !QSBCore.ShowLinesInDebug
|
||||
|| !IsReady
|
||||
|| ReferenceTransform == null
|
||||
|| _intermediaryTransform.GetReferenceTransform() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Red Cube = Where visible object should be
|
||||
* Green/Yellow Cube = Where visible object is
|
||||
* Magenta cube = Reference transform
|
||||
* Red Line = Connection between Red Cube and Green/Yellow Cube
|
||||
* Cyan Line = Connection between Green/Yellow cube and reference transform
|
||||
*/
|
||||
|
||||
Popcron.Gizmos.Cube(_intermediaryTransform.GetTargetPosition_Unparented(), _intermediaryTransform.GetTargetRotation_Unparented(), Vector3.one / 4, Color.red);
|
||||
Popcron.Gizmos.Line(_intermediaryTransform.GetTargetPosition_Unparented(), AttachedObject.transform.position, Color.red);
|
||||
var color = HasMoved() ? Color.green : Color.yellow;
|
||||
Popcron.Gizmos.Cube(AttachedObject.transform.position, AttachedObject.transform.rotation, Vector3.one / 4, color);
|
||||
Popcron.Gizmos.Cube(ReferenceTransform.position, ReferenceTransform.rotation, Vector3.one / 4, Color.magenta);
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceTransform.position, Color.cyan);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,70 +2,44 @@
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Transport;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.TransformSync
|
||||
{
|
||||
/*
|
||||
* Rewrite number : 5
|
||||
* Rewrite number : 7
|
||||
* God has cursed me for my hubris, and my work is never finished.
|
||||
*/
|
||||
|
||||
public abstract class BaseTransformSync : QNetworkTransform, ISync<Transform>
|
||||
public abstract class BaseTransformSync : SyncBase
|
||||
{
|
||||
public uint AttachedNetId
|
||||
private static readonly Dictionary<PlayerInfo, Dictionary<Type, BaseTransformSync>> _storedTransformSyncs = new Dictionary<PlayerInfo, Dictionary<Type, BaseTransformSync>>();
|
||||
|
||||
public static T GetPlayers<T>(PlayerInfo player)
|
||||
where T : BaseTransformSync
|
||||
{
|
||||
get
|
||||
var dictOfOwnedSyncs = _storedTransformSyncs[player];
|
||||
var wantedSync = dictOfOwnedSyncs[typeof(T)];
|
||||
if (wantedSync == default)
|
||||
{
|
||||
if (NetIdentity == null)
|
||||
DebugLog.ToConsole($"Error - _storedTransformSyncs does not contain type:{typeof(T)} under player {player.PlayerId}. Attempting to find manually...", MessageType.Error);
|
||||
var allSyncs = Resources.FindObjectsOfTypeAll<T>();
|
||||
wantedSync = allSyncs.First(x => x.Player == player);
|
||||
if (wantedSync == default)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to get AttachedNetId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
|
||||
return uint.MaxValue;
|
||||
DebugLog.ToConsole($"Error - Could not find type:{typeof(T)} for player {player.PlayerId} manually!", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
|
||||
return NetIdentity.NetId.Value;
|
||||
}
|
||||
|
||||
return (T)wantedSync;
|
||||
}
|
||||
|
||||
public uint PlayerId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (NetIdentity == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to get PlayerId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
return NetIdentity.RootIdentity != null
|
||||
? NetIdentity.RootIdentity.NetId.Value
|
||||
: AttachedNetId;
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
|
||||
|
||||
public Transform ReferenceTransform { get; set; }
|
||||
public Transform AttachedObject { get; set; }
|
||||
|
||||
public abstract bool IsReady { get; }
|
||||
public abstract bool UseInterpolation { get; }
|
||||
|
||||
protected abstract Transform InitLocalTransform();
|
||||
protected abstract Transform InitRemoteTransform();
|
||||
|
||||
protected bool _isInitialized;
|
||||
private const float SmoothTime = 0.1f;
|
||||
protected virtual float DistanceLeeway { get; } = 5f;
|
||||
private float _previousDistance;
|
||||
private Vector3 _positionSmoothVelocity;
|
||||
private Quaternion _rotationSmoothVelocity;
|
||||
private string _logName => $"{PlayerId}.{GetType().Name}";
|
||||
protected IntermediaryTransform _intermediaryTransform;
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
@ -75,6 +49,14 @@ namespace QSB.Syncs.TransformSync
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
|
||||
if (!_storedTransformSyncs.ContainsKey(Player))
|
||||
{
|
||||
_storedTransformSyncs.Add(Player, new Dictionary<Type, BaseTransformSync>());
|
||||
}
|
||||
|
||||
var playerDict = _storedTransformSyncs[Player];
|
||||
playerDict[GetType()] = this;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
@ -85,12 +67,20 @@ namespace QSB.Syncs.TransformSync
|
||||
}
|
||||
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
|
||||
if (!QSBPlayerManager.PlayerExists(PlayerId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var playerDict = _storedTransformSyncs[Player];
|
||||
playerDict.Remove(GetType());
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
|
||||
protected virtual void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse)
|
||||
=> _isInitialized = false;
|
||||
|
||||
protected virtual void Init()
|
||||
protected override void Init()
|
||||
{
|
||||
if (!QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
@ -104,9 +94,47 @@ namespace QSB.Syncs.TransformSync
|
||||
|
||||
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
_isInitialized = true;
|
||||
|
||||
if (QSBCore.DebugMode)
|
||||
{
|
||||
DebugBoxManager.CreateBox(AttachedObject.transform, 0, _logName);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
public override bool OnSerialize(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (!initialState)
|
||||
{
|
||||
if (SyncVarDirtyBits == 0U)
|
||||
{
|
||||
writer.WritePackedUInt32(0U);
|
||||
return false;
|
||||
}
|
||||
|
||||
writer.WritePackedUInt32(1U);
|
||||
}
|
||||
|
||||
SerializeTransform(writer, initialState);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDeserialize(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!IsServer || !QNetworkServer.localClientActive)
|
||||
{
|
||||
if (!initialState)
|
||||
{
|
||||
if (reader.ReadPackedUInt32() == 0U)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DeserializeTransform(reader, initialState);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
@ -121,7 +149,7 @@ namespace QSB.Syncs.TransformSync
|
||||
_prevRotation = worldRot;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
@ -152,51 +180,13 @@ namespace QSB.Syncs.TransformSync
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (!_isInitialized && IsReady)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else if (_isInitialized && !IsReady)
|
||||
{
|
||||
_isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedObject {_logName} is null.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AttachedObject.gameObject.activeInHierarchy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReferenceTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTransform();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected virtual void UpdateTransform()
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_ParentedToReference();
|
||||
@ -214,6 +204,7 @@ namespace QSB.Syncs.TransformSync
|
||||
AttachedObject.transform.localRotation = targetRot;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HasMoved()
|
||||
@ -245,50 +236,23 @@ namespace QSB.Syncs.TransformSync
|
||||
{
|
||||
ReparentAttachedObject(transform);
|
||||
}
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReparentAttachedObject(Transform sectorTransform)
|
||||
private void ReparentAttachedObject(Transform newParent)
|
||||
{
|
||||
if (AttachedObject.transform.parent != null && AttachedObject.transform.parent.GetComponent<Sector>() == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Trying to reparent AttachedObject {AttachedObject.name} which wasnt attached to sector!", MessageType.Warning);
|
||||
}
|
||||
|
||||
AttachedObject.transform.SetParent(sectorTransform, true);
|
||||
AttachedObject.transform.localScale = GetType() == typeof(PlayerTransformSync)
|
||||
? Vector3.one / 10
|
||||
: Vector3.one;
|
||||
}
|
||||
|
||||
private Vector3 SmartSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
|
||||
{
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
{
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
_previousDistance = distance;
|
||||
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
|
||||
}
|
||||
|
||||
private void OnRenderObject()
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady
|
||||
|| !QSBCore.DebugMode
|
||||
|| !QSBCore.ShowLinesInDebug
|
||||
|| !IsReady
|
||||
|| ReferenceTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Cube(_intermediaryTransform.GetTargetPosition_Unparented(), _intermediaryTransform.GetTargetRotation_Unparented(), Vector3.one / 2, Color.red);
|
||||
Popcron.Gizmos.Line(_intermediaryTransform.GetTargetPosition_Unparented(), AttachedObject.transform.position, Color.red);
|
||||
var color = HasMoved() ? Color.green : Color.yellow;
|
||||
Popcron.Gizmos.Cube(AttachedObject.transform.position, AttachedObject.transform.rotation, Vector3.one / 2, color);
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceTransform.position, Color.cyan);
|
||||
AttachedObject.transform.SetParent(newParent, true);
|
||||
AttachedObject.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
using QSB.SectorSync;
|
||||
using QSB.Player;
|
||||
using QSB.SectorSync;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
using UnityEngine;
|
||||
@ -12,6 +14,11 @@ namespace QSB.Syncs.TransformSync
|
||||
public SectorSync.SectorSync SectorSync { get; private set; }
|
||||
public abstract TargetType Type { get; }
|
||||
|
||||
public override bool IgnoreNullReferenceTransform => true;
|
||||
public override bool IgnoreDisabledAttachedObject => false;
|
||||
|
||||
private int _sectorIdWaitingSlot = int.MinValue;
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
|
||||
@ -37,58 +44,146 @@ namespace QSB.Syncs.TransformSync
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
{
|
||||
SetReferenceTransform(closestSector.Transform);
|
||||
SetReferenceSector(closestSector);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"INIT - {PlayerId}.{GetType().Name}'s closest sector is null!");
|
||||
}
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
public override void Update()
|
||||
{
|
||||
if (_sectorIdWaitingSlot == int.MinValue)
|
||||
{
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
var sector = _sectorIdWaitingSlot == -1
|
||||
? null
|
||||
: QSBWorldSync.GetWorldFromId<QSBSector>(_sectorIdWaitingSlot);
|
||||
|
||||
if (sector != ReferenceSector)
|
||||
{
|
||||
if (sector == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {PlayerId}.{GetType().Name} got sector of ID -1.", OWML.Common.MessageType.Error);
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
_sectorIdWaitingSlot = int.MinValue;
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
if (!QSBPlayerManager.PlayerExists(PlayerId))
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to serialize {_logName} before the right player exists.", OWML.Common.MessageType.Warning);
|
||||
writer.Write(-1);
|
||||
}
|
||||
else if (!Player.PlayerStates.IsReady)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to serialize {_logName} before the player was ready.", OWML.Common.MessageType.Warning);
|
||||
writer.Write(-1);
|
||||
}
|
||||
|
||||
if (ReferenceSector != null)
|
||||
{
|
||||
writer.Write(ReferenceSector.ObjectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - ReferenceSector of {PlayerId}.{GetType().Name} is null.", OWML.Common.MessageType.Warning);
|
||||
writer.Write(-1);
|
||||
}
|
||||
|
||||
base.SerializeTransform(writer);
|
||||
base.SerializeTransform(writer, initialState);
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
int sectorId;
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
reader.ReadInt32();
|
||||
sectorId = reader.ReadInt32();
|
||||
if (initialState && sectorId != -1)
|
||||
{
|
||||
DebugLog.DebugWrite($"SET WAITING FOR SECTOR SET - id {sectorId}");
|
||||
_sectorIdWaitingSlot = sectorId;
|
||||
}
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var sectorId = reader.ReadInt32();
|
||||
sectorId = reader.ReadInt32();
|
||||
var sector = sectorId == -1
|
||||
? null
|
||||
: QSBWorldSync.GetWorldFromId<QSBSector>(sectorId);
|
||||
|
||||
if (sector != ReferenceSector)
|
||||
{
|
||||
if (sector == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {PlayerId}.{GetType().Name} got sector of ID -1.", OWML.Common.MessageType.Error);
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
return;
|
||||
}
|
||||
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
base.DeserializeTransform(reader);
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
}
|
||||
|
||||
protected override void UpdateTransform()
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if ((ReferenceTransform == null || ReferenceSector == null) && QSBSectorManager.Instance.IsReady)
|
||||
var referenceNull = ReferenceTransform == null || ReferenceSector == null || _intermediaryTransform.GetReferenceTransform() == null;
|
||||
var sectorManagerReady = QSBSectorManager.Instance.IsReady;
|
||||
|
||||
if (!sectorManagerReady)
|
||||
{
|
||||
if (referenceNull && HasAuthority)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Reference was null, but sector manager wasn't ready. " +
|
||||
$"Transform:{ReferenceTransform == null}, Sector:{ReferenceSector == null}, Intermediary:{_intermediaryTransform.GetReferenceTransform() == null}",
|
||||
OWML.Common.MessageType.Warning);
|
||||
}
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
if (!HasAuthority)
|
||||
{
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
if (referenceNull)
|
||||
{
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
@ -97,11 +192,12 @@ namespace QSB.Syncs.TransformSync
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
DebugLog.ToConsole($"Error - No closest sector found to {PlayerId}.{GetType().Name}!", OWML.Common.MessageType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
base.UpdateTransform();
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
public void SetReferenceSector(QSBSector sector)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user