diff --git a/QSB/Anglerfish/AnglerManager.cs b/QSB/Anglerfish/AnglerManager.cs index b425a317..c5abe84b 100644 --- a/QSB/Anglerfish/AnglerManager.cs +++ b/QSB/Anglerfish/AnglerManager.cs @@ -6,6 +6,8 @@ namespace QSB.Anglerfish { public class AnglerManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + public static readonly List Anglers = new(); protected override void RebuildWorldObjects(OWScene scene) diff --git a/QSB/Anglerfish/WorldObjects/QSBAngler.cs b/QSB/Anglerfish/WorldObjects/QSBAngler.cs index a44edff3..ca3b6970 100644 --- a/QSB/Anglerfish/WorldObjects/QSBAngler.cs +++ b/QSB/Anglerfish/WorldObjects/QSBAngler.cs @@ -1,4 +1,5 @@ using QSB.Anglerfish.TransformSync; +using QSB.Utility; using QSB.WorldSync; using QuantumUNET; using UnityEngine; @@ -17,7 +18,7 @@ namespace QSB.Anglerfish.WorldObjects { if (QSBCore.IsHost) { - QNetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.Instance.AnglerPrefab)); + Object.Instantiate(QSBNetworkManager.Instance.AnglerPrefab).SpawnWithServerAuthority(); } StartDelayedReady(); diff --git a/QSB/Animation/NPC/CharacterAnimManager.cs b/QSB/Animation/NPC/CharacterAnimManager.cs index 8db8da3a..0d4f0ebc 100644 --- a/QSB/Animation/NPC/CharacterAnimManager.cs +++ b/QSB/Animation/NPC/CharacterAnimManager.cs @@ -1,11 +1,13 @@ using QSB.Animation.NPC.WorldObjects; using QSB.WorldSync; -using System.Linq; namespace QSB.Animation.NPC { internal class CharacterAnimManager : WorldObjectManager { + // im assuming this is used in the eye as well + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + protected override void RebuildWorldObjects(OWScene scene) { QSBWorldSync.Init(); @@ -13,6 +15,7 @@ namespace QSB.Animation.NPC QSBWorldSync.Init(); QSBWorldSync.Init(); QSBWorldSync.Init(); + QSBWorldSync.Init(); //MOVE : this is the wrong place to put this... move it to Conversations? QSBWorldSync.OldDialogueTrees.Clear(); diff --git a/QSB/Animation/NPC/WorldObjects/NpcAnimController.cs b/QSB/Animation/NPC/WorldObjects/NpcAnimController.cs index 74a41b5d..7285dc47 100644 --- a/QSB/Animation/NPC/WorldObjects/NpcAnimController.cs +++ b/QSB/Animation/NPC/WorldObjects/NpcAnimController.cs @@ -15,6 +15,7 @@ namespace QSB.Animation.NPC.WorldObjects public virtual void EndConversation() => GetDialogueTree().RaiseEvent("OnEndConversation"); - public abstract bool InConversation(); + public virtual bool InConversation() + => false; } } diff --git a/QSB/Animation/NPC/WorldObjects/QSBHearthianRecorderEffects.cs b/QSB/Animation/NPC/WorldObjects/QSBHearthianRecorderEffects.cs index ca4303a4..4b92ff96 100644 --- a/QSB/Animation/NPC/WorldObjects/QSBHearthianRecorderEffects.cs +++ b/QSB/Animation/NPC/WorldObjects/QSBHearthianRecorderEffects.cs @@ -2,9 +2,6 @@ { internal class QSBHearthianRecorderEffects : NpcAnimController { - public override bool InConversation() - => AttachedObject._characterDialogueTree.InConversation(); - public override CharacterDialogueTree GetDialogueTree() => AttachedObject._characterDialogueTree; } diff --git a/QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs b/QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs index 945fbc6b..516af21a 100644 --- a/QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs +++ b/QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs @@ -4,8 +4,5 @@ { public override CharacterDialogueTree GetDialogueTree() => AttachedObject._characterDialogueTree; - - public override bool InConversation() - => AttachedObject._solanumAnimController._animator.GetBool("ListeningToPlayer"); } } diff --git a/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs b/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs index 52700584..c792028e 100644 --- a/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs +++ b/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs @@ -4,8 +4,5 @@ { public override CharacterDialogueTree GetDialogueTree() => AttachedObject._dialogueSystem; - - public override bool InConversation() - => AttachedObject._talking; } } diff --git a/QSB/Animation/NPC/WorldObjects/QSBTravelerEyeController.cs b/QSB/Animation/NPC/WorldObjects/QSBTravelerEyeController.cs new file mode 100644 index 00000000..a42d3ee1 --- /dev/null +++ b/QSB/Animation/NPC/WorldObjects/QSBTravelerEyeController.cs @@ -0,0 +1,8 @@ +namespace QSB.Animation.NPC.WorldObjects +{ + internal class QSBTravelerEyeController : NpcAnimController + { + public override CharacterDialogueTree GetDialogueTree() + => AttachedObject._dialogueTree; + } +} diff --git a/QSB/CampfireSync/CampfireManager.cs b/QSB/CampfireSync/CampfireManager.cs index 3bcba948..20678239 100644 --- a/QSB/CampfireSync/CampfireManager.cs +++ b/QSB/CampfireSync/CampfireManager.cs @@ -5,6 +5,8 @@ namespace QSB.CampfireSync { internal class CampfireManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init(); } diff --git a/QSB/ClientServerStateSync/ClientState.cs b/QSB/ClientServerStateSync/ClientState.cs index a2b65586..2b0f3b4d 100644 --- a/QSB/ClientServerStateSync/ClientState.cs +++ b/QSB/ClientServerStateSync/ClientState.cs @@ -7,8 +7,8 @@ AliveInSolarSystem, DeadInSolarSystem, AliveInEye, - WaitingForOthersToDieInSolarSystem, - WaitingForOthersToReadyInSolarSystem, + WaitingForOthersToDie, + WaitingForOthersToBeReady, WatchingLongCredits, WatchingShortCredits } diff --git a/QSB/ClientServerStateSync/ClientStateManager.cs b/QSB/ClientServerStateSync/ClientStateManager.cs index 5246b8eb..9ae38f84 100644 --- a/QSB/ClientServerStateSync/ClientStateManager.cs +++ b/QSB/ClientServerStateSync/ClientStateManager.cs @@ -64,7 +64,7 @@ namespace QSB.ClientServerStateSync if (oldScene == OWScene.SolarSystem) { // reloading scene - newState = ClientState.WaitingForOthersToReadyInSolarSystem; + newState = ClientState.WaitingForOthersToBeReady; } else { @@ -98,21 +98,21 @@ namespace QSB.ClientServerStateSync case OWScene.SolarSystem: if (serverState == ServerState.WaitingForAllPlayersToDie) { - newState = ClientState.WaitingForOthersToReadyInSolarSystem; + newState = ClientState.WaitingForOthersToBeReady; break; } if (oldScene == OWScene.SolarSystem) { // reloading scene - newState = ClientState.WaitingForOthersToReadyInSolarSystem; + newState = ClientState.WaitingForOthersToBeReady; } else { // loading in from title screen if (serverState == ServerState.WaitingForAllPlayersToReady) { - newState = ClientState.WaitingForOthersToReadyInSolarSystem; + newState = ClientState.WaitingForOthersToBeReady; } else { @@ -122,7 +122,14 @@ namespace QSB.ClientServerStateSync break; case OWScene.EyeOfTheUniverse: - newState = ClientState.WaitingForOthersToReadyInSolarSystem; + if (serverState == ServerState.WaitingForAllPlayersToReady) + { + newState = ClientState.WaitingForOthersToBeReady; + } + else + { + newState = ClientState.AliveInEye; + } break; default: newState = ClientState.NotLoaded; diff --git a/QSB/ClientServerStateSync/ServerStateManager.cs b/QSB/ClientServerStateSync/ServerStateManager.cs index cc278f67..7aba7d01 100644 --- a/QSB/ClientServerStateSync/ServerStateManager.cs +++ b/QSB/ClientServerStateSync/ServerStateManager.cs @@ -128,7 +128,7 @@ namespace QSB.ClientServerStateSync if (_currentState == ServerState.WaitingForAllPlayersToReady) { if (QSBPlayerManager.PlayerList.All(x - => x.State is ClientState.WaitingForOthersToReadyInSolarSystem + => x.State is ClientState.WaitingForOthersToBeReady or ClientState.AliveInSolarSystem or ClientState.AliveInEye)) { diff --git a/QSB/ConversationSync/ConversationManager.cs b/QSB/ConversationSync/ConversationManager.cs index c72884bb..c69712be 100644 --- a/QSB/ConversationSync/ConversationManager.cs +++ b/QSB/ConversationSync/ConversationManager.cs @@ -13,6 +13,8 @@ namespace QSB.ConversationSync { public class ConversationManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + public static ConversationManager Instance { get; private set; } public Dictionary BoxMappings { get; } = new Dictionary(); diff --git a/QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs b/QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs index a2fa5f5e..4b7f9083 100644 --- a/QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs +++ b/QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs @@ -5,6 +5,9 @@ namespace QSB.EchoesOfTheEye.AirlockSync { internal class AirlockManager : WorldObjectManager { + // is this used in the prisoner sequence in the eye? + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init(); } } diff --git a/QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs b/QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs index 0ffd4f8a..06b6ecfd 100644 --- a/QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs +++ b/QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs @@ -5,6 +5,9 @@ namespace QSB.EchoesOfTheEye.LightSensorSync { internal class LightSensorManager : WorldObjectManager { + // see AirlockManager question + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init(); } } diff --git a/QSB/ElevatorSync/ElevatorManager.cs b/QSB/ElevatorSync/ElevatorManager.cs index d58b8f5a..8c2bc15f 100644 --- a/QSB/ElevatorSync/ElevatorManager.cs +++ b/QSB/ElevatorSync/ElevatorManager.cs @@ -5,6 +5,8 @@ namespace QSB.ElevatorSync { public class ElevatorManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init(); } diff --git a/QSB/Events/EventNames.cs b/QSB/Events/EventNames.cs index 29b07940..eb4ad4b0 100644 --- a/QSB/Events/EventNames.cs +++ b/QSB/Events/EventNames.cs @@ -106,5 +106,6 @@ public const string QSBRequestGameDetails = nameof(QSBRequestGameDetails); public const string QSBGameDetails = nameof(QSBGameDetails); public const string QSBEnterRemoteDialogue = nameof(QSBEnterRemoteDialogue); + public const string QSBGatherInstrument = nameof(QSBGatherInstrument); } } diff --git a/QSB/EyeOfTheUniverse/InstrumentSync/Event/GatherInstrumentEvent.cs b/QSB/EyeOfTheUniverse/InstrumentSync/Event/GatherInstrumentEvent.cs new file mode 100644 index 00000000..0eb55b56 --- /dev/null +++ b/QSB/EyeOfTheUniverse/InstrumentSync/Event/GatherInstrumentEvent.cs @@ -0,0 +1,29 @@ +using QSB.Events; +using QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects; +using QSB.WorldSync; +using QSB.WorldSync.Events; + +namespace QSB.EyeOfTheUniverse.InstrumentSync.Event +{ + internal class GatherInstrumentEvent : QSBEvent + { + public override bool RequireWorldObjectsReady => true; + + public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBGatherInstrument, Handler); + public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBGatherInstrument, Handler); + + private void Handler(QSBQuantumInstrument instrument) => SendEvent(CreateMessage(instrument)); + + private BoolWorldObjectMessage CreateMessage(QSBQuantumInstrument instrument) => new() + { + AboutId = LocalPlayerId, + ObjectId = instrument.ObjectId + }; + + public override void OnReceiveRemote(bool isHost, WorldObjectMessage message) + { + var qsbObj = QSBWorldSync.GetWorldFromId(message.ObjectId); + qsbObj.AttachedObject.Gather(); + } + } +} diff --git a/QSB/EyeOfTheUniverse/InstrumentSync/Patches/QuantumInstrumentPatches.cs b/QSB/EyeOfTheUniverse/InstrumentSync/Patches/QuantumInstrumentPatches.cs new file mode 100644 index 00000000..9e641193 --- /dev/null +++ b/QSB/EyeOfTheUniverse/InstrumentSync/Patches/QuantumInstrumentPatches.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using QSB.Events; +using QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects; +using QSB.Patches; +using QSB.WorldSync; +namespace QSB.EyeOfTheUniverse.InstrumentSync.Patches +{ + internal class QuantumInstrumentPatches : QSBPatch + { + public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; + + [HarmonyPostfix] + [HarmonyPatch(typeof(QuantumInstrument), nameof(QuantumInstrument.OnPressInteract))] + public static void Gather(QuantumInstrument __instance) + => QSBEventManager.FireEvent(EventNames.QSBGatherInstrument, QSBWorldSync.GetWorldFromUnity(__instance)); + } +} diff --git a/QSB/EyeOfTheUniverse/InstrumentSync/QuantumInstrumentManager.cs b/QSB/EyeOfTheUniverse/InstrumentSync/QuantumInstrumentManager.cs new file mode 100644 index 00000000..5f382b3a --- /dev/null +++ b/QSB/EyeOfTheUniverse/InstrumentSync/QuantumInstrumentManager.cs @@ -0,0 +1,13 @@ +using QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects; +using QSB.WorldSync; + +namespace QSB.EyeOfTheUniverse.InstrumentSync +{ + internal class QuantumInstrumentManager : WorldObjectManager + { + public override WorldObjectType WorldObjectType => WorldObjectType.Eye; + + protected override void RebuildWorldObjects(OWScene scene) + => QSBWorldSync.Init(); + } +} diff --git a/QSB/EyeOfTheUniverse/InstrumentSync/WorldObjects/QSBQuantumInstrument.cs b/QSB/EyeOfTheUniverse/InstrumentSync/WorldObjects/QSBQuantumInstrument.cs new file mode 100644 index 00000000..3cd3e380 --- /dev/null +++ b/QSB/EyeOfTheUniverse/InstrumentSync/WorldObjects/QSBQuantumInstrument.cs @@ -0,0 +1,8 @@ +using QSB.WorldSync; + +namespace QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects +{ + internal class QSBQuantumInstrument : WorldObject + { + } +} diff --git a/QSB/GeyserSync/GeyserManager.cs b/QSB/GeyserSync/GeyserManager.cs index 75667201..5a8bbfdd 100644 --- a/QSB/GeyserSync/GeyserManager.cs +++ b/QSB/GeyserSync/GeyserManager.cs @@ -5,6 +5,8 @@ namespace QSB.GeyserSync { public class GeyserManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init(); } diff --git a/QSB/ItemSync/ItemManager.cs b/QSB/ItemSync/ItemManager.cs index 55f43a26..8f4e1253 100644 --- a/QSB/ItemSync/ItemManager.cs +++ b/QSB/ItemSync/ItemManager.cs @@ -8,6 +8,8 @@ namespace QSB.ItemSync { internal class ItemManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + protected override void RebuildWorldObjects(OWScene scene) { DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Info); diff --git a/QSB/JellyfishSync/JellyfishManager.cs b/QSB/JellyfishSync/JellyfishManager.cs index 47e64e88..369c9e22 100644 --- a/QSB/JellyfishSync/JellyfishManager.cs +++ b/QSB/JellyfishSync/JellyfishManager.cs @@ -6,6 +6,8 @@ namespace QSB.JellyfishSync { public class JellyfishManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + public static readonly List Jellyfish = new(); protected override void RebuildWorldObjects(OWScene scene) diff --git a/QSB/JellyfishSync/WorldObjects/QSBJellyfish.cs b/QSB/JellyfishSync/WorldObjects/QSBJellyfish.cs index 47fad09d..3ca72758 100644 --- a/QSB/JellyfishSync/WorldObjects/QSBJellyfish.cs +++ b/QSB/JellyfishSync/WorldObjects/QSBJellyfish.cs @@ -1,4 +1,5 @@ using QSB.JellyfishSync.TransformSync; +using QSB.Utility; using QSB.WorldSync; using QuantumUNET; using UnityEngine; @@ -16,7 +17,7 @@ namespace QSB.JellyfishSync.WorldObjects if (QSBCore.IsHost) { - QNetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.Instance.JellyfishPrefab)); + Object.Instantiate(QSBNetworkManager.Instance.JellyfishPrefab).SpawnWithServerAuthority(); } StartDelayedReady(); diff --git a/QSB/MeteorSync/MeteorManager.cs b/QSB/MeteorSync/MeteorManager.cs index b3b26bcb..7ddfbc9d 100644 --- a/QSB/MeteorSync/MeteorManager.cs +++ b/QSB/MeteorSync/MeteorManager.cs @@ -6,6 +6,8 @@ namespace QSB.MeteorSync { public class MeteorManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + public static WhiteHoleVolume WhiteHoleVolume; protected override void RebuildWorldObjects(OWScene scene) diff --git a/QSB/OrbSync/OrbManager.cs b/QSB/OrbSync/OrbManager.cs index ffcad1b2..3a652bc9 100644 --- a/QSB/OrbSync/OrbManager.cs +++ b/QSB/OrbSync/OrbManager.cs @@ -6,6 +6,8 @@ namespace QSB.OrbSync { public class OrbManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + public static readonly List Orbs = new(); protected override void RebuildWorldObjects(OWScene scene) diff --git a/QSB/OrbSync/WorldObjects/QSBOrb.cs b/QSB/OrbSync/WorldObjects/QSBOrb.cs index a24bf28e..5def3f59 100644 --- a/QSB/OrbSync/WorldObjects/QSBOrb.cs +++ b/QSB/OrbSync/WorldObjects/QSBOrb.cs @@ -14,7 +14,7 @@ namespace QSB.OrbSync.WorldObjects { if (QSBCore.IsHost) { - QNetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.Instance.OrbPrefab)); + Object.Instantiate(QSBNetworkManager.Instance.OrbPrefab).SpawnWithServerAuthority(); } StartDelayedReady(); diff --git a/QSB/Patches/QSBPatchManager.cs b/QSB/Patches/QSBPatchManager.cs index 43fd4ab7..04832658 100644 --- a/QSB/Patches/QSBPatchManager.cs +++ b/QSB/Patches/QSBPatchManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using HarmonyLib; diff --git a/QSB/PoolSync/PoolManager.cs b/QSB/PoolSync/PoolManager.cs index 59edc022..247145ab 100644 --- a/QSB/PoolSync/PoolManager.cs +++ b/QSB/PoolSync/PoolManager.cs @@ -4,6 +4,8 @@ namespace QSB.PoolSync { internal class PoolManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + protected override void RebuildWorldObjects(OWScene scene) { foreach (var streaming in QSBWorldSync.GetUnityObjects()) diff --git a/QSB/QuantumSync/QuantumManager.cs b/QSB/QuantumSync/QuantumManager.cs index b335ad37..879e9a94 100644 --- a/QSB/QuantumSync/QuantumManager.cs +++ b/QSB/QuantumSync/QuantumManager.cs @@ -14,6 +14,8 @@ namespace QSB.QuantumSync { internal class QuantumManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + public static QuantumShrine Shrine { get; private set; } public static QuantumManager Instance { get; private set; } diff --git a/QSB/SaveSync/Events/GameStateEvent.cs b/QSB/SaveSync/Events/GameStateEvent.cs index cfcc5545..ac8bc4d8 100644 --- a/QSB/SaveSync/Events/GameStateEvent.cs +++ b/QSB/SaveSync/Events/GameStateEvent.cs @@ -14,17 +14,23 @@ namespace QSB.SaveSync.Events private void Handler(uint toId) => SendEvent(CreateMessage(toId)); - private GameStateMessage CreateMessage(uint toId) => new() + private GameStateMessage CreateMessage(uint toId) { - AboutId = LocalPlayerId, - ForId = toId, - InSolarSystem = QSBSceneManager.CurrentScene == OWScene.SolarSystem, - InEye = QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse, - LaunchCodesGiven = PlayerData.KnowsLaunchCodes(), - LoopCount = StandaloneProfileManager.SharedInstance.currentProfileGameSave.loopCount, - KnownFrequencies = StandaloneProfileManager.SharedInstance.currentProfileGameSave.knownFrequencies, - KnownSignals = StandaloneProfileManager.SharedInstance.currentProfileGameSave.knownSignals - }; + var gameSave = StandaloneProfileManager.SharedInstance.currentProfileGameSave; + return new() + { + AboutId = LocalPlayerId, + ForId = toId, + InSolarSystem = QSBSceneManager.CurrentScene == OWScene.SolarSystem, + InEye = QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse, + WarpedToTheEye = gameSave.warpedToTheEye, + SecondsRemainingOnWarp = gameSave.secondsRemainingOnWarp, + LaunchCodesGiven = PlayerData.KnowsLaunchCodes(), + LoopCount = gameSave.loopCount, + KnownFrequencies = gameSave.knownFrequencies, + KnownSignals = gameSave.knownSignals, + }; + } public override void OnReceiveRemote(bool isHost, GameStateMessage message) { @@ -40,6 +46,8 @@ namespace QSB.SaveSync.Events gameSave.loopCount = message.LoopCount; gameSave.knownFrequencies = message.KnownFrequencies; gameSave.knownSignals = message.KnownSignals; + gameSave.warpedToTheEye = message.WarpedToTheEye; + gameSave.secondsRemainingOnWarp = message.SecondsRemainingOnWarp; PlayerData.SetPersistentCondition("LAUNCH_CODES_GIVEN", message.LaunchCodesGiven); diff --git a/QSB/SaveSync/Events/GameStateMessage.cs b/QSB/SaveSync/Events/GameStateMessage.cs index 74755a57..945bd72d 100644 --- a/QSB/SaveSync/Events/GameStateMessage.cs +++ b/QSB/SaveSync/Events/GameStateMessage.cs @@ -9,6 +9,8 @@ namespace QSB.SaveSync.Events { public bool InSolarSystem { get; set; } public bool InEye { get; set; } + public bool WarpedToTheEye { get; set; } + public float SecondsRemainingOnWarp { get; set; } public bool LaunchCodesGiven { get; set; } public int LoopCount { get; set; } public bool[] KnownFrequencies { get; set; } @@ -19,6 +21,8 @@ namespace QSB.SaveSync.Events base.Deserialize(reader); InSolarSystem = reader.ReadBoolean(); InEye = reader.ReadBoolean(); + WarpedToTheEye = reader.ReadBoolean(); + SecondsRemainingOnWarp = reader.ReadSingle(); LaunchCodesGiven = reader.ReadBoolean(); LoopCount = reader.ReadInt32(); @@ -46,6 +50,8 @@ namespace QSB.SaveSync.Events base.Serialize(writer); writer.Write(InSolarSystem); writer.Write(InEye); + writer.Write(WarpedToTheEye); + writer.Write(SecondsRemainingOnWarp); writer.Write(LaunchCodesGiven); writer.Write(LoopCount); diff --git a/QSB/SectorSync/QSBSectorManager.cs b/QSB/SectorSync/QSBSectorManager.cs index db4e4127..c12401cf 100644 --- a/QSB/SectorSync/QSBSectorManager.cs +++ b/QSB/SectorSync/QSBSectorManager.cs @@ -11,6 +11,8 @@ namespace QSB.SectorSync { public class QSBSectorManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + public static QSBSectorManager Instance { get; private set; } public bool IsReady { get; private set; } public readonly List FakeSectors = new(); diff --git a/QSB/ShipSync/ShipManager.cs b/QSB/ShipSync/ShipManager.cs index 31204387..ce56b39d 100644 --- a/QSB/ShipSync/ShipManager.cs +++ b/QSB/ShipSync/ShipManager.cs @@ -14,6 +14,8 @@ namespace QSB.ShipSync { internal class ShipManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + public static ShipManager Instance; public InteractZone HatchInteractZone; diff --git a/QSB/TimeSync/WakeUpSync.cs b/QSB/TimeSync/WakeUpSync.cs index cc2b8a0e..0deba009 100644 --- a/QSB/TimeSync/WakeUpSync.cs +++ b/QSB/TimeSync/WakeUpSync.cs @@ -273,7 +273,7 @@ namespace QSB.TimeSync var serverState = ServerStateManager.Instance.GetServerState(); var clientState = QSBPlayerManager.LocalPlayer.State; - if (serverState == ServerState.WaitingForAllPlayersToReady && clientState == ClientState.WaitingForOthersToReadyInSolarSystem) + if (serverState == ServerState.WaitingForAllPlayersToReady && clientState == ClientState.WaitingForOthersToBeReady) { if (CurrentState != State.Pausing) { @@ -289,7 +289,7 @@ namespace QSB.TimeSync } } - if (serverState == ServerState.WaitingForAllPlayersToDie && clientState == ClientState.WaitingForOthersToReadyInSolarSystem) + if (serverState == ServerState.WaitingForAllPlayersToDie && clientState == ClientState.WaitingForOthersToBeReady) { if (CurrentState == State.Pausing && (PauseReason)CurrentReason == PauseReason.WaitingForAllPlayersToBeReady) { @@ -352,12 +352,12 @@ namespace QSB.TimeSync StartPausing(PauseReason.ServerNotStarted); } - if (serverState == ServerState.WaitingForAllPlayersToReady && CurrentState != State.Pausing && clientState == ClientState.WaitingForOthersToReadyInSolarSystem) + if (serverState == ServerState.WaitingForAllPlayersToReady && CurrentState != State.Pausing && clientState == ClientState.WaitingForOthersToBeReady) { StartPausing(PauseReason.WaitingForAllPlayersToBeReady); } - if (serverState == ServerState.WaitingForAllPlayersToDie && clientState == ClientState.WaitingForOthersToReadyInSolarSystem) + if (serverState == ServerState.WaitingForAllPlayersToDie && clientState == ClientState.WaitingForOthersToBeReady) { StartPausing(PauseReason.WaitingForAllPlayersToBeReady); } diff --git a/QSB/Tools/ProbeLauncherTool/ProbeLauncherManager.cs b/QSB/Tools/ProbeLauncherTool/ProbeLauncherManager.cs index d96d9604..eed8efa9 100644 --- a/QSB/Tools/ProbeLauncherTool/ProbeLauncherManager.cs +++ b/QSB/Tools/ProbeLauncherTool/ProbeLauncherManager.cs @@ -5,6 +5,8 @@ namespace QSB.Tools.ProbeLauncherTool { internal class ProbeLauncherManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init(typeof(PlayerProbeLauncher)); } diff --git a/QSB/Tools/TranslatorTool/TranslationSync/SpiralManager.cs b/QSB/Tools/TranslatorTool/TranslationSync/SpiralManager.cs index c5c24f7a..9d3b6bad 100644 --- a/QSB/Tools/TranslatorTool/TranslationSync/SpiralManager.cs +++ b/QSB/Tools/TranslatorTool/TranslationSync/SpiralManager.cs @@ -5,6 +5,8 @@ namespace QSB.Tools.TranslatorTool.TranslationSync { internal class SpiralManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.Both; + protected override void RebuildWorldObjects(OWScene scene) { QSBWorldSync.Init(); diff --git a/QSB/TornadoSync/TornadoManager.cs b/QSB/TornadoSync/TornadoManager.cs index e07ec13d..85b865c8 100644 --- a/QSB/TornadoSync/TornadoManager.cs +++ b/QSB/TornadoSync/TornadoManager.cs @@ -8,6 +8,8 @@ namespace QSB.TornadoSync { public class TornadoManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + protected override void RebuildWorldObjects(OWScene scene) { QSBWorldSync.Init(); diff --git a/QSB/Utility/DebugActions.cs b/QSB/Utility/DebugActions.cs index bf5aa9ff..c091f5c8 100644 --- a/QSB/Utility/DebugActions.cs +++ b/QSB/Utility/DebugActions.cs @@ -39,6 +39,45 @@ namespace QSB.Utility return; } + /* + * 1 - Warp to first player + * 2 - Set time flowing + * 3 - + * 4 - Damage ship electricals + * 5 - Trigger supernova + * 6 - + * 7 - Warp to vessel + * 8 - Place warp core into vessel + * 9 - Load eye scene + * 0 - + */ + + if (Keyboard.current[Key.Numpad1].wasPressedThisFrame) + { + var otherPlayer = QSBPlayerManager.PlayerList.FirstOrDefault(x => x.PlayerId != QSBPlayerManager.LocalPlayerId); + if (otherPlayer != null && otherPlayer.Body != null) + { + var playerBody = Locator.GetPlayerBody(); + playerBody.WarpToPositionRotation(otherPlayer.Body.transform.position, otherPlayer.Body.transform.rotation); + var parentBody = otherPlayer.TransformSync?.ReferenceSector?.AttachedObject?.GetOWRigidbody(); + if (parentBody != null) + { + playerBody.SetVelocity(parentBody.GetVelocity()); + playerBody.SetAngularVelocity(parentBody.GetAngularVelocity()); + } + else + { + playerBody.SetVelocity(Vector3.zero); + playerBody.SetAngularVelocity(Vector3.zero); + } + } + } + + if (Keyboard.current[Key.Numpad1].wasPressedThisFrame) + { + TimeLoop._isTimeFlowing = true; + } + if (Keyboard.current[Key.Numpad4].wasPressedThisFrame) { DamageShipElectricalSystem(); @@ -64,27 +103,6 @@ namespace QSB.Utility PlayerData.SaveWarpedToTheEye(60); LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToWhite); } - - if (Keyboard.current[Key.Numpad1].wasPressedThisFrame) - { - var otherPlayer = QSBPlayerManager.PlayerList.FirstOrDefault(x => x.PlayerId != QSBPlayerManager.LocalPlayerId); - if (otherPlayer != null && otherPlayer.Body != null) - { - var playerBody = Locator.GetPlayerBody(); - playerBody.WarpToPositionRotation(otherPlayer.Body.transform.position, otherPlayer.Body.transform.rotation); - var parentBody = otherPlayer.TransformSync?.ReferenceSector?.AttachedObject?.GetOWRigidbody(); - if (parentBody != null) - { - playerBody.SetVelocity(parentBody.GetVelocity()); - playerBody.SetAngularVelocity(parentBody.GetAngularVelocity()); - } - else - { - playerBody.SetVelocity(Vector3.zero); - playerBody.SetAngularVelocity(Vector3.zero); - } - } - } } } } diff --git a/QSB/Utility/IsExternalInit.cs b/QSB/Utility/IsExternalInit.cs new file mode 100644 index 00000000..6fe43b48 --- /dev/null +++ b/QSB/Utility/IsExternalInit.cs @@ -0,0 +1,13 @@ +namespace System.Runtime.CompilerServices +{ + public static class IsExternalInit + { + /* + * You might think this class isn't used. And you'd be right! + * But if you delete this file, the project will refuse to compile. + * This is because IsExternalInit is only included in net5 and above. + * So we have to create this dummy file to make it happy. + * Yay. + */ + } +} \ No newline at end of file diff --git a/QSB/WorldSync/QSBWorldSync.cs b/QSB/WorldSync/QSBWorldSync.cs index ff17f5c7..03edba0a 100644 --- a/QSB/WorldSync/QSBWorldSync.cs +++ b/QSB/WorldSync/QSBWorldSync.cs @@ -53,19 +53,19 @@ namespace QSB.WorldSync return default; } - if (!WorldObjectsToUnityObjects.TryGetValue(unityObject, out var returnObject)) + if (!WorldObjectsToUnityObjects.TryGetValue(unityObject, out var worldObject)) { DebugLog.ToConsole($"Error - WorldObjectsToUnityObjects does not contain \"{unityObject.name}\"! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}, Stacktrace:\r\n{Environment.StackTrace}", MessageType.Error); return default; } - if (returnObject == null) + if (worldObject == null) { DebugLog.ToConsole($"Error - World object for unity object {unityObject.name} is null! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}, Stacktrace:\r\n{Environment.StackTrace}", MessageType.Error); return default; } - return (TWorldObject)returnObject; + return (TWorldObject)worldObject; } public static int GetIdFromUnity(MonoBehaviour unityObject) diff --git a/QSB/WorldSync/WorldObject.cs b/QSB/WorldSync/WorldObject.cs index b2d699b7..42a5c3b0 100644 --- a/QSB/WorldSync/WorldObject.cs +++ b/QSB/WorldSync/WorldObject.cs @@ -6,8 +6,8 @@ namespace QSB.WorldSync public abstract class WorldObject : IWorldObject where T : MonoBehaviour { - public int ObjectId { get; set; } - public T AttachedObject { get; set; } + public int ObjectId { get; init; } + public T AttachedObject { get; init; } public string Name => AttachedObject == null ? "" : AttachedObject.name; public string LogName => $"{QSBPlayerManager.LocalPlayerId}.{ObjectId}:{GetType().Name}"; diff --git a/QSB/WorldSync/WorldObjectManager.cs b/QSB/WorldSync/WorldObjectManager.cs index bd70ab9f..f0e6c0f3 100644 --- a/QSB/WorldSync/WorldObjectManager.cs +++ b/QSB/WorldSync/WorldObjectManager.cs @@ -7,6 +7,13 @@ using UnityEngine; namespace QSB.WorldSync { + public enum WorldObjectType + { + Both, + SolarSystem, + Eye + } + public abstract class WorldObjectManager : MonoBehaviour { private static readonly List _managers = new(); @@ -21,6 +28,11 @@ namespace QSB.WorldSync /// public static bool AllObjectsReady { get; private set; } + /// + /// when the scene does not match the type, this manager will not build its world objects + /// + public abstract WorldObjectType WorldObjectType { get; } + public virtual void Awake() { QSBSceneManager.OnSceneLoaded += OnSceneLoaded; @@ -73,6 +85,14 @@ namespace QSB.WorldSync AllObjectsReady = false; foreach (var manager in _managers) { + switch (manager.WorldObjectType) + { + case WorldObjectType.SolarSystem when QSBSceneManager.CurrentScene != OWScene.SolarSystem: + case WorldObjectType.Eye when QSBSceneManager.CurrentScene != OWScene.EyeOfTheUniverse: + DebugLog.DebugWrite($"skipping {manager.GetType().Name} as it is type {manager.WorldObjectType} and scene is {QSBSceneManager.CurrentScene}"); + continue; + } + try { DebugLog.DebugWrite($"Rebuilding {manager.GetType().Name}", MessageType.Info); diff --git a/QSB/ZeroGCaveSync/ZeroGCaveManager.cs b/QSB/ZeroGCaveSync/ZeroGCaveManager.cs index e635712d..206ccc74 100644 --- a/QSB/ZeroGCaveSync/ZeroGCaveManager.cs +++ b/QSB/ZeroGCaveSync/ZeroGCaveManager.cs @@ -5,6 +5,8 @@ namespace QSB.ZeroGCaveSync { internal class ZeroGCaveManager : WorldObjectManager { + public override WorldObjectType WorldObjectType => WorldObjectType.SolarSystem; + protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init(); } diff --git a/QSB/debugsettings.json b/QSB/debugsettings.json index 931e7da6..e8d2e410 100644 --- a/QSB/debugsettings.json +++ b/QSB/debugsettings.json @@ -1,8 +1,8 @@ { "debugMode": false, "drawLines": false, - "showQuantumVisibilityObjects": false, - "showQuantumDebugBoxes": false, + "showQuantumVisibilityObjects": true, + "showQuantumDebugBoxes": true, "avoidTimeSync": false, "skipTitleScreen": false } \ No newline at end of file