mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-29 09:32:38 +00:00
Sync probe launcher rotation, allow one person to use at a time
This commit is contained in:
parent
efa54ba7c8
commit
875d269781
@ -8,7 +8,7 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye;
|
||||
|
||||
internal abstract class RotatingElementsVariableSyncer<TWorldObject> : BaseVariableSyncer<Quaternion[]>, ILinkedNetworkBehaviour
|
||||
public abstract class RotatingElementsVariableSyncer<TWorldObject> : BaseVariableSyncer<Quaternion[]>, ILinkedNetworkBehaviour
|
||||
where TWorldObject : IWorldObject
|
||||
{
|
||||
public override void OnStartClient()
|
||||
|
@ -24,6 +24,7 @@ using QSB.Player.TransformSync;
|
||||
using QSB.SaveSync;
|
||||
using QSB.ShipSync;
|
||||
using QSB.ShipSync.TransformSync;
|
||||
using QSB.StationaryProbeLauncherSync.TransformSync;
|
||||
using QSB.Syncs.Occasional;
|
||||
using QSB.TimeSync;
|
||||
using QSB.Tools.ProbeTool.TransformSync;
|
||||
@ -56,6 +57,7 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
|
||||
public GameObject ShipModulePrefab { get; private set; }
|
||||
public GameObject ShipLegPrefab { get; private set; }
|
||||
public GameObject ModelShipPrefab { get; private set; }
|
||||
public GameObject StationaryProbeLauncherPrefab { get; private set; }
|
||||
private string PlayerName { get; set; }
|
||||
|
||||
private GameObject _probePrefab;
|
||||
@ -149,6 +151,9 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
|
||||
ModelShipPrefab = MakeNewNetworkObject(14, "NetworkModelShip", typeof(ModelShipTransformSync));
|
||||
spawnPrefabs.Add(ModelShipPrefab);
|
||||
|
||||
StationaryProbeLauncherPrefab = MakeNewNetworkObject(15, "NetworkStationaryProbeLauncher", typeof(StationaryProbeLauncherTransformSync));
|
||||
spawnPrefabs.Add(StationaryProbeLauncherPrefab);
|
||||
|
||||
ConfigureNetworkManager();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.StationaryProbeLauncherSync.WorldObjects;
|
||||
|
||||
namespace QSB.StationaryProbeLauncherSync.Messages;
|
||||
|
||||
public class StationaryProbeLauncherMessage : QSBWorldObjectMessage<QSBStationaryProbeLauncher, bool>
|
||||
{
|
||||
public StationaryProbeLauncherMessage(bool inUse) : base(inUse) { }
|
||||
|
||||
public override void OnReceiveRemote() => WorldObject.OnUseStateChanged(Data, From);
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using QSB.StationaryProbeLauncherSync.Messages;
|
||||
using QSB.StationaryProbeLauncherSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.StationaryProbeLauncherSync.Patches;
|
||||
|
||||
[HarmonyPatch]
|
||||
public class StationaryProbeLauncherPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(StationaryProbeLauncher), nameof(StationaryProbeLauncher.FinishExitSequence))]
|
||||
public static void StationaryProbeLauncher_FinishExitSequence(Elevator __instance)
|
||||
{
|
||||
if (Remote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var qsbStationaryProbe = __instance.GetWorldObject<QSBStationaryProbeLauncher>();
|
||||
qsbStationaryProbe.SendMessage(new StationaryProbeLauncherMessage(false));
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using QSB.StationaryProbeLauncherSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Threading;
|
||||
|
||||
namespace QSB.StationaryProbeLauncherSync;
|
||||
|
||||
public class StationaryProbeLauncherManager : WorldObjectManager
|
||||
{
|
||||
public override WorldObjectScene WorldObjectScene => WorldObjectScene.SolarSystem;
|
||||
|
||||
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct) =>
|
||||
QSBWorldSync.Init<QSBStationaryProbeLauncher, ProbeLauncher>(QSBWorldSync.GetUnityObjects<StationaryProbeLauncher>().SortDeterministic());
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
using Mirror;
|
||||
using QSB.EchoesOfTheEye;
|
||||
using QSB.StationaryProbeLauncherSync.WorldObjects;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.StationaryProbeLauncherSync.TransformSync;
|
||||
|
||||
public class StationaryProbeLauncherTransformSync : RotatingElementsVariableSyncer<QSBStationaryProbeLauncher>
|
||||
{
|
||||
protected override Transform[] RotatingElements => new Transform[] { WorldObject.AttachedObject.transform };
|
||||
|
||||
protected override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var launcher = (WorldObject.AttachedObject as StationaryProbeLauncher);
|
||||
|
||||
writer.Write(launcher.transform.localRotation);
|
||||
writer.Write(launcher._degreesX);
|
||||
writer.Write(launcher._degreesY);
|
||||
writer.Write(launcher._audioSource.GetLocalVolume());
|
||||
}
|
||||
|
||||
protected override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var launcher = (WorldObject.AttachedObject as StationaryProbeLauncher);
|
||||
|
||||
launcher.transform.localRotation = reader.Read<Quaternion>();
|
||||
launcher._degreesX = reader.Read<float>();
|
||||
launcher._degreesY = reader.Read<float>();
|
||||
launcher._audioSource.SetLocalVolume(reader.Read<float>());
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Mirror;
|
||||
using QSB.AuthoritySync;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.StationaryProbeLauncherSync.Messages;
|
||||
using QSB.StationaryProbeLauncherSync.TransformSync;
|
||||
using QSB.Tools.ProbeLauncherTool.WorldObjects;
|
||||
using QSB.Utility.LinkedWorldObject;
|
||||
using System.Threading;
|
||||
|
||||
namespace QSB.StationaryProbeLauncherSync.WorldObjects;
|
||||
|
||||
public class QSBStationaryProbeLauncher : QSBProbeLauncher, ILinkedWorldObject<StationaryProbeLauncherTransformSync>
|
||||
{
|
||||
public StationaryProbeLauncherTransformSync NetworkBehaviour { get; private set; }
|
||||
public void SetNetworkBehaviour(NetworkBehaviour networkBehaviour) => NetworkBehaviour = (StationaryProbeLauncherTransformSync)networkBehaviour;
|
||||
|
||||
private bool _isInit;
|
||||
private bool _isInUse;
|
||||
private Shape _shape;
|
||||
private StationaryProbeLauncher _stationaryProbeLauncher;
|
||||
|
||||
public override async UniTask Init(CancellationToken ct)
|
||||
{
|
||||
_isInit = true;
|
||||
|
||||
// This is implemented by inheriting LinkedWorldObject normally, however I want to inherit from QSBProbeLauncher
|
||||
// Else we'd have to redo the sync for the effects
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
this.SpawnLinked(QSBNetworkManager.singleton.StationaryProbeLauncherPrefab, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await this.WaitForLink(ct);
|
||||
}
|
||||
|
||||
await base.Init(ct);
|
||||
|
||||
_stationaryProbeLauncher = AttachedObject as StationaryProbeLauncher;
|
||||
_shape = ((InteractZone)_stationaryProbeLauncher._interactVolume)._trigger._shape;
|
||||
|
||||
_stationaryProbeLauncher._interactVolume.OnPressInteract += OnPressInteract;
|
||||
|
||||
UpdateUse();
|
||||
}
|
||||
|
||||
public override void OnRemoval()
|
||||
{
|
||||
_isInit = false;
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
NetworkServer.Destroy(NetworkBehaviour.gameObject);
|
||||
}
|
||||
|
||||
base.OnRemoval();
|
||||
|
||||
_stationaryProbeLauncher._interactVolume.OnPressInteract -= OnPressInteract;
|
||||
}
|
||||
|
||||
private void OnPressInteract()
|
||||
{
|
||||
// Whoever is using it needs authority to be able to rotate it
|
||||
// If this is a client they'll get authority from the host when the message is received otherwise give now
|
||||
if (QSBCore.IsHost) NetworkBehaviour.netIdentity.SetAuthority(QSBPlayerManager.LocalPlayerId);
|
||||
|
||||
_isInUse = true;
|
||||
this.SendMessage(new StationaryProbeLauncherMessage(_isInUse));
|
||||
}
|
||||
|
||||
public override void SendInitialState(uint to)
|
||||
{
|
||||
base.SendInitialState(to);
|
||||
|
||||
this.SendMessage(new StationaryProbeLauncherMessage(_isInUse) { To = to });
|
||||
}
|
||||
|
||||
private void UpdateUse()
|
||||
{
|
||||
// Stuff can be null when its sending the initial state info
|
||||
if (!_isInit) return;
|
||||
|
||||
// If somebody is using this we disable the interaction shape
|
||||
_shape.enabled = !_isInUse;
|
||||
|
||||
if (_isInUse)
|
||||
{
|
||||
_stationaryProbeLauncher._audioSource.SetLocalVolume(0f);
|
||||
_stationaryProbeLauncher._audioSource.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
_stationaryProbeLauncher._audioSource.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnUseStateChanged(bool isInUse, uint from)
|
||||
{
|
||||
// Whoever is using it needs authority to be able to rotate it
|
||||
if (QSBCore.IsHost) NetworkBehaviour.netIdentity.SetAuthority(from);
|
||||
|
||||
_isInUse = isInUse;
|
||||
|
||||
UpdateUse();
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ internal class ProbeLauncherManager : WorldObjectManager
|
||||
|
||||
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct)
|
||||
{
|
||||
QSBWorldSync.Init<QSBProbeLauncher, ProbeLauncher>(typeof(PlayerProbeLauncher));
|
||||
QSBWorldSync.Init<QSBProbeLauncher, ProbeLauncher>(typeof(PlayerProbeLauncher), typeof(StationaryProbeLauncher));
|
||||
if (scene == OWScene.SolarSystem)
|
||||
{
|
||||
QSBWorldSync.Init<QSBProbeLauncher, ProbeLauncher>(new[]
|
||||
|
Loading…
x
Reference in New Issue
Block a user