Merge pull request #266 from misternebula/more-fixes

More fixes
This commit is contained in:
_nebula 2021-03-28 14:39:55 +01:00 committed by GitHub
commit 3f8b05c653
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 675 additions and 435 deletions

View File

@ -45,6 +45,9 @@ namespace QSB.Animation
protected override void OnDestroy()
{
base.OnDestroy();
Destroy(_anim);
Destroy(_netAnim);
QSBSceneManager.OnUniverseSceneLoaded -= OnUniverseSceneLoaded;
if (_playerController == null)
{
return;
@ -52,8 +55,6 @@ namespace QSB.Animation
_playerController.OnJump -= OnJump;
_playerController.OnBecomeGrounded -= OnBecomeGrounded;
_playerController.OnBecomeUngrounded -= OnBecomeUngrounded;
QSBSceneManager.OnUniverseSceneLoaded -= OnUniverseSceneLoaded;
}
private void OnUniverseSceneLoaded(OWScene obj) => LoadControllers();

View File

@ -32,7 +32,7 @@ namespace QSB.ConversationSync.Events
{
case ConversationType.Character:
var translated = TextTranslation.Translate(message.Message).Trim();
translated = Regex.Replace(translated, @"<Pause=?\d*\.?\d*\s\/>", "");
translated = Regex.Replace(translated, @"<[Pp]ause=?\d*\.?\d*\s?\/?>", "");
ConversationManager.Instance.DisplayCharacterConversationBox(message.ObjectId, translated);
break;

View File

@ -94,9 +94,18 @@ namespace QSB.ConversationSync.Patches
CharacterDialogueTree ____dialogueTree)
{
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
var position = playerId == uint.MaxValue
? Locator.GetActiveCamera().transform.position
: QSBPlayerManager.GetPlayer(playerId).CameraBody.transform.position;
Vector3 position;
if (playerId == uint.MaxValue)
{
position = Locator.GetActiveCamera().transform.position;
}
else
{
var player = QSBPlayerManager.GetPlayer(playerId);
position = player.CameraBody == null
? Locator.GetActiveCamera().transform.position
: player.CameraBody.transform.position;
}
var localPosition = ____animator.transform.InverseTransformPoint(position);
var targetWeight = ___headTrackingWeight * Mathf.Min(1, !___lookOnlyWhenTalking
? !____playerInHeadZone ? 0 : 1

View File

@ -9,7 +9,7 @@ namespace QSB.DeathSync.Patches
{
public class DeathPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnModStart;
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
public override void DoPatches()
{

View File

@ -1,22 +1,11 @@
using QSB.ElevatorSync.WorldObjects;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.ElevatorSync
{
public class ElevatorManager : MonoBehaviour
public class ElevatorManager : WorldObjectManager
{
public static ElevatorManager Instance { get; private set; }
public void Awake()
{
Instance = this;
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
public void OnDestroy() => QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
protected override void RebuildWorldObjects(OWScene scene)
=> QSBWorldSync.Init<QSBElevator, Elevator>();
}
}

View File

@ -8,7 +8,7 @@ namespace QSB.ElevatorSync.Patches
{
public class ElevatorPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnModStart;
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
public static void StartLift(Elevator __instance)
{

View File

@ -16,7 +16,6 @@ namespace QSB.ElevatorSync.WorldObjects
public override void Init(Elevator elevator, int id)
{
DebugLog.DebugWrite($"init with id {id}");
AttachedObject = elevator;
ObjectId = id;
QSBCore.UnityEvents.RunWhen(() => AttachedObject.GetValue<SingleInteractionVolume>("_interactVolume") != null, InitValues);

View File

@ -1,34 +1,11 @@
using QSB.GeyserSync.WorldObjects;
using QSB.Patches;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.GeyserSync
{
public class GeyserManager : MonoBehaviour
public class GeyserManager : WorldObjectManager
{
public void Awake()
{
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
QSBPatchManager.OnPatchType += OnPatchType;
}
public void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
QSBPatchManager.OnPatchType -= OnPatchType;
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
protected override void RebuildWorldObjects(OWScene scene)
=> QSBWorldSync.Init<QSBGeyser, GeyserController>();
public void OnPatchType(QSBPatchTypes type)
{
if (type != QSBPatchTypes.OnNonServerClientConnect)
{
return;
}
QSBCore.HarmonyHelper.EmptyMethod<GeyserController>("Update");
}
}
}

View File

@ -0,0 +1,12 @@
using QSB.Patches;
namespace QSB.GeyserSync.Patches
{
internal class GeyserPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnNonServerClientConnect;
public override void DoPatches() => QSBCore.HarmonyHelper.EmptyMethod<GeyserController>("Update");
public override void DoUnpatches() => QSBCore.HarmonyHelper.Unpatch<GeyserController>("Update");
}
}

View File

@ -19,111 +19,27 @@ namespace QSB.ItemSync
private static int s_propID_WaveScale;
private static int s_propID_Ripple2Position;
private static int s_propID_Ripple2Params;
public string _dataPointID
{
get => _oldPlatform.GetValue<string>("_dataPointID");
set => _oldPlatform.SetValue("_dataPointID", value);
}
public Sector _visualSector
{
get => _oldPlatform.GetValue<Sector>("_visualSector");
set => _oldPlatform.SetValue("_visualSector", value);
}
public Sector _visualSector2
{
get => _oldPlatform.GetValue<Sector>("_visualSector2");
set => _oldPlatform.SetValue("_visualSector2", value);
}
public Shape _connectionBounds
{
get => _oldPlatform.GetValue<Shape>("_connectionBounds");
set => _oldPlatform.SetValue("_connectionBounds", value);
}
public MeshRenderer _poolRenderer
{
get => _oldPlatform.GetValue<MeshRenderer>("_poolRenderer");
set => _oldPlatform.SetValue("_poolRenderer", value);
}
public float _poolFillLength
{
get => _oldPlatform.GetValue<float>("_poolFillLength");
set => _oldPlatform.SetValue("_poolFillLength", value);
}
public float _poolEmptyLength
{
get => _oldPlatform.GetValue<float>("_poolEmptyLength");
set => _oldPlatform.SetValue("_poolEmptyLength", value);
}
public AnimationCurve _poolHeightCurve
{
get => _oldPlatform.GetValue<AnimationCurve>("_poolHeightCurve");
set => _oldPlatform.SetValue("_poolHeightCurve", value);
}
public AnimationCurve _poolMaskCurve
{
get => _oldPlatform.GetValue<AnimationCurve>("_poolMaskCurve");
set => _oldPlatform.SetValue("_poolMaskCurve", value);
}
public AnimationCurve _poolWaveHeightCurve
{
get => _oldPlatform.GetValue<AnimationCurve>("_poolWaveHeightCurve");
set => _oldPlatform.SetValue("_poolWaveHeightCurve", value);
}
public Renderer[] _transitionRenderers
{
get => _oldPlatform.GetValue<Renderer[]>("_transitionRenderers");
set => _oldPlatform.SetValue("_transitionRenderers", value);
}
public PedestalAnimator _transitionPedestalAnimator
{
get => _oldPlatform.GetValue<PedestalAnimator>("_transitionPedestalAnimator");
set => _oldPlatform.SetValue("_transitionPedestalAnimator", value);
}
public GameObject _transitionStone
{
get => _oldPlatform.GetValue<GameObject>("_transitionStone");
set => _oldPlatform.SetValue("_transitionStone", value);
}
public GameObject _hologramGroup
{
get => _oldPlatform.GetValue<GameObject>("_hologramGroup");
set => _oldPlatform.SetValue("_hologramGroup", value);
}
public Transform _playerHologram
{
get => _oldPlatform.GetValue<Transform>("_playerHologram");
set => _oldPlatform.SetValue("_playerHologram", value);
}
public Transform _stoneHologram
{
get => _oldPlatform.GetValue<Transform>("_stoneHologram");
set => _oldPlatform.SetValue("_stoneHologram", value);
}
public float _fadeInLength
{
get => _oldPlatform.GetValue<float>("_fadeInLength");
set => _oldPlatform.SetValue("_fadeInLength", value);
}
public float _fadeOutLength
{
get => _oldPlatform.GetValue<float>("_fadeOutLength");
set => _oldPlatform.SetValue("_fadeOutLength", value);
}
public OWAudioSource _ambientAudioSource
{
get => _oldPlatform.GetValue<OWAudioSource>("_ambientAudioSource");
set => _oldPlatform.SetValue("_ambientAudioSource", value);
}
public OWAudioSource _oneShotAudioSource
{
get => _oldPlatform.GetValue<OWAudioSource>("_oneShotAudioSource");
set => _oldPlatform.SetValue("_oneShotAudioSource", value);
}
public DarkZone _darkZone
{
get => _oldPlatform.GetValue<DarkZone>("_darkZone");
set => _oldPlatform.SetValue("_darkZone", value);
}
public string _dataPointID => _oldPlatform.GetValue<string>("_dataPointID");
public Sector _visualSector => _oldPlatform.GetValue<Sector>("_visualSector");
public Sector _visualSector2 => _oldPlatform.GetValue<Sector>("_visualSector2");
public Shape _connectionBounds => _oldPlatform.GetValue<Shape>("_connectionBounds");
public MeshRenderer _poolRenderer => _oldPlatform.GetValue<MeshRenderer>("_poolRenderer");
public float _poolFillLength => _oldPlatform.GetValue<float>("_poolFillLength");
public float _poolEmptyLength => _oldPlatform.GetValue<float>("_poolEmptyLength");
public AnimationCurve _poolHeightCurve => _oldPlatform.GetValue<AnimationCurve>("_poolHeightCurve");
public AnimationCurve _poolMaskCurve => _oldPlatform.GetValue<AnimationCurve>("_poolMaskCurve");
public AnimationCurve _poolWaveHeightCurve => _oldPlatform.GetValue<AnimationCurve>("_poolWaveHeightCurve");
public Renderer[] _transitionRenderers => _oldPlatform.GetValue<Renderer[]>("_transitionRenderers");
public PedestalAnimator _transitionPedestalAnimator => _oldPlatform.GetValue<PedestalAnimator>("_transitionPedestalAnimator");
public GameObject _transitionStone => _oldPlatform.GetValue<GameObject>("_transitionStone");
public GameObject _hologramGroup => _oldPlatform.GetValue<GameObject>("_hologramGroup");
public Transform _playerHologram => _oldPlatform.GetValue<Transform>("_playerHologram");
public Transform _stoneHologram => _oldPlatform.GetValue<Transform>("_stoneHologram");
public float _fadeInLength => _oldPlatform.GetValue<float>("_fadeInLength");
public float _fadeOutLength => _oldPlatform.GetValue<float>("_fadeOutLength");
public OWAudioSource _ambientAudioSource => _oldPlatform.GetValue<OWAudioSource>("_ambientAudioSource");
public OWAudioSource _oneShotAudioSource => _oldPlatform.GetValue<OWAudioSource>("_oneShotAudioSource");
public DarkZone _darkZone => _oldPlatform.GetValue<DarkZone>("_darkZone");
private OWCamera _playerCamera;
private CustomNomaiRemoteCamera _ownedCamera;
private SharedStoneSocket _socket;
@ -188,27 +104,30 @@ namespace QSB.ItemSync
_playerCamera = Locator.GetPlayerCamera();
if (_socket != null)
{
var socket = _socket;
socket.OnSocketableRemoved += OnSocketableRemoved;
var socket2 = _socket;
socket2.OnSocketableDonePlacing += OnSocketableDonePlacing;
_socket.OnSocketableRemoved += OnSocketableRemoved;
_socket.OnSocketableDonePlacing += OnSocketableDonePlacing;
}
enabled = false;
QSBPlayerManager.OnRemovePlayer += OnRemovePlayer;
}
private void OnDestroy()
{
if (_socket != null)
{
var socket = _socket;
socket.OnSocketableRemoved -= OnSocketableRemoved;
var socket2 = _socket;
socket2.OnSocketableDonePlacing -= OnSocketableDonePlacing;
_socket.OnSocketableRemoved -= OnSocketableRemoved;
_socket.OnSocketableDonePlacing -= OnSocketableDonePlacing;
}
if (CustomPlatformList != null)
{
CustomPlatformList.Remove(this);
}
if (_cameraState == CameraState.Connected || _cameraState == CameraState.Connecting_FadeIn || _cameraState == CameraState.Connecting_FadeOut)
{
DisconnectCamera();
SwitchToPlayerCamera();
}
QSBPlayerManager.OnRemovePlayer -= OnRemovePlayer;
}
private void Update()
@ -216,7 +135,9 @@ namespace QSB.ItemSync
if (_platformActive)
{
var localInBounds = _connectionBounds.PointInside(_playerCamera.transform.position);
_anyoneStillOnPlatform = QSBPlayerManager.PlayerList.Any(x => _connectionBounds.PointInside(x.Camera.transform.position));
_anyoneStillOnPlatform = QSBCore.IsInMultiplayer
? QSBPlayerManager.PlayerList.Any(x => _connectionBounds.PointInside(x.Camera.transform.position))
: localInBounds;
if (!localInBounds && _wasLocalInBounds)
{
OnLeaveBounds();
@ -412,8 +333,14 @@ namespace QSB.ItemSync
foreach (var item in _playerToHologram)
{
if (item.Value == null)
{
DebugLog.ToConsole($"Error - Gameobject for {item.Key.PlayerId} in _playerToHologram is null!", MessageType.Error);
continue;
}
if (!item.Value.activeInHierarchy)
{
DebugLog.ToConsole($"Error - Gameobject for {item.Key.PlayerId} is inactive!", MessageType.Error);
continue;
}
var hologram = item.Value.transform.GetChild(0);
@ -694,6 +621,25 @@ namespace QSB.ItemSync
public bool IsPlatformActive() => _platformActive;
public void OnRemovePlayer(uint id)
{
if (id == QSBPlayerManager.LocalPlayerId)
{
return;
}
var player = QSBPlayerManager.GetPlayer(id);
if (!_playerToHologram.Any(x => x.Key == player))
{
return;
}
var hologram = _playerToHologram.First(x => x.Key == player).Value;
if (hologram.activeInHierarchy)
{
OnRemotePlayerExit(id);
}
_playerToHologram.Remove(player);
}
public void OnRemotePlayerEnter(uint playerId)
{
if (playerId == QSBPlayerManager.LocalPlayerId)
@ -737,7 +683,13 @@ namespace QSB.ItemSync
{
return;
}
_playerToHologram[QSBPlayerManager.GetPlayer(playerId)].SetActive(false);
var player = QSBPlayerManager.GetPlayer(playerId);
if (!_playerToHologram.ContainsKey(player))
{
DebugLog.ToConsole($"Error - Trying to remove remote player {playerId} that isn't in _playerToHologram!", MessageType.Error);
return;
}
_playerToHologram[player].SetActive(false);
}
public enum CameraState

View File

@ -50,7 +50,7 @@ namespace QSB.ItemSync.Events
break;
}
itemObject.PickUpItem(itemSocket);
itemObject.PickUpItem(itemSocket, message.AboutId);
}
}
}

View File

@ -1,6 +1,7 @@
using QSB.Events;
using QSB.ItemSync.WorldObjects;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
namespace QSB.ItemSync.Events
@ -36,6 +37,11 @@ namespace QSB.ItemSync.Events
socketWorldObject.PlaceIntoSocket(itemWorldObject);
return;
case SocketEventType.StartUnsocket:
if (!socketWorldObject.IsSocketOccupied())
{
DebugLog.ToConsole($"Warning - Trying to start unsocket on socket that is unoccupied! Socket:{(socketWorldObject as IWorldObject).Name}");
return;
}
socketWorldObject.RemoveFromSocket();
return;
case SocketEventType.CompleteUnsocket:

View File

@ -6,43 +6,30 @@ using UnityEngine;
namespace QSB.ItemSync
{
internal class ItemManager : MonoBehaviour
internal class ItemManager : WorldObjectManager
{
public static ItemManager Instance { get; private set; }
public void Awake()
{
Instance = this;
QSBSceneManager.OnUniverseSceneLoaded += RebuildItems;
}
public void OnDestroy() => QSBSceneManager.OnUniverseSceneLoaded -= RebuildItems;
public void RebuildItems(OWScene scene)
protected override void RebuildWorldObjects(OWScene scene)
{
DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Warning);
QSBWorldSync.Init<QSBScrollItem, ScrollItem>();
QSBWorldSync.Init<QSBScrollSocket, ScrollSocket>();
QSBWorldSync.Init<QSBSharedStone, SharedStone>();
QSBWorldSync.Init<QSBScrollItem, ScrollItem>();
QSBWorldSync.Init<QSBSharedStoneSocket, SharedStoneSocket>();
QSBWorldSync.Init<QSBWarpCoreItem, WarpCoreItem>();
QSBWorldSync.Init<QSBSharedStone, SharedStone>();
QSBWorldSync.Init<QSBWarpCoreSocket, WarpCoreSocket>();
QSBWorldSync.Init<QSBNomaiConversationStone, NomaiConversationStone>();
QSBWorldSync.Init<QSBWarpCoreItem, WarpCoreItem>();
QSBWorldSync.Init<QSBNomaiConversationStoneSocket, NomaiConversationStoneSocket>();
QSBWorldSync.Init<QSBNomaiConversationStone, NomaiConversationStone>();
foreach (var streaming in Resources.FindObjectsOfTypeAll<NomaiRemoteCameraStreaming>())
{
streaming.gameObject.AddComponent<CustomNomaiRemoteCameraStreaming>();
streaming.enabled = false;
}
foreach (var camera in Resources.FindObjectsOfTypeAll<NomaiRemoteCamera>())
{
camera.gameObject.AddComponent<CustomNomaiRemoteCamera>();
camera.enabled = false;
}
foreach (var platform in Resources.FindObjectsOfTypeAll<NomaiRemoteCameraPlatform>())
{
platform.gameObject.AddComponent<CustomNomaiRemoteCameraPlatform>();
platform.enabled = false;
}
}
@ -50,6 +37,7 @@ namespace QSB.ItemSync
{
if (unityObject == null)
{
DebugLog.ToConsole($"Error - Trying to run GetObject (Item) with null unity object!", MessageType.Error);
return default;
}
IQSBOWItem worldObj = null;
@ -80,6 +68,7 @@ namespace QSB.ItemSync
{
if (unityObject == null)
{
DebugLog.ToConsole($"Error - Trying to run GetObject (Socket) with null unity object!", MessageType.Error);
return default;
}
IQSBOWItemSocket worldObj = null;

View File

@ -18,23 +18,36 @@ namespace QSB.ItemSync.Patches
QSBCore.HarmonyHelper.AddPrefix<ItemTool>("StartUnsocketItem", typeof(ItemPatches), nameof(ItemTool_StartUnsocketItem));
QSBCore.HarmonyHelper.AddPrefix<ItemTool>("CompleteUnsocketItem", typeof(ItemPatches), nameof(ItemTool_CompleteUnsocketItem));
QSBCore.HarmonyHelper.AddPrefix<ItemTool>("DropItem", typeof(ItemPatches), nameof(ItemTool_DropItem));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("Update", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("OnSocketableRemoved", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("OnSocketableDonePlacing", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("OnPedestalContact", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("FixedUpdate", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnSectorOccupantAdded", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnSectorOccupantRemoved", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnEntry", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnExit", typeof(ItemPatches), nameof(Platform_ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("Update", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("OnSocketableRemoved", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("OnSocketableDonePlacing", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraPlatform>("OnPedestalContact", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("FixedUpdate", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnSectorOccupantAdded", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnSectorOccupantRemoved", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnEntry", typeof(ItemPatches), nameof(ReturnFalse));
QSBCore.HarmonyHelper.AddPrefix<NomaiRemoteCameraStreaming>("OnExit", typeof(ItemPatches), nameof(ReturnFalse));
}
public override void DoUnpatches()
{
// TODO : add this
QSBCore.HarmonyHelper.Unpatch<ItemTool>("MoveItemToCarrySocket");
QSBCore.HarmonyHelper.Unpatch<ItemTool>("SocketItem");
QSBCore.HarmonyHelper.Unpatch<ItemTool>("StartUnsocketItem");
QSBCore.HarmonyHelper.Unpatch<ItemTool>("CompleteUnsocketItem");
QSBCore.HarmonyHelper.Unpatch<ItemTool>("DropItem");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraPlatform>("Update");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraPlatform>("OnSocketableRemoved");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraPlatform>("OnSocketableDonePlacing");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraPlatform>("OnPedestalContact");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraStreaming>("FixedUpdate");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraStreaming>("OnSectorOccupantAdded");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraStreaming>("OnSectorOccupantRemoved");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraStreaming>("OnEntry");
QSBCore.HarmonyHelper.Unpatch<NomaiRemoteCameraStreaming>("OnExit");
}
public static bool Platform_ReturnFalse() => false;
public static bool ReturnFalse() => false;
public static bool ItemTool_MoveItemToCarrySocket(OWItem item)
{

View File

@ -8,7 +8,7 @@ namespace QSB.ItemSync.WorldObjects
ItemType GetItemType();
void SetColliderActivation(bool active);
void SocketItem(Transform socketTransform, Sector sector);
void PickUpItem(Transform holdTransform);
void PickUpItem(Transform holdTransform, uint playerId);
void DropItem(Vector3 position, Vector3 normal, Sector sector);
void PlaySocketAnimation();
void PlayUnsocketAnimation();

View File

@ -5,6 +5,7 @@ namespace QSB.ItemSync.WorldObjects
public interface IQSBOWItemSocket : IWorldObjectTypeSubset
{
bool AcceptsItem(IQSBOWItem item);
bool IsSocketOccupied();
bool PlaceIntoSocket(IQSBOWItem item);
IQSBOWItem RemoveFromSocket();
}

View File

@ -1,4 +1,7 @@
using OWML.Utils;
using QSB.Player;
using QSB.SectorSync.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
@ -7,7 +10,47 @@ namespace QSB.ItemSync.WorldObjects
internal class QSBOWItem<T> : WorldObject<T>, IQSBOWItem
where T : OWItem
{
public override void Init(T attachedObject, int id) { }
public IQSBOWItemSocket InitialSocket { get; private set; }
public Transform InitialParent { get; private set; }
public Vector3 InitialPosition { get; private set; }
public Quaternion InitialRotation { get; private set; }
public QSBSector InitialSector { get; private set; }
public uint HoldingPlayer { get; private set; }
public override void Init(T attachedObject, int id)
{
InitialParent = attachedObject.transform.parent;
InitialPosition = attachedObject.transform.localPosition;
InitialRotation = attachedObject.transform.localRotation;
InitialSector = QSBWorldSync.GetWorldFromUnity<QSBSector, Sector>(attachedObject.GetSector());
if (InitialParent.GetComponent<OWItemSocket>() != null)
{
var qsbObj = ItemManager.GetObject(InitialParent.GetComponent<OWItemSocket>());
InitialSocket = qsbObj;
}
QSBPlayerManager.OnRemovePlayer += OnPlayerLeave;
}
public override void OnRemoval() => QSBPlayerManager.OnRemovePlayer -= OnPlayerLeave;
private void OnPlayerLeave(uint player)
{
if (HoldingPlayer != player)
{
return;
}
if (InitialSocket != null)
{
InitialSocket.PlaceIntoSocket(this);
return;
}
AttachedObject.transform.parent = InitialParent;
AttachedObject.transform.localPosition = InitialPosition;
AttachedObject.transform.localRotation = InitialRotation;
AttachedObject.transform.localScale = Vector3.one;
AttachedObject.SetSector(InitialSector.AttachedObject);
AttachedObject.SetColliderActivation(true);
}
public ItemType GetItemType()
=> AttachedObject.GetItemType();
@ -16,10 +59,17 @@ namespace QSB.ItemSync.WorldObjects
=> AttachedObject.SetColliderActivation(active);
public virtual void SocketItem(Transform socketTransform, Sector sector)
=> AttachedObject.SocketItem(socketTransform, sector);
{
AttachedObject.SocketItem(socketTransform, sector);
HoldingPlayer = 0;
}
public virtual void PickUpItem(Transform holdTransform)
=> AttachedObject.PickUpItem(holdTransform);
public virtual void PickUpItem(Transform holdTransform, uint playerId)
{
AttachedObject.PickUpItem(holdTransform);
HoldingPlayer = playerId;
}
public virtual void DropItem(Vector3 position, Vector3 normal, Sector sector)
{
@ -32,6 +82,7 @@ namespace QSB.ItemSync.WorldObjects
AttachedObject.transform.position = sector.transform.TransformPoint(position) + AttachedObject.transform.TransformDirection(localDropOffset);
AttachedObject.SetSector(sector);
AttachedObject.SetColliderActivation(true);
HoldingPlayer = 0;
}
public virtual void PlaySocketAnimation() { }

View File

@ -15,6 +15,9 @@ namespace QSB.ItemSync.WorldObjects
return (itemType & acceptableType) == itemType;
}
public virtual bool IsSocketOccupied()
=> AttachedObject.IsSocketOccupied();
public virtual bool PlaceIntoSocket(IQSBOWItem item)
=> AttachedObject.PlaceIntoSocket((OWItem)(item as IWorldObject).ReturnObject());

View File

@ -8,8 +8,5 @@
AttachedObject = attachedObject;
base.Init(attachedObject, id);
}
public override IQSBOWItem RemoveFromSocket()
=> ItemManager.GetObject(AttachedObject.RemoveFromSocket());
}
}

View File

@ -51,9 +51,14 @@ namespace QSB.OrbSync.Events
private static void HandleServer(WorldObjectMessage message)
{
var fromPlayer = QNetworkServer.connections.First(x => x.GetPlayerId() == message.FromId);
if (QSBWorldSync.OrbSyncList.Count == 0)
if (QSBWorldSync.OrbSyncList == null || QSBWorldSync.OrbSyncList.Count == 0)
{
DebugLog.ToConsole($"Error - OrbSyncList is empty. (ID {message.ObjectId})", MessageType.Error);
DebugLog.ToConsole($"Error - OrbSyncList is empty or null. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count == 0)
{
DebugLog.ToConsole($"Error - OldOrbList is empty or null. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (fromPlayer == null)
@ -83,11 +88,14 @@ namespace QSB.OrbSync.Events
private static void HandleClient(WorldObjectMessage message)
{
if (QSBWorldSync.OrbSyncList.Count < message.ObjectId)
if (QSBWorldSync.OrbSyncList == null || QSBWorldSync.OrbSyncList.Count == 0)
{
DebugLog.ToConsole(
$"Error - Orb id {message.ObjectId} out of range of orb sync list {QSBWorldSync.OrbSyncList.Count}.",
MessageType.Error);
DebugLog.ToConsole($"Error - OrbSyncList is empty or null. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count == 0)
{
DebugLog.ToConsole($"Error - OldOrbList is empty or null. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (!QSBWorldSync.OrbSyncList.Any(x => x.AttachedOrb == QSBWorldSync.OldOrbList[message.ObjectId]))

View File

@ -1,5 +1,4 @@
using OWML.Common;
using OWML.Utils;
using QSB.OrbSync.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
@ -9,23 +8,20 @@ using UnityEngine;
namespace QSB.OrbSync
{
public class OrbManager : MonoBehaviour
public class OrbManager : WorldObjectManager
{
public static OrbManager Instance { get; private set; }
private void Awake() => Instance = this;
private void BuildOrbSlots()
protected override void RebuildWorldObjects(OWScene scene)
{
QSBWorldSync.Init<QSBOrbSlot, NomaiInterfaceSlot>();
DebugLog.DebugWrite($"Finished slot build with {QSBWorldSync.GetWorldObjects<QSBOrbSlot>().Count()} slots.", MessageType.Success);
BuildOrbs();
}
public void BuildOrbs()
private void BuildOrbs()
{
QSBWorldSync.OldOrbList.Clear();
QSBWorldSync.OldOrbList = Resources.FindObjectsOfTypeAll<NomaiInterfaceOrb>().ToList();
if (QNetworkServer.active)
if (QSBCore.IsServer)
{
QSBWorldSync.OrbSyncList.ForEach(x => QNetworkServer.Destroy(x.gameObject));
QSBWorldSync.OrbSyncList.Clear();
@ -33,35 +29,5 @@ namespace QSB.OrbSync
}
DebugLog.DebugWrite($"Finished orb build with {QSBWorldSync.OldOrbList.Count} orbs.", MessageType.Success);
}
public void OnRenderObject()
{
if (!QSBCore.HasWokenUp || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug)
{
return;
}
foreach (var orb in QSBWorldSync.OldOrbList)
{
var rails = orb.GetValue<OWRail[]>("_safetyRails");
if (rails.Length > 0)
{
foreach (var rail in rails)
{
var points = rail.GetValue<Vector3[]>("_railPoints");
for (var i = 0; i < points.Length; i++)
{
if (i > 0)
{
Popcron.Gizmos.Line(rail.transform.TransformPoint(points[i - 1]), rail.transform.TransformPoint(points[i]), Color.white);
}
}
}
}
}
}
public void QueueBuildSlots() => QSBCore.UnityEvents.RunWhen(() => QSBCore.HasWokenUp, BuildOrbSlots);
public void QueueBuildOrbs() => QSBCore.UnityEvents.RunWhen(() => QNetworkServer.active, BuildOrbs);
}
}

View File

@ -3,6 +3,7 @@ using QSB.ConversationSync.Patches;
using QSB.DeathSync.Patches;
using QSB.ElevatorSync.Patches;
using QSB.FrequencySync.Patches;
using QSB.GeyserSync.Patches;
using QSB.ItemSync.Patches;
using QSB.LogSync.Patches;
using QSB.OrbSync.Patches;
@ -41,7 +42,8 @@ namespace QSB.Patches
new SpiralPatches(),
new QuantumPatches(),
new ItemPatches(),
new StatuePatches()
new StatuePatches(),
new GeyserPatches()
};
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);

View File

@ -2,9 +2,8 @@
{
public enum QSBPatchTypes
{
OnModStart = 0,
OnClientConnect = 1,
OnNonServerClientConnect = 2,
OnServerClientConnect = 3
OnClientConnect = 0,
OnNonServerClientConnect = 1,
OnServerClientConnect = 2
}
}

View File

@ -24,7 +24,7 @@ namespace QSB.Player.Events
{
if (server && (message.QSBVersion != QSBCore.QSBVersion))
{
DebugLog.DebugWrite($"Error - Client {message.PlayerName} connecting with wrong version. (Client:{message.QSBVersion}, Server:{QSBCore.QSBVersion})", MessageType.Error);
DebugLog.ToConsole($"Error - Client {message.PlayerName} connecting with wrong version. (Client:{message.QSBVersion}, Server:{QSBCore.QSBVersion})", MessageType.Error);
QSBEventManager.FireEvent(EventNames.QSBPlayerKick, message.AboutId, KickReason.VersionNotMatching);
return;
}

View File

@ -1,4 +1,5 @@
using UnityEngine;
using QSB.Utility;
using UnityEngine;
namespace QSB.Player
{
@ -47,11 +48,14 @@ namespace QSB.Player
public void Remove()
{
// do N O T destroy the parent - it completely breaks the ENTIRE GAME
if (_canvasMarker?.gameObject != null)
if (_canvasMarker != null)
{
_canvasMarker.DestroyMarker();
}
Destroy(_markerTarget.gameObject);
if (_markerTarget != null)
{
Destroy(_markerTarget.gameObject);
}
Destroy(this);
}
}

View File

@ -32,6 +32,8 @@ namespace QSB.Player
}
}
public static Action<uint> OnRemovePlayer;
public static PlayerInfo LocalPlayer => GetPlayer(LocalPlayerId);
public static List<PlayerInfo> PlayerList { get; } = new List<PlayerInfo>();
@ -103,7 +105,9 @@ namespace QSB.Player
public static List<PlayerInfo> GetPlayersWithCameras(bool includeLocalCamera = true)
{
var cameraList = PlayerList.Where(x => x.Camera != null && x.PlayerId != LocalPlayerId).ToList();
if (includeLocalCamera)
if (includeLocalCamera
&& LocalPlayer != default
&& LocalPlayer.Camera != null)
{
cameraList.Add(LocalPlayer);
}

View File

@ -129,6 +129,7 @@
<Compile Include="FrequencySync\Events\IdentifyFrequencyEvent.cs" />
<Compile Include="FrequencySync\Events\IdentifySignalEvent.cs" />
<Compile Include="FrequencySync\Patches\FrequencyPatches.cs" />
<Compile Include="GeyserSync\Patches\GeyserPatches.cs" />
<Compile Include="Instruments\QSBCamera\CameraController.cs" />
<Compile Include="Instruments\QSBCamera\CameraManager.cs" />
<Compile Include="Instruments\QSBCamera\CameraMode.cs" />
@ -196,10 +197,12 @@
<Compile Include="QuantumSync\Events\SocketStateChangeEvent.cs" />
<Compile Include="QuantumSync\Events\SocketStateChangeMessage.cs" />
<Compile Include="QuantumSync\Patches\QuantumPatches.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBEyeProxyQuantumMoon.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBMultiStateQuantumObject.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBQuantumMoon.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBQuantumObject.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBQuantumShuffleObject.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBQuantumState.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBSocketedQuantumObject.cs" />
<Compile Include="QuantumSync\WorldObjects\QSBQuantumSocket.cs" />
<Compile Include="QuantumSync\QuantumManager.cs" />
@ -301,6 +304,7 @@
<Compile Include="WorldSync\IWorldObjectTypeSubset.cs" />
<Compile Include="WorldSync\QSBWorldSync.cs" />
<Compile Include="WorldSync\WorldObject.cs" />
<Compile Include="WorldSync\WorldObjectManager.cs" />
</ItemGroup>
<ItemGroup>
<None Include="default-config.json">

View File

@ -87,7 +87,6 @@ namespace QSB
ConversationAssetBundle = Helper.Assets.LoadBundle("assets/conversation");
QSBPatchManager.Init();
QSBPatchManager.DoPatchType(QSBPatchTypes.OnModStart);
gameObject.AddComponent<QSBNetworkManager>();
gameObject.AddComponent<QNetworkManagerHUD>();
@ -127,12 +126,35 @@ namespace QSB
offset += _debugLineSpacing;
GUI.Label(new Rect(220, offset, 200f, 20f), $"HasWokenUp : {HasWokenUp}");
offset += _debugLineSpacing;
if (WakeUpSync.LocalInstance != null)
{
GUI.Label(new Rect(220, offset, 200f, 20f), $"Time Difference : {WakeUpSync.LocalInstance.GetTimeDifference()}");
offset += _debugLineSpacing;
GUI.Label(new Rect(220, offset, 200f, 20f), $"Timescale : {OWTime.GetTimeScale()}");
offset += _debugLineSpacing;
}
if (!HasWokenUp)
{
return;
}
var offset3 = 10f;
GUI.Label(new Rect(420, offset3, 200f, 20f), $"Current closest sector :");
offset3 += _debugLineSpacing;
var sector = PlayerTransformSync.LocalInstance.SectorSync.GetClosestSector(Locator.GetPlayerTransform());
GUI.Label(new Rect(420, offset3, 400f, 20f), $"- {sector.AttachedObject.name} : {sector.IsFakeSector}");
offset3 += _debugLineSpacing;
var offset2 = 10f;
GUI.Label(new Rect(620, offset2, 200f, 20f), $"Owned Objects :");
offset2 += _debugLineSpacing;
foreach (var obj in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().Where(x => x.ControllingPlayer == QSBPlayerManager.LocalPlayerId))
{
GUI.Label(new Rect(620, offset2, 200f, 20f), $"- {(obj as IWorldObject).Name}, {obj.ControllingPlayer}, {obj.IsEnabled}");
offset2 += _debugLineSpacing;
}
if (QSBSceneManager.CurrentScene != OWScene.SolarSystem)
{
return;
@ -151,22 +173,6 @@ namespace QSB
offset += _debugLineSpacing;
}
var offset3 = 10f;
GUI.Label(new Rect(420, offset3, 200f, 20f), $"Current closest sector :");
offset3 += _debugLineSpacing;
var sector = PlayerTransformSync.LocalInstance.SectorSync.GetClosestSector(Locator.GetPlayerTransform());
GUI.Label(new Rect(420, offset3, 400f, 20f), $"- {sector.AttachedObject.name} : {sector.IsFakeSector}");
offset3 += _debugLineSpacing;
var offset2 = 10f;
GUI.Label(new Rect(620, offset2, 200f, 20f), $"Owned Objects :");
offset2 += _debugLineSpacing;
foreach (var obj in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().Where(x => x.ControllingPlayer == QSBPlayerManager.LocalPlayerId))
{
GUI.Label(new Rect(620, offset2, 200f, 20f), $"- {(obj as IWorldObject).Name}");
offset2 += _debugLineSpacing;
}
if (SocketedObjToDebug == -1)
{
return;

View File

@ -2,17 +2,11 @@
using OWML.Utils;
using QSB.Animation;
using QSB.DeathSync;
using QSB.ElevatorSync.WorldObjects;
using QSB.Events;
using QSB.GeyserSync.WorldObjects;
using QSB.Instruments;
using QSB.OrbSync;
using QSB.OrbSync.WorldObjects;
using QSB.ItemSync;
using QSB.Patches;
using QSB.Player;
using QSB.QuantumSync;
using QSB.SectorSync;
using QSB.SectorSync.WorldObjects;
using QSB.TimeSync;
using QSB.TransformSync;
using QSB.Utility;
@ -110,8 +104,6 @@ namespace QSB
private void OnSceneLoaded(OWScene scene)
{
OrbManager.Instance.BuildOrbs();
OrbManager.Instance.QueueBuildSlots();
QSBWorldSync.OldDialogueTrees.Clear();
QSBWorldSync.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
}
@ -134,10 +126,6 @@ namespace QSB
public override void OnStartServer()
{
DebugLog.DebugWrite("OnStartServer", MessageType.Info);
if (QSBWorldSync.OrbSyncList.Count == 0 && QSBSceneManager.IsInUniverse)
{
OrbManager.Instance.QueueBuildOrbs();
}
if (QSBWorldSync.OldDialogueTrees.Count == 0 && QSBSceneManager.IsInUniverse)
{
QSBWorldSync.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
@ -178,9 +166,7 @@ namespace QSB
if (QSBSceneManager.IsInUniverse)
{
QSBSectorManager.Instance?.RebuildSectors();
OrbManager.Instance?.QueueBuildSlots();
QuantumManager.Instance?.RebuildQuantumObjects(QSBSceneManager.CurrentScene);
WorldObjectManager.Rebuild(QSBSceneManager.CurrentScene);
}
var specificType = QNetworkServer.active ? QSBPatchTypes.OnServerClientConnect : QSBPatchTypes.OnNonServerClientConnect;
@ -208,7 +194,6 @@ namespace QSB
{
DebugLog.DebugWrite("OnStopClient", MessageType.Info);
DebugLog.ToConsole("Disconnecting from server...", MessageType.Info);
Destroy(GetComponent<SectorSync.QSBSectorManager>());
Destroy(GetComponent<RespawnOnDeath>());
QSBEventManager.Reset();
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
@ -244,24 +229,16 @@ namespace QSB
identity.RemoveClientAuthority(connection);
}
}
// Server takes some time to process removal of player/deletion of networkidentity
Invoke(nameof(LateFinalizeDisconnect), 1f);
}
private void LateFinalizeDisconnect()
=> QuantumManager.Instance.CheckExistingPlayers();
public override void OnStopServer()
{
DebugLog.DebugWrite("OnStopServer", MessageType.Info);
Destroy(GetComponent<SectorSync.QSBSectorManager>());
Destroy(GetComponent<RespawnOnDeath>());
QSBEventManager.Reset();
DebugLog.ToConsole("Server stopped!", MessageType.Info);
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
RemoveWorldObjects();
QSBCore.HasWokenUp = false;
base.OnStopServer();
@ -269,11 +246,20 @@ namespace QSB
private void RemoveWorldObjects()
{
QSBWorldSync.RemoveWorldObjects<QSBOrbSlot>();
QSBWorldSync.RemoveWorldObjects<QSBElevator>();
QSBWorldSync.RemoveWorldObjects<QSBGeyser>();
QSBWorldSync.RemoveWorldObjects<QSBSector>();
QSBWorldSync.RemoveWorldObjects<IQSBQuantumObject>();
QSBWorldSync.RemoveWorldObjects<IWorldObjectTypeSubset>();
QSBWorldSync.RemoveWorldObjects<IWorldObject>();
foreach (var platform in Resources.FindObjectsOfTypeAll<CustomNomaiRemoteCameraPlatform>())
{
Destroy(platform);
}
foreach (var camera in Resources.FindObjectsOfTypeAll<CustomNomaiRemoteCamera>())
{
Destroy(camera);
}
foreach (var streaming in Resources.FindObjectsOfTypeAll<CustomNomaiRemoteCameraStreaming>())
{
Destroy(streaming);
}
}
}
}

View File

@ -1,5 +1,6 @@
using OWML.Common;
using QSB.Utility;
using QSB.WorldSync;
using System;
namespace QSB
@ -22,6 +23,10 @@ namespace QSB
private static void OnCompleteSceneLoad(OWScene oldScene, OWScene newScene)
{
DebugLog.DebugWrite($"COMPLETE SCENE LOAD ({oldScene} -> {newScene})", MessageType.Info);
if (QSBCore.IsInMultiplayer)
{
WorldObjectManager.Rebuild(newScene);
}
var universe = InUniverse(newScene);
OnSceneLoaded?.SafeInvoke(newScene, universe);
if (universe)

View File

@ -1,5 +1,7 @@
using QSB.Events;
using OWML.Common;
using QSB.Events;
using QSB.QuantumSync.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
namespace QSB.QuantumSync.Events
@ -37,6 +39,11 @@ namespace QSB.QuantumSync.Events
return;
}
var qsbObj = QSBWorldSync.GetWorldFromId<QSBMultiStateQuantumObject>(message.ObjectId);
if (qsbObj.ControllingPlayer != message.FromId)
{
DebugLog.ToConsole($"Error - Got MultiStateChangeEvent for {qsbObj.Name} from {message.FromId}, but it's currently controlled by {qsbObj.ControllingPlayer}!", MessageType.Error);
return;
}
qsbObj.ChangeState(message.StateIndex);
}
}

View File

@ -1,5 +1,7 @@
using QSB.Events;
using OWML.Common;
using QSB.Events;
using QSB.QuantumSync.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
@ -29,6 +31,11 @@ namespace QSB.QuantumSync.Events
return;
}
var obj = QSBWorldSync.GetWorldFromId<QSBSocketedQuantumObject>(message.ObjectId);
if (obj.ControllingPlayer != message.FromId)
{
DebugLog.ToConsole($"Error - Got SocketStateChangeEvent for {obj.Name} from {message.FromId}, but it's currently controlled by {obj.ControllingPlayer}!", MessageType.Error);
return;
}
obj.MoveToSocket(message);
}
}

View File

@ -5,7 +5,6 @@ using QSB.Player;
using QSB.QuantumSync.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@ -30,6 +29,7 @@ namespace QSB.QuantumSync.Patches
QSBCore.HarmonyHelper.AddPrefix<QuantumShrine>("OnExit", typeof(QuantumPatches), nameof(Shrine_OnExit));
QSBCore.HarmonyHelper.AddPrefix<QuantumMoon>("CheckPlayerFogProximity", typeof(QuantumPatches), nameof(Moon_CheckPlayerFogProximity));
QSBCore.HarmonyHelper.AddPrefix<QuantumObject>("IsLockedByPlayerContact", typeof(QuantumPatches), nameof(Object_IsLockedByPlayerContact));
QSBCore.HarmonyHelper.AddPrefix<MultiStateQuantumObject>("Start", typeof(QuantumPatches), nameof(MultiState_Start));
}
public override void DoUnpatches()
@ -220,9 +220,41 @@ namespace QSB.QuantumSync.Patches
return false;
}
public static bool MultiState_Start(MultiStateQuantumObject __instance, Sector ____sector, bool ____collapseOnStart)
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBMultiStateQuantumObject, MultiStateQuantumObject>(__instance);
if (qsbObj.ControllingPlayer == 0)
{
return true;
}
foreach (var state in qsbObj.QuantumStates)
{
if (!state.IsMeantToBeEnabled)
{
state.SetVisible(false);
}
}
if (____sector == null)
{
__instance.GetType().GetMethod("CheckEnabled", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null);
}
if (____collapseOnStart)
{
__instance.GetType().GetMethod("Collapse", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { true });
}
return false;
}
public static bool MultiState_ChangeQuantumState(MultiStateQuantumObject __instance)
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBMultiStateQuantumObject, MultiStateQuantumObject>(__instance);
if (qsbObj.ControllingPlayer == 0 && qsbObj.CurrentState == -1)
{
return true;
}
var isInControl = qsbObj.ControllingPlayer == QSBPlayerManager.LocalPlayerId;
return isInControl;
}
@ -234,17 +266,17 @@ namespace QSB.QuantumSync.Patches
return;
}
var allMultiStates = QSBWorldSync.GetWorldObjects<QSBMultiStateQuantumObject>();
var owner = allMultiStates.First(x => x.QuantumStates.Contains(__instance));
//DebugLog.DebugWrite($"{owner.AttachedObject.name} controller is {owner.ControllingPlayer}");
var stateObject = QSBWorldSync.GetWorldFromUnity<QSBQuantumState, QuantumState>(__instance);
var owner = allMultiStates.First(x => x.QuantumStates.Contains(stateObject));
if (owner.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
{
return;
}
//DebugLog.DebugWrite($"{owner.AttachedObject.name} to quantum state {Array.IndexOf(owner.QuantumStates, __instance)}");
var stateIndex = owner.QuantumStates.IndexOf(stateObject);
QSBEventManager.FireEvent(
EventNames.QSBMultiStateChange,
owner.ObjectId,
Array.IndexOf(owner.QuantumStates, __instance));
stateIndex);
}
public static bool Shrine_IsPlayerInDarkness(ref bool __result, Light[] ____lamps, float ____fadeFraction, bool ____isProbeInside, NomaiGateway ____gate)
@ -259,14 +291,33 @@ namespace QSB.QuantumSync.Patches
}
var playersInMoon = QSBPlayerManager.PlayerList.Where(x => x.IsInMoon);
if (playersInMoon.Any(x => !x.IsInShrine)
|| playersInMoon.Any(x => x.FlashLight != null && x.FlashLight.FlashlightOn)
|| (QSBPlayerManager.LocalPlayer.IsInShrine && PlayerState.IsFlashlightOn())
|| playersInMoon.Count() == 0)
if (playersInMoon.Any(player => !player.IsInShrine))
{
__result = false;
return false;
}
if (playersInMoon.Any(player => player.FlashLight != null && player.FlashLight.FlashlightOn))
{
__result = false;
return false;
}
if (playersInMoon.Count() == 0)
{
__result = false;
return false;
}
if (QSBPlayerManager.LocalPlayer != null
&& QSBPlayerManager.LocalPlayer.IsInShrine
&& PlayerState.IsFlashlightOn())
{
__result = false;
return false;
}
// TODO : make this *really* check for all players - check other probes and other jetpacks!
__result = ____gate.GetOpenFraction() == 0f
&& !____isProbeInside

View File

@ -11,28 +11,35 @@ using UnityEngine;
namespace QSB.QuantumSync
{
internal class QuantumManager : MonoBehaviour
internal class QuantumManager : WorldObjectManager
{
public static QuantumManager Instance { get; private set; }
public QuantumShrine Shrine;
public bool IsReady;
public void Awake()
public override void Awake()
{
base.Awake();
Instance = this;
QSBSceneManager.OnUniverseSceneLoaded += RebuildQuantumObjects;
QSBPlayerManager.OnRemovePlayer += PlayerLeave;
}
public void OnDestroy() => QSBSceneManager.OnUniverseSceneLoaded -= RebuildQuantumObjects;
public override void OnDestroy()
{
base.OnDestroy();
QSBPlayerManager.OnRemovePlayer -= PlayerLeave;
}
public void RebuildQuantumObjects(OWScene scene)
protected override void RebuildWorldObjects(OWScene scene)
{
DebugLog.DebugWrite("Rebuilding quantum objects...", MessageType.Warning);
QSBWorldSync.Init<QSBQuantumState, QuantumState>();
QSBWorldSync.Init<QSBSocketedQuantumObject, SocketedQuantumObject>();
QSBWorldSync.Init<QSBMultiStateQuantumObject, MultiStateQuantumObject>();
QSBWorldSync.Init<QSBQuantumSocket, QuantumSocket>();
QSBWorldSync.Init<QSBQuantumShuffleObject, QuantumShuffleObject>();
QSBWorldSync.Init<QSBQuantumMoon, QuantumMoon>();
QSBWorldSync.Init<QSBEyeProxyQuantumMoon, EyeProxyQuantumMoon>();
if (scene == OWScene.SolarSystem)
{
Shrine = Resources.FindObjectsOfTypeAll<QuantumShrine>().First();
@ -40,14 +47,17 @@ namespace QSB.QuantumSync
IsReady = true;
}
public void CheckExistingPlayers()
public void PlayerLeave(uint playerId)
{
DebugLog.DebugWrite("Checking quantum objects for non-existent players...", MessageType.Info);
if (!QSBCore.IsServer)
{
return;
}
var quantumObjects = QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().ToList();
for (var i = 0; i < quantumObjects.Count; i++)
{
var obj = quantumObjects[i];
if (!QSBPlayerManager.PlayerExists(obj.ControllingPlayer))
if (obj.ControllingPlayer == playerId)
{
var idToSend = obj.IsEnabled ? QSBPlayerManager.LocalPlayerId : 0u;
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, i, idToSend);
@ -70,11 +80,31 @@ namespace QSB.QuantumSync
public static bool IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
{
return tracker.gameObject.activeInHierarchy
&& QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera)
.Any(x => (bool)tracker.GetType()
.GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(tracker, new object[] { x.Camera.GetFrustumPlanes() }));
var playersWithCameras = QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera);
if (playersWithCameras.Count == 0)
{
DebugLog.ToConsole($"Warning - Trying to run IsVisibleUsingCameraFrustum when there are no players!", MessageType.Warning);
return false;
}
if (!tracker.gameObject.activeInHierarchy)
{
return false;
}
var frustumMethod = tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var player in playersWithCameras)
{
if (player.Camera == null)
{
DebugLog.ToConsole($"Warning - Camera is null for id:{player.PlayerId}!", MessageType.Warning);
continue;
}
var isInFrustum = (bool)frustumMethod.Invoke(tracker, new object[] { player.Camera.GetFrustumPlanes() });
if (isInFrustum)
{
return true;
}
}
return false;
}
public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
@ -110,6 +140,10 @@ namespace QSB.QuantumSync
{
worldObj = QSBWorldSync.GetWorldFromUnity<QSBQuantumMoon, QuantumMoon>((QuantumMoon)unityObject);
}
else if (unityObject.GetType() == typeof(EyeProxyQuantumMoon))
{
worldObj = QSBWorldSync.GetWorldFromUnity<QSBEyeProxyQuantumMoon, EyeProxyQuantumMoon>((EyeProxyQuantumMoon)unityObject);
}
else
{
DebugLog.ToConsole($"Warning - couldn't work out type of QuantumObject {unityObject.name}.", MessageType.Warning);

View File

@ -0,0 +1,13 @@
namespace QSB.QuantumSync.WorldObjects
{
internal class QSBEyeProxyQuantumMoon : QSBQuantumObject<EyeProxyQuantumMoon>
{
public override void Init(EyeProxyQuantumMoon moonObject, int id)
{
ObjectId = id;
AttachedObject = moonObject;
ControllingPlayer = 1u;
base.Init(moonObject, id);
}
}
}

View File

@ -1,13 +1,17 @@
using OWML.Utils;
using QSB.Utility;
using QSB.WorldSync;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.UI;
namespace QSB.QuantumSync.WorldObjects
{
internal class QSBMultiStateQuantumObject : QSBQuantumObject<MultiStateQuantumObject>
{
public QuantumState[] QuantumStates { get; private set; }
public List<QSBQuantumState> QuantumStates { get; private set; }
public Text DebugBoxText;
public int CurrentState => AttachedObject.GetValue<int>("_stateIndex");
public override void OnRemoval()
{
@ -22,26 +26,25 @@ namespace QSB.QuantumSync.WorldObjects
{
ObjectId = id;
AttachedObject = attachedObject;
QuantumStates = AttachedObject.GetValue<QuantumState[]>("_states");
QuantumStates = AttachedObject.GetValue<QuantumState[]>("_states").ToList().Select(x => QSBWorldSync.GetWorldFromUnity<QSBQuantumState, QuantumState>(x)).ToList();
if (QSBCore.DebugMode)
{
DebugBoxText = DebugBoxManager.CreateBox(AttachedObject.transform, 0, AttachedObject.GetValue<int>("_stateIndex").ToString()).GetComponent<Text>();
DebugBoxText = DebugBoxManager.CreateBox(AttachedObject.transform, 0, CurrentState.ToString()).GetComponent<Text>();
}
base.Init(attachedObject, id);
}
public void ChangeState(int stateIndex)
public void ChangeState(int newStateIndex)
{
var currentStateIndex = AttachedObject.GetValue<int>("_stateIndex");
if (currentStateIndex != -1)
if (CurrentState != -1)
{
QuantumStates[currentStateIndex].SetVisible(false);
QuantumStates[CurrentState].SetVisible(false);
}
QuantumStates[stateIndex].SetVisible(true);
AttachedObject.SetValue("_stateIndex", stateIndex);
QuantumStates[newStateIndex].SetVisible(true);
AttachedObject.SetValue("_stateIndex", newStateIndex);
if (QSBCore.DebugMode)
{
DebugBoxText.text = stateIndex.ToString();
DebugBoxText.text = newStateIndex.ToString();
}
}
}

View File

@ -7,6 +7,7 @@
ObjectId = id;
AttachedObject = moonObject;
ControllingPlayer = 1u;
base.Init(moonObject, id);
}
}
}

View File

@ -19,8 +19,11 @@ namespace QSB.QuantumSync.WorldObjects
{
foreach (var shape in GetAttachedShapes())
{
shape.OnShapeActivated -= (Shape s) => OnEnable();
shape.OnShapeDeactivated -= (Shape s) => OnDisable();
shape.OnShapeActivated -= (Shape s)
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnEnable(s));
shape.OnShapeDeactivated -= (Shape s)
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnDisable(s));
}
}
@ -32,10 +35,23 @@ namespace QSB.QuantumSync.WorldObjects
{
break;
}
shape.OnShapeActivated += (Shape s) => OnEnable();
shape.OnShapeDeactivated += (Shape s) => OnDisable();
// Firing next update to give time for shapes to actually be disabled
shape.OnShapeActivated += (Shape s)
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnEnable(s));
shape.OnShapeDeactivated += (Shape s)
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnDisable(s));
}
if (GetAttachedShapes().Any(x => !x.enabled || !x.active))
{
ControllingPlayer = 0u;
IsEnabled = false;
}
else
{
IsEnabled = true;
}
ControllingPlayer = 0u;
}
private List<Shape> GetAttachedShapes()
@ -64,12 +80,8 @@ namespace QSB.QuantumSync.WorldObjects
return totalShapes;
}
private void OnEnable()
private void OnEnable(Shape s)
{
if (IsEnabled)
{
return;
}
IsEnabled = true;
if (!QSBCore.HasWokenUp && !QSBCore.IsServer)
{
@ -80,17 +92,21 @@ namespace QSB.QuantumSync.WorldObjects
// controlled by another player, dont care that we activate it
return;
}
var id = QSBWorldSync.GetIdFromTypeSubset(this);
var id = QSBWorldSync.GetIdFromTypeSubset<IQSBQuantumObject>(this);
// no one is controlling this object right now, request authority
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, id, QSBPlayerManager.LocalPlayerId);
}
private void OnDisable()
private void OnDisable(Shape s)
{
if (!IsEnabled)
{
return;
}
if (GetAttachedShapes().Any(x => x.gameObject.activeInHierarchy))
{
return;
}
IsEnabled = false;
if (!QSBCore.HasWokenUp && !QSBCore.IsServer)
{
@ -101,7 +117,7 @@ namespace QSB.QuantumSync.WorldObjects
// not being controlled by us, don't care if we leave area
return;
}
var id = QSBWorldSync.GetIdFromTypeSubset(this);
var id = QSBWorldSync.GetIdFromTypeSubset<IQSBQuantumObject>(this);
// send event to other players that we're releasing authority
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, id, 0u);
}

View File

@ -0,0 +1,21 @@
using QSB.WorldSync;
namespace QSB.QuantumSync.WorldObjects
{
internal class QSBQuantumState : WorldObject<QuantumState>
{
public bool IsMeantToBeEnabled;
public override void Init(QuantumState state, int id)
{
ObjectId = id;
AttachedObject = state;
}
public void SetVisible(bool visible)
{
IsMeantToBeEnabled = visible;
AttachedObject.SetVisible(visible);
}
}
}

View File

@ -10,7 +10,7 @@ using UnityEngine;
namespace QSB.SectorSync
{
public class QSBSectorManager : MonoBehaviour, IRepeating
public class QSBSectorManager : WorldObjectManager, IRepeating
{
public static QSBSectorManager Instance { get; private set; }
public bool IsReady { get; private set; }
@ -25,24 +25,14 @@ namespace QSB.SectorSync
.Where(x => x.HasAuthority).ToList().ForEach(CheckTransformSyncSector);
}
public void Awake()
public override void Awake()
{
if (Instance != null)
{
DebugLog.ToConsole("Error - Cannot have multiple QSBSectorManagers!", MessageType.Error);
Destroy(this);
return;
}
base.Awake();
Instance = this;
QSBSceneManager.OnUniverseSceneLoaded += (OWScene scene) => RebuildSectors();
DebugLog.DebugWrite("Sector Manager ready.", MessageType.Success);
}
public void OnDestroy()
=> QSBSceneManager.OnUniverseSceneLoaded -= (OWScene scene) => RebuildSectors();
public void RebuildSectors()
protected override void RebuildWorldObjects(OWScene scene)
{
DebugLog.DebugWrite("Rebuilding sectors...", MessageType.Warning);
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)

View File

@ -14,6 +14,15 @@ namespace QSB.SectorSync
private SectorDetector _sectorDetector;
private void OnDestroy()
{
if (_sectorDetector != null)
{
_sectorDetector.OnEnterSector -= AddSector;
_sectorDetector.OnExitSector -= RemoveSector;
}
}
public void SetSectorDetector(SectorDetector detector)
{
if (_sectorDetector != null)

View File

@ -1,4 +1,8 @@
using QSB.WorldSync;
using OWML.Common;
using OWML.Utils;
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
using UnityEngine;
namespace QSB.SectorSync.WorldObjects
@ -30,14 +34,43 @@ namespace QSB.SectorSync.WorldObjects
public bool ShouldSyncTo()
{
if (AttachedObject == null)
{
DebugLog.ToConsole($"Warning - AttachedObject for sector id:{ObjectId} is null!", MessageType.Warning);
return false;
}
if (Type == Sector.Name.Ship)
{
return false;
}
if ((AttachedObject.name == "Sector_Shuttle" || AttachedObject.name == "Sector_NomaiShuttleInterior")
&& !AttachedObject.gameObject.GetComponentInParent<NomaiShuttleController>().IsPlayerInside())
if (AttachedObject.name == "Sector_Shuttle" || AttachedObject.name == "Sector_NomaiShuttleInterior")
{
return false;
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
{
var shuttleController = AttachedObject.gameObject.GetComponentInParent<NomaiShuttleController>();
if (shuttleController == null)
{
DebugLog.ToConsole($"Warning - Expected to find a NomaiShuttleController for {AttachedObject.name}!", MessageType.Warning);
return false;
}
if (!shuttleController.IsPlayerInside())
{
return false;
}
}
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
{
var shuttleController = Resources.FindObjectsOfTypeAll<EyeShuttleController>().First();
if (shuttleController == null)
{
DebugLog.ToConsole($"Warning - Expected to find a EyeShuttleController for {AttachedObject.name}!", MessageType.Warning);
return false;
}
if (!shuttleController.GetValue<bool>("_isPlayerInside"))
{
return false;
}
}
}
return true;
}

View File

@ -12,7 +12,9 @@ namespace QSB.TimeSync
{
public static WakeUpSync LocalInstance { get; private set; }
private const float TimeThreshold = 0.5f;
private const float PauseOrFastForwardThreshold = 1.0f;
private const float TimescaleBounds = 0.3f;
private const float MaxFastForwardSpeed = 60f;
private const float MaxFastForwardDiff = 20f;
private const float MinFastForwardSpeed = 2f;
@ -23,8 +25,6 @@ namespace QSB.TimeSync
private float _sendTimer;
private float _serverTime;
private float _timeScale;
private bool _isInputEnabled = true;
private bool _isFirstFastForward = true;
private int _localLoopCount;
private int _serverLoopCount;
@ -40,6 +40,7 @@ namespace QSB.TimeSync
if (QSBSceneManager.IsInUniverse)
{
_isFirstFastForward = false;
Init();
}
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
@ -48,6 +49,12 @@ namespace QSB.TimeSync
GlobalMessenger.AddListener(EventNames.WakeUp, OnWakeUp);
}
public float GetTimeDifference()
{
var myTime = Time.timeSinceLevelLoad;
return myTime - _serverTime;
}
private void OnWakeUp()
{
DebugLog.DebugWrite($"OnWakeUp", MessageType.Info);
@ -94,13 +101,12 @@ namespace QSB.TimeSync
}
}
private void SendServerTime() => QSBEventManager.FireEvent(EventNames.QSBServerTime, Time.timeSinceLevelLoad, _localLoopCount);
private void SendServerTime() => QSBEventManager.FireEvent(EventNames.QSBServerTime, _serverTime, _localLoopCount);
public void OnClientReceiveMessage(ServerTimeMessage message)
{
_serverTime = message.ServerTime;
_serverLoopCount = message.LoopCount;
WakeUpOrSleep();
}
private void WakeUpOrSleep()
@ -113,13 +119,13 @@ namespace QSB.TimeSync
var myTime = Time.timeSinceLevelLoad;
var diff = myTime - _serverTime;
if (diff > TimeThreshold)
if (diff > PauseOrFastForwardThreshold)
{
StartPausing();
return;
}
if (diff < -TimeThreshold)
if (diff < -PauseOrFastForwardThreshold)
{
StartFastForwarding();
}
@ -137,13 +143,11 @@ namespace QSB.TimeSync
{
Locator.GetActiveCamera().enabled = false;
}
_timeScale = MaxFastForwardSpeed;
_state = State.FastForwarding;
OWTime.SetMaxDeltaTime(0.033333335f);
OWTime.SetFixedTimestep(0.033333335f);
TimeSyncUI.TargetTime = _serverTime;
TimeSyncUI.Start(TimeSyncType.Fastforwarding);
DisableInput();
}
private void StartPausing()
@ -154,25 +158,20 @@ namespace QSB.TimeSync
}
DebugLog.DebugWrite($"START PAUSING (Target:{_serverTime} Current:{Time.timeSinceLevelLoad})", MessageType.Info);
Locator.GetActiveCamera().enabled = false;
_timeScale = 0f;
OWTime.SetTimeScale(0f);
_state = State.Pausing;
SpinnerUI.Show();
TimeSyncUI.Start(TimeSyncType.Pausing);
DisableInput();
}
private void ResetTimeScale()
{
_timeScale = 1f;
OWTime.SetTimeScale(1f);
OWTime.SetMaxDeltaTime(0.06666667f);
OWTime.SetFixedTimestep(0.01666667f);
Locator.GetActiveCamera().enabled = true;
_state = State.Loaded;
if (!_isInputEnabled)
{
EnableInput();
}
DebugLog.DebugWrite($"RESET TIMESCALE", MessageType.Info);
_isFirstFastForward = false;
QSBCore.HasWokenUp = true;
@ -183,26 +182,6 @@ namespace QSB.TimeSync
RespawnOnDeath.Instance.Init();
}
private void DisableInput()
{
if (OWInput.GetInputMode() != InputMode.None && _isInputEnabled)
{
OWInput.ChangeInputMode(InputMode.None);
_isInputEnabled = false;
}
}
private void EnableInput()
{
_isInputEnabled = true;
if (OWInput.GetInputMode() != InputMode.None)
{
DebugLog.ToConsole($"Warning - InputMode was changed to {OWInput.GetInputMode()} while pausing/fastforwarding!", MessageType.Warning);
return;
}
OWInput.RestorePreviousInputs();
}
public void Update()
{
if (IsServer)
@ -217,6 +196,7 @@ namespace QSB.TimeSync
private void UpdateServer()
{
_serverTime = Time.timeSinceLevelLoad;
if (_state != State.Loaded)
{
return;
@ -234,11 +214,6 @@ namespace QSB.TimeSync
{
_serverTime += Time.unscaledDeltaTime;
if (!_isInputEnabled && OWInput.GetInputMode() != InputMode.None)
{
DisableInput();
}
if (_state == State.NotLoaded)
{
return;
@ -251,7 +226,7 @@ namespace QSB.TimeSync
Locator.GetPlayerCamera().enabled = false;
}
var diff = _serverTime - Time.timeSinceLevelLoad;
Time.timeScale = Mathf.SmoothStep(MinFastForwardSpeed, MaxFastForwardSpeed, Mathf.Abs(diff) / MaxFastForwardDiff);
OWTime.SetTimeScale(Mathf.SmoothStep(MinFastForwardSpeed, MaxFastForwardSpeed, Mathf.Abs(diff) / MaxFastForwardDiff));
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem && _isFirstFastForward)
{
@ -261,10 +236,6 @@ namespace QSB.TimeSync
Physics.SyncTransforms();
}
}
else
{
Time.timeScale = _timeScale;
}
var isDoneFastForwarding = _state == State.FastForwarding && Time.timeSinceLevelLoad >= _serverTime;
var isDonePausing = _state == State.Pausing && Time.timeSinceLevelLoad < _serverTime;
@ -273,6 +244,24 @@ namespace QSB.TimeSync
{
ResetTimeScale();
}
if (_state == State.Loaded)
{
CheckTimeDifference();
}
}
private void CheckTimeDifference()
{
var diff = GetTimeDifference();
if (diff > PauseOrFastForwardThreshold || diff < -PauseOrFastForwardThreshold)
{
WakeUpOrSleep();
}
var mappedTimescale = diff.Map(-PauseOrFastForwardThreshold, PauseOrFastForwardThreshold, 1 + TimescaleBounds, 1 - TimescaleBounds);
OWTime.SetTimeScale(mappedTimescale);
}
}
}

View File

@ -198,6 +198,7 @@ namespace QSB.Tools
tool.Type = ToolType.ProbeLauncher;
tool.ToolGameObject = model;
// TODO : investigate why probe is wack
GetRenderer(launcherRoot, "Props_HEA_Probe_Prelaunch").materials[0] = _playerToolsMaterial;
GetRenderer(launcherRoot, "Props_HEA_Probe_Prelaunch").materials[1] = _lightbulbMaterial;
GetRenderer(launcherRoot, "PressureGauge_Arrow").material = _playerToolsMaterial;

View File

@ -1,4 +1,5 @@
using QSB.WorldSync;
using QSB.Utility;
using QSB.WorldSync;
using QuantumUNET;
using UnityEngine;
@ -25,6 +26,11 @@ namespace QSB.TransformSync
private void OnReady()
{
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count < Index)
{
DebugLog.ToConsole($"Error - OldOrbList is null or does not contain index {Index}.", OWML.Common.MessageType.Error);
return;
}
AttachedOrb = QSBWorldSync.OldOrbList[Index];
_isReady = true;
}

View File

@ -49,7 +49,12 @@ namespace QSB.TransformSync
return body;
}
private void SetSocket(Transform socket) => _disabledSocket = socket;
private void SetSocket(Transform socket)
{
DebugLog.DebugWrite($"Set DisabledSocket of id:{PlayerId}.");
_disabledSocket = socket;
}
protected override void UpdateTransform()
{
@ -61,7 +66,7 @@ namespace QSB.TransformSync
}
if (_disabledSocket == null)
{
DebugLog.ToConsole($"DisabledSocket is null for {AttachedNetId}! (ProbeLauncher null? : {Player.ProbeLauncher == null})", MessageType.Error);
DebugLog.ToConsole($"DisabledSocket is null for {PlayerId}! (ProbeLauncher null? : {Player.ProbeLauncher == null})", MessageType.Error);
return;
}
if (Player.GetState(State.ProbeActive) || ReferenceSector?.AttachedObject == null)

View File

@ -16,6 +16,7 @@ namespace QSB.TransformSync
protected override void OnDestroy()
{
QSBPlayerManager.OnRemovePlayer?.Invoke(PlayerId);
base.OnDestroy();
if (QSBPlayerManager.PlayerExists(PlayerId))
{

View File

@ -47,6 +47,10 @@ namespace QSB.TransformSync
Destroy(SyncedTransform.gameObject);
}
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
if (SectorSync != null)
{
Destroy(SectorSync);
}
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse) =>

View File

@ -1,22 +1,11 @@
using QSB.TranslationSync.WorldObjects;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.TranslationSync
{
internal class SpiralManager : MonoBehaviour
internal class SpiralManager : WorldObjectManager
{
public static SpiralManager Instance { get; private set; }
public void Awake()
{
Instance = this;
QSBSceneManager.OnUniverseSceneLoaded += OnSceneLoaded;
}
public void OnDestroy() => QSBSceneManager.OnUniverseSceneLoaded -= OnSceneLoaded;
private void OnSceneLoaded(OWScene scene)
protected override void RebuildWorldObjects(OWScene scene)
{
QSBWorldSync.Init<QSBWallText, NomaiWallText>();
QSBWorldSync.Init<QSBComputer, NomaiComputer>();

View File

@ -1,4 +1,7 @@
using OWML.Utils;
using QSB.Player;
using QSB.TransformSync;
using System.Linq;
using UnityEngine;
namespace QSB.Utility
@ -24,21 +27,44 @@ namespace QSB.Utility
bridgeVolume.AddObjectToVolume(Locator.GetPlayerCameraDetector());
}
private void DebugWarpToPlayer(int index)
{
var allPlayers = QSBPlayerManager.PlayerList.Where(x => x != QSBPlayerManager.LocalPlayer).ToList();
if (allPlayers.Count <= index)
{
return;
}
var player = allPlayers[index];
var localPlayer = Locator.GetPlayerBody();
localPlayer.WarpToPositionRotation(player.CameraBody.transform.position, player.CameraBody.transform.rotation);
var playerTransformSync = QSBPlayerManager.GetSyncObject<PlayerTransformSync>(player.PlayerId);
var syncedRigidbody = playerTransformSync.ReferenceSector.AttachedObject.GetOWRigidbody();
localPlayer.SetVelocity(syncedRigidbody.GetPointVelocity(player.Body.transform.position));
}
public void Update()
{
if (!QSBCore.DebugMode)
{
return;
}
if (Input.GetKeyDown(KeyCode.Keypad0))
{
DebugWarpToPlayer(0);
}
if (Input.GetKeyDown(KeyCode.Keypad1))
{
DebugWarpToPlayer(1);
}
if (Input.GetKeyDown(KeyCode.Keypad7))
{
GoToVessel();
}
if (Input.GetKeyDown(KeyCode.Keypad2))
if (Input.GetKeyDown(KeyCode.Keypad8))
{
InsertWarpCore();
}
if (Input.GetKeyDown(KeyCode.Keypad3))
if (Input.GetKeyDown(KeyCode.Keypad9))
{
LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToWhite);
}

View File

@ -57,5 +57,8 @@ namespace QSB.Utility
}
}
}
public static float Map(this float value, float inputFrom, float inputTo, float outputFrom, float outputTo)
=> ((value - inputFrom) / (inputTo - inputFrom) * (outputTo - outputFrom)) + outputFrom;
}
}

