diff --git a/QSB/AssetBundles/network b/QSB/AssetBundles/network index 8de1b060..6efbc1fc 100644 Binary files a/QSB/AssetBundles/network and b/QSB/AssetBundles/network differ diff --git a/QSB/AssetBundles/network.manifest b/QSB/AssetBundles/network.manifest index 12010b7b..6e5ee70c 100644 --- a/QSB/AssetBundles/network.manifest +++ b/QSB/AssetBundles/network.manifest @@ -1,12 +1,12 @@ ManifestFileVersion: 0 -CRC: 1923832523 +CRC: 551896829 Hashes: AssetFileHash: serializedVersion: 2 - Hash: 81ec87f15e23d40065c2c9c6a04728d0 + Hash: 0fa5758f55c8803c7ba77a52ab2c9488 TypeTreeHash: serializedVersion: 2 - Hash: 0f787b84b284b04ad8bc62b6e0ef5423 + Hash: 927887737c4cf3ead147733f47326ca9 HashAppended: 0 ClassTypes: - Class: 1 @@ -29,6 +29,8 @@ ClassTypes: Script: {fileID: -1164351254, guid: 27687deae413b90448366870cb0de502, type: 3} - Class: 114 Script: {fileID: -1309757293, guid: 27687deae413b90448366870cb0de502, type: 3} +- Class: 114 + Script: {fileID: 316226861, guid: 27687deae413b90448366870cb0de502, type: 3} - Class: 114 Script: {fileID: 78926581, guid: 27687deae413b90448366870cb0de502, type: 3} - Class: 114 @@ -47,6 +49,7 @@ ClassTypes: Script: {instanceID: 0} SerializeReferenceClassIdentifiers: [] Assets: +- Assets/Prefabs/NetworkJellyfish.prefab - Assets/Prefabs/NetworkProbe.prefab - Assets/Prefabs/NETWORK_Player_Body.prefab - Assets/Prefabs/NetworkOrb.prefab diff --git a/QSB/JellyfishSync/JellyfishManager.cs b/QSB/JellyfishSync/JellyfishManager.cs new file mode 100644 index 00000000..f85fa7cd --- /dev/null +++ b/QSB/JellyfishSync/JellyfishManager.cs @@ -0,0 +1,11 @@ +using QSB.JellyfishSync.WorldObjects; +using QSB.WorldSync; + +namespace QSB.JellyfishSync +{ + public class JellyfishManager : WorldObjectManager + { + protected override void RebuildWorldObjects(OWScene scene) + => QSBWorldSync.Init(); + } +} diff --git a/QSB/JellyfishSync/Patches/JellyfishPatches.cs b/QSB/JellyfishSync/Patches/JellyfishPatches.cs new file mode 100644 index 00000000..c194fcc5 --- /dev/null +++ b/QSB/JellyfishSync/Patches/JellyfishPatches.cs @@ -0,0 +1,40 @@ +using HarmonyLib; +using QSB.Events; +using QSB.JellyfishSync.WorldObjects; +using QSB.Patches; +using QSB.WorldSync; + +namespace QSB.JellyfishSync.Patches +{ + public class JellyfishPatches : QSBPatch + { + public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; + + [HarmonyPrefix] + [HarmonyPatch(typeof(JellyfishController), nameof(JellyfishController.OnSectorOccupantsUpdated))] + public static bool OnSectorOccupantsUpdated(JellyfishController __instance) + { + if (!QSBCore.WorldObjectsReady) + { + return false; + } + var qsbJellyfish = QSBWorldSync.GetWorldFromUnity(__instance); + + if (!__instance.gameObject.activeSelf && __instance._sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe | DynamicOccupant.Ship)) + { + __instance.gameObject.SetActive(true); + __instance._jellyfishBody.Unsuspend(); + QSBEventManager.FireEvent(EventNames.QSBSuspendChange, qsbJellyfish.TransformSync.NetIdentity, true); + return false; + } + if (__instance.gameObject.activeSelf && !__instance._sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe | DynamicOccupant.Ship)) + { + __instance._jellyfishBody.Suspend(); + __instance.gameObject.SetActive(false); + QSBEventManager.FireEvent(EventNames.QSBSuspendChange, qsbJellyfish.TransformSync.NetIdentity, true); + } + + return false; + } + } +} diff --git a/QSB/JellyfishSync/TransformSync/JellyfishTransformSync.cs b/QSB/JellyfishSync/TransformSync/JellyfishTransformSync.cs new file mode 100644 index 00000000..5f3a614e --- /dev/null +++ b/QSB/JellyfishSync/TransformSync/JellyfishTransformSync.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using QSB.JellyfishSync.WorldObjects; +using QSB.Syncs.Unsectored.Rigidbodies; +using QSB.WorldSync; +using QuantumUNET.Transport; + +namespace QSB.JellyfishSync.TransformSync +{ + public class JellyfishTransformSync : UnsectoredRigidbodySync + { + public override bool IsReady => QSBCore.WorldObjectsReady; + public override bool UseInterpolation => false; + + private QSBJellyfish _qsbJellyfish; + private static readonly List _instances = new(); + + protected override OWRigidbody GetRigidbody() + => _qsbJellyfish.AttachedObject._jellyfishBody; + + private static int _nextId; + private int _id; + + public override void Start() + { + _id = _nextId++; + base.Start(); + } + + protected override void OnDestroy() + { + _nextId--; + base.OnDestroy(); + } + + public override float GetNetworkSendInterval() => 1; + + protected override void Init() + { + _qsbJellyfish = QSBWorldSync.GetWorldFromId(_id); + _qsbJellyfish.TransformSync = this; + + base.Init(); + SetReferenceTransform(_qsbJellyfish.AttachedObject._planetBody.transform); + } + + private bool _shouldUpdate; + + public override void DeserializeTransform(QNetworkReader reader, bool initialState) + { + base.DeserializeTransform(reader, initialState); + _shouldUpdate = true; + } + + protected override bool UpdateTransform() + { + if (HasAuthority) + { + return base.UpdateTransform(); + } + + if (!_shouldUpdate) + { + return false; + } + + _shouldUpdate = false; + return base.UpdateTransform(); + } + } +} diff --git a/QSB/JellyfishSync/WorldObjects/QSBJellyfish.cs b/QSB/JellyfishSync/WorldObjects/QSBJellyfish.cs new file mode 100644 index 00000000..9641f551 --- /dev/null +++ b/QSB/JellyfishSync/WorldObjects/QSBJellyfish.cs @@ -0,0 +1,40 @@ +using QSB.Events; +using QSB.JellyfishSync.TransformSync; +using QSB.SuspendableSync; +using QSB.WorldSync; +using QuantumUNET; +using UnityEngine; + +namespace QSB.JellyfishSync.WorldObjects +{ + public class QSBJellyfish : WorldObject + { + public JellyfishTransformSync TransformSync; + + public override void Init(JellyfishController attachedObject, int id) + { + ObjectId = id; + AttachedObject = attachedObject; + + if (QSBCore.IsHost) + { + QNetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.Instance.JellyfishPrefab)); + QSBCore.UnityEvents.RunWhen(() => TransformSync, () => + SuspendableManager.Register(TransformSync.NetIdentity)); + } + + // for when you host/connect mid-game + QSBCore.UnityEvents.RunWhen(() => TransformSync, () => + QSBEventManager.FireEvent(EventNames.QSBSuspendChange, TransformSync.NetIdentity, AttachedObject._jellyfishBody.IsSuspended())); + } + + public override void OnRemoval() + { + if (QSBCore.IsHost) + { + SuspendableManager.Unregister(TransformSync.NetIdentity); + QNetworkServer.Destroy(TransformSync.gameObject); + } + } + } +} diff --git a/QSB/Patches/QSBPatchManager.cs b/QSB/Patches/QSBPatchManager.cs index 8d3745cb..9712fdb5 100644 --- a/QSB/Patches/QSBPatchManager.cs +++ b/QSB/Patches/QSBPatchManager.cs @@ -1,4 +1,7 @@ -using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using HarmonyLib; using OWML.Common; using QSB.Anglerfish.Patches; using QSB.Animation.NPC.Patches; @@ -11,6 +14,7 @@ using QSB.ElevatorSync.Patches; using QSB.GeyserSync.Patches; using QSB.Inputs.Patches; using QSB.ItemSync.Patches; +using QSB.JellyfishSync.Patches; using QSB.LogSync.Patches; using QSB.MeteorSync.Patches; using QSB.OrbSync.Patches; @@ -27,9 +31,6 @@ using QSB.Tools.SignalscopeTool.FrequencySync.Patches; using QSB.Tools.TranslatorTool.TranslationSync.Patches; using QSB.Utility; using QSB.ZeroGCaveSync.Patches; -using System; -using System.Collections.Generic; -using System.Linq; namespace QSB.Patches { @@ -78,6 +79,7 @@ namespace QSB.Patches new AnglerPatches(), new MeteorClientPatches(), new MeteorServerPatches(), + new JellyfishPatches(), new TravelerControllerPatches(), new ZeroGCavePatches() }; diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs index 97e13472..93dd0944 100644 --- a/QSB/QSBCore.cs +++ b/QSB/QSBCore.cs @@ -1,4 +1,5 @@ -using OWML.Common; +using System.Linq; +using OWML.Common; using OWML.ModHelper; using OWML.ModHelper.Input; using QSB.Anglerfish; @@ -11,6 +12,7 @@ using QSB.ElevatorSync; using QSB.GeyserSync; using QSB.Inputs; using QSB.ItemSync; +using QSB.JellyfishSync; using QSB.Menus; using QSB.MeteorSync; using QSB.OrbSync; @@ -32,7 +34,6 @@ using QSB.WorldSync; using QSB.ZeroGCaveSync; using QuantumUNET; using QuantumUNET.Components; -using System.Linq; using UnityEngine; /* @@ -141,6 +142,7 @@ namespace QSB gameObject.AddComponent(); gameObject.AddComponent(); gameObject.AddComponent(); + gameObject.AddComponent(); gameObject.AddComponent(); DebugBoxManager.Init(); diff --git a/QSB/QSBNetworkManager.cs b/QSB/QSBNetworkManager.cs index 57b5f4d3..a9f5c970 100644 --- a/QSB/QSBNetworkManager.cs +++ b/QSB/QSBNetworkManager.cs @@ -35,6 +35,7 @@ namespace QSB public GameObject OrbPrefab { get; private set; } public GameObject ShipPrefab { get; private set; } public GameObject AnglerPrefab { get; private set; } + public GameObject JellyfishPrefab { get; private set; } public string PlayerName { get; private set; } private const int MaxConnections = 128; @@ -66,6 +67,9 @@ namespace QSB AnglerPrefab = _assetBundle.LoadAsset("assets/Prefabs/networkangler.prefab"); spawnPrefabs.Add(AnglerPrefab); + JellyfishPrefab = _assetBundle.LoadAsset("assets/Prefabs/networkjellyfish.prefab"); + spawnPrefabs.Add(JellyfishPrefab); + ConfigureNetworkManager(); }