View File

@ -42,7 +42,24 @@ namespace QSB.WorldSync
public static TWorldObject GetWorldFromUnity<TWorldObject, TUnityObject>(TUnityObject unityObject)
where TWorldObject : WorldObject<TUnityObject>
where TUnityObject : MonoBehaviour
=> WorldObjectsToUnityObjects[unityObject] as TWorldObject;
{
if (unityObject == null)
{
DebugLog.ToConsole($"Error - Trying to run GetWorldFromUnity with a null unity object! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{typeof(TUnityObject).Name}.", MessageType.Error);
return default;
}
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Trying to run GetWorldFromUnity while not in multiplayer!");
return default;
}
if (!WorldObjectsToUnityObjects.ContainsKey(unityObject))
{
DebugLog.ToConsole($"Error - WorldObjectsToUnityObjects does not contain \"{unityObject.name}\"!", MessageType.Error);
return default;
}
return WorldObjectsToUnityObjects[unityObject] as TWorldObject;
}
public static int GetIdFromUnity<TWorldObject, TUnityObject>(TUnityObject unityObject)
where TWorldObject : WorldObject<TUnityObject>
@ -71,7 +88,7 @@ namespace QSB.WorldSync
}
catch (Exception e)
{
DebugLog.ToConsole($"Error - Exception in OnRemoval() for {item.GetType()}. Message : {e.Message}, Stack trace : {e.StackTrace}", MessageType.Error);
DebugLog.ToConsole($"Error - Exception in OnRemoval() for {item.GetType()}. Message : {e.InnerException.Message}, Stack trace : {e.InnerException.StackTrace}", MessageType.Error);
}
}
DebugLog.DebugWrite($"Removing {typeof(TWorldObject).Name} : {WorldObjects.Count(x => x is TWorldObject)} instances.");
@ -130,7 +147,12 @@ namespace QSB.WorldSync
DebugLog.ToConsole($"Error - No QSBOrbSlot found for {slot.name}!", MessageType.Error);
return;
}
var orbSync = OrbSyncList.First(x => x.AttachedOrb == affectingOrb);
var orbSync = OrbSyncList.FirstOrDefault(x => x.AttachedOrb == affectingOrb);
if (orbSync == null)
{
DebugLog.ToConsole($"Error - No NomaiOrbTransformSync found for {affectingOrb.name} (For slot {slot.name})!", MessageType.Error);
return;
}
if (orbSync.HasAuthority)
{
qsbSlot.HandleEvent(state, OldOrbList.IndexOf(affectingOrb));

View File

@ -0,0 +1,26 @@
using System.Collections.Generic;
using UnityEngine;
namespace QSB.WorldSync
{
public abstract class WorldObjectManager : MonoBehaviour
{
private static readonly List<WorldObjectManager> _managers = new List<WorldObjectManager>();
public virtual void Awake()
=> _managers.Add(this);
public virtual void OnDestroy()
=> _managers.Remove(this);
public static void Rebuild(OWScene scene)
{
foreach (var manager in _managers)
{
manager.RebuildWorldObjects(scene);
}
}
protected abstract void RebuildWorldObjects(OWScene scene);
}
}