mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-03-12 04:14:08 +00:00
commit
4a4daedc80
@ -93,6 +93,7 @@ public class AnimationSync : PlayerSyncObject
|
|||||||
SetSuitState(QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse);
|
SetSuitState(QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse);
|
||||||
InitAccelerationSync();
|
InitAccelerationSync();
|
||||||
ThrusterManager.CreateRemotePlayerVFX(Player);
|
ThrusterManager.CreateRemotePlayerVFX(Player);
|
||||||
|
ThrusterManager.CreateRemotePlayerSFX(Player);
|
||||||
|
|
||||||
Delay.RunWhen(() => Player.CameraBody != null,
|
Delay.RunWhen(() => Player.CameraBody != null,
|
||||||
() => body.GetComponent<PlayerHeadRotationSync>().Init(Player.CameraBody.transform));
|
() => body.GetComponent<PlayerHeadRotationSync>().Init(Player.CameraBody.transform));
|
||||||
|
@ -37,6 +37,15 @@ public class PlayerSuitMessage : QSBMessage<bool>
|
|||||||
|
|
||||||
var animator = player.AnimationSync;
|
var animator = player.AnimationSync;
|
||||||
animator.SetSuitState(Data);
|
animator.SetSuitState(Data);
|
||||||
|
|
||||||
|
if (player.SuitedUp)
|
||||||
|
{
|
||||||
|
player.AudioController.PlayWearSuit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.AudioController.PlayRemoveSuit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnReceiveLocal()
|
public override void OnReceiveLocal()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using QSB.Player;
|
using QSB.Audio;
|
||||||
|
using QSB.Player;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace QSB.Animation.Player.Thrusters;
|
namespace QSB.Animation.Player.Thrusters;
|
||||||
@ -14,6 +15,11 @@ internal static class ThrusterManager
|
|||||||
InitParticleControllers(newVfx, player);
|
InitParticleControllers(newVfx, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void CreateRemotePlayerSFX(PlayerInfo player)
|
||||||
|
{
|
||||||
|
player.Body.GetComponentInChildren<QSBJetpackThrusterAudio>(true)?.Init(player);
|
||||||
|
}
|
||||||
|
|
||||||
private static void InitFlameControllers(GameObject root, PlayerInfo player)
|
private static void InitFlameControllers(GameObject root, PlayerInfo player)
|
||||||
{
|
{
|
||||||
var existingControllers = root.GetComponentsInChildren<RemoteThrusterFlameController>(true);
|
var existingControllers = root.GetComponentsInChildren<RemoteThrusterFlameController>(true);
|
||||||
|
16
QSB/Audio/Messages/PlayerAudioControllerOneShotMessage.cs
Normal file
16
QSB/Audio/Messages/PlayerAudioControllerOneShotMessage.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Player;
|
||||||
|
using QSB.WorldSync;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Messages;
|
||||||
|
|
||||||
|
|
||||||
|
public class PlayerAudioControllerOneShotMessage : QSBMessage<(AudioType audioType, uint userID, float pitch, float volume)>
|
||||||
|
{
|
||||||
|
public PlayerAudioControllerOneShotMessage(AudioType audioType, uint userID, float pitch = 1f, float volume = 1f) : base((audioType, userID, pitch, volume)) { }
|
||||||
|
|
||||||
|
public override bool ShouldReceive => QSBWorldSync.AllObjectsReady;
|
||||||
|
|
||||||
|
public override void OnReceiveRemote() =>
|
||||||
|
QSBPlayerManager.GetPlayer(Data.userID)?.AudioController?.PlayOneShot(Data.audioType, Data.pitch, Data.volume);
|
||||||
|
}
|
16
QSB/Audio/Messages/PlayerMovementAudioFootstepMessage.cs
Normal file
16
QSB/Audio/Messages/PlayerMovementAudioFootstepMessage.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Player;
|
||||||
|
using QSB.WorldSync;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Messages;
|
||||||
|
|
||||||
|
|
||||||
|
public class PlayerMovementAudioFootstepMessage : QSBMessage<(AudioType audioType, float pitch, uint userID)>
|
||||||
|
{
|
||||||
|
public PlayerMovementAudioFootstepMessage(AudioType audioType, float pitch, uint userID) : base((audioType, pitch, userID)) { }
|
||||||
|
|
||||||
|
public override bool ShouldReceive => QSBWorldSync.AllObjectsReady;
|
||||||
|
|
||||||
|
public override void OnReceiveRemote() =>
|
||||||
|
QSBPlayerManager.GetPlayer(Data.userID)?.AudioController?.PlayFootstep(Data.audioType, Data.pitch);
|
||||||
|
}
|
16
QSB/Audio/Messages/PlayerMovementAudioJumpMessage.cs
Normal file
16
QSB/Audio/Messages/PlayerMovementAudioJumpMessage.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Player;
|
||||||
|
using QSB.WorldSync;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Messages;
|
||||||
|
|
||||||
|
|
||||||
|
public class PlayerMovementAudioJumpMessage : QSBMessage<(float pitch, uint userID)>
|
||||||
|
{
|
||||||
|
public PlayerMovementAudioJumpMessage(float pitch, uint userID) : base((pitch, userID)) { }
|
||||||
|
|
||||||
|
public override bool ShouldReceive => QSBWorldSync.AllObjectsReady;
|
||||||
|
|
||||||
|
public override void OnReceiveRemote() =>
|
||||||
|
QSBPlayerManager.GetPlayer(Data.userID)?.AudioController?.OnJump(Data.pitch);
|
||||||
|
}
|
21
QSB/Audio/Messages/ShipThrusterAudioOneShotMessage.cs
Normal file
21
QSB/Audio/Messages/ShipThrusterAudioOneShotMessage.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.ShipSync;
|
||||||
|
using QSB.WorldSync;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Messages;
|
||||||
|
|
||||||
|
|
||||||
|
public class ShipThrusterAudioOneShotMessage : QSBMessage<(AudioType audioType, float pitch, float volume)>
|
||||||
|
{
|
||||||
|
public ShipThrusterAudioOneShotMessage(AudioType audioType, float pitch = 1f, float volume = 1f) : base((audioType, pitch, volume)) { }
|
||||||
|
|
||||||
|
public override bool ShouldReceive => QSBWorldSync.AllObjectsReady;
|
||||||
|
|
||||||
|
public override void OnReceiveRemote()
|
||||||
|
{
|
||||||
|
var source = ShipManager.Instance.ShipThrusterAudio._rotationalSource;
|
||||||
|
source.pitch = Data.pitch;
|
||||||
|
source.PlayOneShot(Data.audioType, Data.volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
QSB/Audio/Patches/PlayerAudioControllerPatches.cs
Normal file
36
QSB/Audio/Patches/PlayerAudioControllerPatches.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.Audio.Messages;
|
||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Patches;
|
||||||
|
using QSB.Player;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Patches;
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
internal class PlayerAudioControllerPatches : QSBPatch
|
||||||
|
{
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||||
|
|
||||||
|
private static void PlayOneShot(AudioType audioType) =>
|
||||||
|
new PlayerAudioControllerOneShotMessage(audioType, QSBPlayerManager.LocalPlayerId).Send();
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerAudioController), nameof(PlayerAudioController.PlayMarshmallowEat))]
|
||||||
|
public static void PlayerAudioController_PlayMarshmallowEat() => PlayOneShot(AudioType.ToolMarshmallowEat);
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerAudioController), nameof(PlayerAudioController.PlayMarshmallowEatBurnt))]
|
||||||
|
public static void PlayerAudioController_PlayMarshmallowEatBurnt() => PlayOneShot(AudioType.ToolMarshmallowEatBurnt);
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerAudioController), nameof(PlayerAudioController.PlayPatchPuncture))]
|
||||||
|
public static void PlayerAudioController_PlayPatchPuncture() => PlayOneShot(AudioType.PlayerSuitPatchPuncture);
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerAudioController), nameof(PlayerAudioController.PlayMedkit))]
|
||||||
|
public static void PlayerAudioController_PlayMedkit() => PlayOneShot(AudioType.ShipCabinUseMedkit);
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerAudioController), nameof(PlayerAudioController.PlayRefuel))]
|
||||||
|
public static void PlayerAudioController_PlayRefuel() => PlayOneShot(AudioType.ShipCabinUseRefueller);
|
||||||
|
}
|
40
QSB/Audio/Patches/PlayerImpactAudioPatches.cs
Normal file
40
QSB/Audio/Patches/PlayerImpactAudioPatches.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.Audio.Messages;
|
||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Patches;
|
||||||
|
using QSB.Player;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Patches;
|
||||||
|
|
||||||
|
internal class PlayerImpactAudioPatches : QSBPatch
|
||||||
|
{
|
||||||
|
// Since we patch Start we do it when the mod starts, else it won't run
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnModStart;
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerImpactAudio), nameof(PlayerImpactAudio.Start))]
|
||||||
|
public static void PlayerImpactAudio_Start(PlayerImpactAudio __instance)
|
||||||
|
{
|
||||||
|
__instance.gameObject.AddComponent<QSBAudioSourceOneShotTracker>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(PlayerImpactAudio), nameof(PlayerImpactAudio.OnImpact))]
|
||||||
|
public static void PlayerImpactAudio_OnImpact_Prefix(PlayerImpactAudio __instance) =>
|
||||||
|
// First we reset in case no audio is actually played
|
||||||
|
__instance.gameObject.GetComponent<QSBAudioSourceOneShotTracker>()?.Reset();
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerImpactAudio), nameof(PlayerImpactAudio.OnImpact))]
|
||||||
|
public static void PlayerImpactAudio_OnImpact_Postfix(PlayerImpactAudio __instance)
|
||||||
|
{
|
||||||
|
var tracker = __instance.gameObject.GetComponent<QSBAudioSourceOneShotTracker>();
|
||||||
|
if (tracker)
|
||||||
|
{
|
||||||
|
if (tracker.LastPlayed != AudioType.None)
|
||||||
|
{
|
||||||
|
new PlayerAudioControllerOneShotMessage(tracker.LastPlayed, QSBPlayerManager.LocalPlayerId, tracker.Pitch, tracker.Volume).Send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
QSB/Audio/Patches/PlayerMovementAudioPatches.cs
Normal file
32
QSB/Audio/Patches/PlayerMovementAudioPatches.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.Audio.Messages;
|
||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Patches;
|
||||||
|
using QSB.Player;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Patches;
|
||||||
|
|
||||||
|
internal class PlayerMovementAudioPatches : QSBPatch
|
||||||
|
{
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerMovementAudio), nameof(PlayerMovementAudio.PlayFootstep))]
|
||||||
|
public static void PlayerMovementAudio_PlayFootstep(PlayerMovementAudio __instance)
|
||||||
|
{
|
||||||
|
var underwater = !PlayerState.IsCameraUnderwater() && __instance._fluidDetector.InFluidType(FluidVolume.Type.WATER);
|
||||||
|
var audioType = underwater ? AudioType.MovementShallowWaterFootstep : PlayerMovementAudio.GetFootstepAudioType(__instance._playerController.GetGroundSurface());
|
||||||
|
|
||||||
|
if (audioType != AudioType.None)
|
||||||
|
{
|
||||||
|
new PlayerMovementAudioFootstepMessage(audioType, __instance._footstepAudio.pitch, QSBPlayerManager.LocalPlayerId).Send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(PlayerMovementAudio), nameof(PlayerMovementAudio.OnJump))]
|
||||||
|
public static void PlayerMovementAudio_OnJump(PlayerMovementAudio __instance)
|
||||||
|
{
|
||||||
|
new PlayerMovementAudioJumpMessage(__instance._jumpAudio.pitch, QSBPlayerManager.LocalPlayerId).Send();
|
||||||
|
}
|
||||||
|
}
|
42
QSB/Audio/Patches/ThrusterAudioPatches.cs
Normal file
42
QSB/Audio/Patches/ThrusterAudioPatches.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.Audio.Messages;
|
||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Patches;
|
||||||
|
|
||||||
|
namespace QSB.Audio.Patches;
|
||||||
|
|
||||||
|
internal class ThrusterAudioPatches : QSBPatch
|
||||||
|
{
|
||||||
|
// Since we patch Start we do it when the mod starts, else it won't run
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnModStart;
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(ThrusterAudio), nameof(ThrusterAudio.Start))]
|
||||||
|
public static void ThrusterAudio_Start(ThrusterAudio __instance)
|
||||||
|
{
|
||||||
|
__instance._rotationalSource.gameObject.AddComponent<QSBAudioSourceOneShotTracker>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ThrusterAudio), nameof(ThrusterAudio.OnFireRotationalThruster))]
|
||||||
|
public static void ThrusterAudio_OnFireRotationalThruster_Prefix(ThrusterAudio __instance) =>
|
||||||
|
// First we reset in case no audio is actually played
|
||||||
|
__instance._rotationalSource.gameObject.GetComponent<QSBAudioSourceOneShotTracker>()?.Reset();
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(ThrusterAudio), nameof(ThrusterAudio.OnFireRotationalThruster))]
|
||||||
|
public static void ThrusterAudio_OnFireRotationalThruster_Postfix(ThrusterAudio __instance)
|
||||||
|
{
|
||||||
|
if (__instance._rotationalSource.gameObject.TryGetComponent<QSBAudioSourceOneShotTracker>(out var tracker))
|
||||||
|
{
|
||||||
|
if (tracker.LastPlayed != AudioType.None)
|
||||||
|
{
|
||||||
|
if (__instance is ShipThrusterAudio)
|
||||||
|
{
|
||||||
|
new ShipThrusterAudioOneShotMessage(tracker.LastPlayed, tracker.Pitch, tracker.Volume).Send();
|
||||||
|
}
|
||||||
|
// TODO: Apply to player jetpack thruster?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
QSB/Audio/QSBAudioSourceOneShotTracker.cs
Normal file
63
QSB/Audio/QSBAudioSourceOneShotTracker.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.Patches;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace QSB.Audio;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// tracks what audioType was last played on when PlayOneShot is called on an OWAudioSource
|
||||||
|
/// makes it easier to send a message afterwards syncing what was just played
|
||||||
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(OWAudioSource))]
|
||||||
|
public class QSBAudioSourceOneShotTracker : MonoBehaviour
|
||||||
|
{
|
||||||
|
public AudioType LastPlayed { get; internal set; }
|
||||||
|
public float Pitch { get => _source.pitch; }
|
||||||
|
public float Volume { get; internal set; }
|
||||||
|
public int Index { get; internal set; }
|
||||||
|
|
||||||
|
public void Reset() => LastPlayed = AudioType.None;
|
||||||
|
|
||||||
|
private OWAudioSource _source;
|
||||||
|
public void Awake()
|
||||||
|
{
|
||||||
|
_source = GetComponent<OWAudioSource>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(OWAudioSource))]
|
||||||
|
internal class OneShotTrackerPatches : QSBPatch
|
||||||
|
{
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(nameof(OWAudioSource.PlayOneShot), new[] { typeof(AudioType), typeof(float) })]
|
||||||
|
private static void TrackOneShot_AudioType(OWAudioSource __instance, AudioType type, float volume)
|
||||||
|
{
|
||||||
|
var tracker = __instance.gameObject.GetComponent<QSBAudioSourceOneShotTracker>();
|
||||||
|
if (tracker)
|
||||||
|
{
|
||||||
|
tracker.LastPlayed = type;
|
||||||
|
tracker.Volume = volume;
|
||||||
|
tracker.Index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(nameof(OWAudioSource.PlayOneShot), new[] { typeof(AudioType), typeof(int), typeof(float) })]
|
||||||
|
private static void TrackOneShot_AudioType(OWAudioSource __instance, AudioType type, int index, float volume)
|
||||||
|
{
|
||||||
|
var tracker = __instance.gameObject.GetComponent<QSBAudioSourceOneShotTracker>();
|
||||||
|
if (tracker)
|
||||||
|
{
|
||||||
|
tracker.LastPlayed = type;
|
||||||
|
tracker.Volume = volume;
|
||||||
|
tracker.Index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
using QSB.Utility;
|
using QSB.Player;
|
||||||
|
using QSB.Utility;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace QSB.Audio;
|
namespace QSB.Audio;
|
||||||
|
|
||||||
@ -8,4 +10,90 @@ internal class QSBJetpackThrusterAudio : QSBThrusterAudio
|
|||||||
public OWAudioSource _underwaterSource;
|
public OWAudioSource _underwaterSource;
|
||||||
public OWAudioSource _oxygenSource;
|
public OWAudioSource _oxygenSource;
|
||||||
public OWAudioSource _boostSource;
|
public OWAudioSource _boostSource;
|
||||||
|
|
||||||
|
private PlayerInfo _attachedPlayer;
|
||||||
|
private bool _wasBoosting;
|
||||||
|
|
||||||
|
// Taken from Player_Body settings
|
||||||
|
private const float maxTranslationalThrust = 6f;
|
||||||
|
|
||||||
|
private bool _underwater;
|
||||||
|
private RemotePlayerFluidDetector _fluidDetector;
|
||||||
|
|
||||||
|
public void Init(PlayerInfo player)
|
||||||
|
{
|
||||||
|
_attachedPlayer = player;
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
_fluidDetector = player.FluidDetector;
|
||||||
|
_fluidDetector.OnEnterFluidType += OnEnterExitFluidType;
|
||||||
|
_fluidDetector.OnExitFluidType += OnEnterExitFluidType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
if (_fluidDetector != null)
|
||||||
|
{
|
||||||
|
_fluidDetector.OnEnterFluidType -= OnEnterExitFluidType;
|
||||||
|
_fluidDetector.OnExitFluidType -= OnEnterExitFluidType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnterExitFluidType(FluidVolume.Type type)
|
||||||
|
{
|
||||||
|
_underwater = _fluidDetector.InFluidType(FluidVolume.Type.WATER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if(_attachedPlayer == null)
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc = _attachedPlayer.JetpackAcceleration.AccelerationVariableSyncer.Value;
|
||||||
|
var thrustFraction = acc.magnitude / maxTranslationalThrust;
|
||||||
|
|
||||||
|
// TODO: Sync
|
||||||
|
var usingBooster = false;
|
||||||
|
var usingOxygen = false;
|
||||||
|
|
||||||
|
float targetVolume = usingBooster ? 0f : thrustFraction;
|
||||||
|
float targetPan = -acc.x / maxTranslationalThrust * 0.4f;
|
||||||
|
UpdateTranslationalSource(_translationalSource, targetVolume, targetPan, !_underwater && !usingOxygen);
|
||||||
|
UpdateTranslationalSource(_underwaterSource, targetVolume, targetPan, _underwater);
|
||||||
|
UpdateTranslationalSource(_oxygenSource, targetVolume, targetPan, !_underwater && usingOxygen);
|
||||||
|
|
||||||
|
if (!_wasBoosting && usingBooster)
|
||||||
|
{
|
||||||
|
_boostSource.FadeIn(0.3f, false, false, 1f);
|
||||||
|
}
|
||||||
|
else if (_wasBoosting && !usingBooster)
|
||||||
|
{
|
||||||
|
_boostSource.FadeOut(0.3f, OWAudioSource.FadeOutCompleteAction.STOP, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
_wasBoosting = usingBooster;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTranslationalSource(OWAudioSource source, float targetVolume, float targetPan, bool active)
|
||||||
|
{
|
||||||
|
if (!active)
|
||||||
|
{
|
||||||
|
targetVolume = 0f;
|
||||||
|
targetPan = 0f;
|
||||||
|
}
|
||||||
|
if (!source.isPlaying && targetVolume > 0f)
|
||||||
|
{
|
||||||
|
source.SetLocalVolume(0f);
|
||||||
|
source.Play();
|
||||||
|
}
|
||||||
|
else if (source.isPlaying && source.volume <= 0f)
|
||||||
|
{
|
||||||
|
source.Stop();
|
||||||
|
}
|
||||||
|
source.SetLocalVolume(Mathf.MoveTowards(source.GetLocalVolume(), targetVolume, 5f * Time.deltaTime));
|
||||||
|
source.panStereo = Mathf.MoveTowards(source.panStereo, targetPan, 5f * Time.deltaTime);
|
||||||
|
}
|
||||||
}
|
}
|
@ -20,4 +20,25 @@ public class QSBPlayerAudioController : MonoBehaviour
|
|||||||
|
|
||||||
public void PlayTurnOffFlashlight()
|
public void PlayTurnOffFlashlight()
|
||||||
=> _oneShotExternalSource?.PlayOneShot(AudioType.ToolFlashlightOff);
|
=> _oneShotExternalSource?.PlayOneShot(AudioType.ToolFlashlightOff);
|
||||||
|
|
||||||
|
public void PlayWearSuit()
|
||||||
|
=> PlayOneShot(AudioType.PlayerSuitWearSuit);
|
||||||
|
|
||||||
|
public void PlayRemoveSuit()
|
||||||
|
=> PlayOneShot(AudioType.PlayerSuitRemoveSuit);
|
||||||
|
|
||||||
|
public void PlayOneShot(AudioType audioType, float pitch = 1f, float volume = 1f)
|
||||||
|
{
|
||||||
|
if (_oneShotExternalSource)
|
||||||
|
{
|
||||||
|
_oneShotExternalSource.pitch = pitch;
|
||||||
|
_oneShotExternalSource.PlayOneShot(audioType, volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlayFootstep(AudioType audioType, float pitch) =>
|
||||||
|
PlayOneShot(audioType, pitch, 0.7f);
|
||||||
|
|
||||||
|
public void OnJump(float pitch) =>
|
||||||
|
PlayOneShot(AudioType.MovementJump, pitch, 0.7f);
|
||||||
}
|
}
|
@ -33,4 +33,7 @@ public static class OWEvents
|
|||||||
public const string ExitDreamWorld = nameof(ExitDreamWorld);
|
public const string ExitDreamWorld = nameof(ExitDreamWorld);
|
||||||
public const string EnterRemoteFlightConsole = nameof(EnterRemoteFlightConsole);
|
public const string EnterRemoteFlightConsole = nameof(EnterRemoteFlightConsole);
|
||||||
public const string ExitRemoteFlightConsole = nameof(ExitRemoteFlightConsole);
|
public const string ExitRemoteFlightConsole = nameof(ExitRemoteFlightConsole);
|
||||||
|
public const string StartShipIgnition = nameof(StartShipIgnition);
|
||||||
|
public const string CompleteShipIgnition = nameof(CompleteShipIgnition);
|
||||||
|
public const string CancelShipIgnition = nameof(CancelShipIgnition);
|
||||||
}
|
}
|
16
QSB/ModelShip/Messages/CrashModelShipMessage.cs
Normal file
16
QSB/ModelShip/Messages/CrashModelShipMessage.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.WorldSync;
|
||||||
|
|
||||||
|
namespace QSB.ModelShip.Messages;
|
||||||
|
|
||||||
|
internal class CrashModelShipMessage : QSBMessage
|
||||||
|
{
|
||||||
|
public CrashModelShipMessage() { }
|
||||||
|
|
||||||
|
public override void OnReceiveRemote()
|
||||||
|
{
|
||||||
|
var crashBehaviour = QSBWorldSync.GetUnityObject<ModelShipCrashBehavior>();
|
||||||
|
crashBehaviour._crashEffect.Play();
|
||||||
|
crashBehaviour.gameObject.GetComponent<OWAudioSource>().PlayOneShot(AudioType.TH_ModelShipCrash);
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,10 @@ internal class RespawnModelShipMessage : QSBMessage<bool>
|
|||||||
{
|
{
|
||||||
public RespawnModelShipMessage(bool playEffects) : base(playEffects) { }
|
public RespawnModelShipMessage(bool playEffects) : base(playEffects) { }
|
||||||
|
|
||||||
public override void OnReceiveRemote() =>
|
public override void OnReceiveRemote()
|
||||||
QSBPatch.RemoteCall(() => QSBWorldSync.GetUnityObject<RemoteFlightConsole>().RespawnModelShip(Data));
|
{
|
||||||
|
var flightConsole = QSBWorldSync.GetUnityObject<RemoteFlightConsole>();
|
||||||
|
QSBPatch.RemoteCall(() => flightConsole.RespawnModelShip(Data));
|
||||||
|
if (Data) flightConsole._modelShipBody.GetComponent<OWAudioSource>().PlayOneShot(AudioType.TH_RetrieveModelShip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using QSB.AuthoritySync;
|
using QSB.AuthoritySync;
|
||||||
using QSB.Messaging;
|
using QSB.Messaging;
|
||||||
using QSB.ModelShip.TransformSync;
|
using QSB.ModelShip.TransformSync;
|
||||||
|
using QSB.Patches;
|
||||||
using QSB.Player;
|
using QSB.Player;
|
||||||
using QSB.Player.TransformSync;
|
using QSB.Player.TransformSync;
|
||||||
using QSB.Utility;
|
using QSB.Utility;
|
||||||
@ -26,20 +27,14 @@ internal class UseFlightConsoleMessage : QSBMessage<bool>
|
|||||||
|
|
||||||
private UseFlightConsoleMessage(bool active) : base(active) { }
|
private UseFlightConsoleMessage(bool active) : base(active) { }
|
||||||
|
|
||||||
public override void OnReceiveLocal()
|
public override void OnReceiveLocal() => SetCurrentFlyer(From, Data);
|
||||||
{
|
|
||||||
if (QSBCore.IsHost)
|
|
||||||
{
|
|
||||||
ModelShipTransformSync.LocalInstance.netIdentity.SetAuthority(Data
|
|
||||||
? From
|
|
||||||
: QSBPlayerManager.LocalPlayerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnReceiveRemote()
|
public override void OnReceiveRemote()
|
||||||
{
|
{
|
||||||
var console = QSBWorldSync.GetUnityObject<RemoteFlightConsole>();
|
var console = QSBWorldSync.GetUnityObject<RemoteFlightConsole>();
|
||||||
|
|
||||||
|
SetCurrentFlyer(From, Data);
|
||||||
|
|
||||||
if (Data)
|
if (Data)
|
||||||
{
|
{
|
||||||
console._modelShipBody.Unsuspend();
|
console._modelShipBody.Unsuspend();
|
||||||
@ -62,12 +57,24 @@ internal class UseFlightConsoleMessage : QSBMessage<bool>
|
|||||||
|
|
||||||
QSBWorldSync.GetUnityObject<ModelShipController>()._detector.SetActive(Data);
|
QSBWorldSync.GetUnityObject<ModelShipController>()._detector.SetActive(Data);
|
||||||
QSBWorldSync.GetUnityObjects<ModelShipLandingSpot>().ForEach(x => x._owCollider.SetActivation(Data));
|
QSBWorldSync.GetUnityObjects<ModelShipLandingSpot>().ForEach(x => x._owCollider.SetActivation(Data));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCurrentFlyer(uint flyer, bool isFlying)
|
||||||
|
{
|
||||||
|
ModelShipManager.Instance.CurrentFlyer = isFlying
|
||||||
|
? flyer
|
||||||
|
: uint.MaxValue;
|
||||||
|
|
||||||
if (QSBCore.IsHost)
|
if (QSBCore.IsHost)
|
||||||
{
|
{
|
||||||
ModelShipTransformSync.LocalInstance.netIdentity.SetAuthority(Data
|
ModelShipTransformSync.LocalInstance.netIdentity.SetAuthority(isFlying
|
||||||
? From
|
? flyer
|
||||||
: QSBPlayerManager.LocalPlayerId);
|
: QSBPlayerManager.LocalPlayerId); // Host gets authority when its not in use
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Client messes up its position when they start flying it
|
||||||
|
// We can just recall it immediately so its in the right place.
|
||||||
|
var console = QSBWorldSync.GetUnityObject<RemoteFlightConsole>();
|
||||||
|
QSBPatch.RemoteCall(() => console.RespawnModelShip(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,37 @@ internal class ModelShipManager : WorldObjectManager
|
|||||||
public override WorldObjectScene WorldObjectScene => WorldObjectScene.SolarSystem;
|
public override WorldObjectScene WorldObjectScene => WorldObjectScene.SolarSystem;
|
||||||
public override bool DlcOnly => false;
|
public override bool DlcOnly => false;
|
||||||
|
|
||||||
|
public static ModelShipManager Instance;
|
||||||
|
|
||||||
|
public uint CurrentFlyer
|
||||||
|
{
|
||||||
|
get => _currentFlyer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_currentFlyer != uint.MaxValue && value != uint.MaxValue)
|
||||||
|
{
|
||||||
|
DebugLog.ToConsole($"Warning - Trying to set current model ship flyer while someone is still flying? Current:{_currentFlyer}, New:{value}", MessageType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentFlyer = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private uint _currentFlyer = uint.MaxValue;
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct)
|
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (QSBCore.IsHost)
|
if (QSBCore.IsHost)
|
||||||
{
|
{
|
||||||
Instantiate(QSBNetworkManager.singleton.ModelShipPrefab).SpawnWithServerAuthority();
|
Instantiate(QSBNetworkManager.singleton.ModelShipPrefab).SpawnWithServerAuthority();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is 0 by default -> 2D (bad)
|
||||||
|
QSBWorldSync.GetUnityObject<RemoteFlightConsole>()._consoleAudio.spatialBlend = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UnbuildWorldObjects()
|
public override void UnbuildWorldObjects()
|
||||||
|
76
QSB/ModelShip/ModelShipThrusterVariableSyncer.cs
Normal file
76
QSB/ModelShip/ModelShipThrusterVariableSyncer.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using Mirror;
|
||||||
|
using QSB.Player;
|
||||||
|
using QSB.Utility;
|
||||||
|
using QSB.Utility.VariableSync;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace QSB.ModelShip;
|
||||||
|
|
||||||
|
public class ModelShipThrusterVariableSyncer : MonoBehaviour
|
||||||
|
{
|
||||||
|
public Vector3VariableSyncer AccelerationSyncer;
|
||||||
|
|
||||||
|
public ThrusterModel ThrusterModel { get; private set; }
|
||||||
|
private ThrusterAudio _thrusterAudio;
|
||||||
|
public List<ThrusterFlameController> ThrusterFlameControllers = new();
|
||||||
|
public ThrusterWashController ThrusterWashController { get; private set; }
|
||||||
|
|
||||||
|
public void Init(GameObject modelShip)
|
||||||
|
{
|
||||||
|
ThrusterModel = modelShip.GetComponent<ThrusterModel>();
|
||||||
|
_thrusterAudio = modelShip.GetComponentInChildren<ThrusterAudio>();
|
||||||
|
|
||||||
|
ThrusterFlameControllers.Clear();
|
||||||
|
foreach (var item in modelShip.GetComponentsInChildren<ThrusterFlameController>())
|
||||||
|
{
|
||||||
|
ThrusterFlameControllers.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThrusterWashController = modelShip.GetComponentInChildren<ThrusterWashController>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
if (QSBPlayerManager.LocalPlayer.FlyingModelShip)
|
||||||
|
{
|
||||||
|
GetFromShip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AccelerationSyncer.public_HasChanged())
|
||||||
|
{
|
||||||
|
if (AccelerationSyncer.Value == Vector3.zero)
|
||||||
|
{
|
||||||
|
foreach (var item in ThrusterFlameControllers)
|
||||||
|
{
|
||||||
|
item.OnStopTranslationalThrust();
|
||||||
|
}
|
||||||
|
|
||||||
|
_thrusterAudio.OnStopTranslationalThrust();
|
||||||
|
|
||||||
|
ThrusterWashController.OnStopTranslationalThrust();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var item in ThrusterFlameControllers)
|
||||||
|
{
|
||||||
|
item.OnStartTranslationalThrust();
|
||||||
|
}
|
||||||
|
|
||||||
|
_thrusterAudio.OnStartTranslationalThrust();
|
||||||
|
|
||||||
|
ThrusterWashController.OnStartTranslationalThrust();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetFromShip()
|
||||||
|
{
|
||||||
|
if (ThrusterModel)
|
||||||
|
{
|
||||||
|
AccelerationSyncer.Value = ThrusterModel.GetLocalAcceleration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
using QSB.Messaging;
|
using QSB.Messaging;
|
||||||
using QSB.ModelShip.Messages;
|
using QSB.ModelShip.Messages;
|
||||||
using QSB.Patches;
|
using QSB.Patches;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace QSB.ModelShip.Patches;
|
namespace QSB.ModelShip.Patches;
|
||||||
|
|
||||||
@ -20,4 +21,14 @@ public class ModelShipPatches : QSBPatch
|
|||||||
|
|
||||||
new RespawnModelShipMessage(playEffects).Send();
|
new RespawnModelShipMessage(playEffects).Send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModelShipCrashBehavior), nameof(ModelShipCrashBehavior.OnImpact))]
|
||||||
|
private static void ModelShipCrashBehavior_OnImpact(ModelShipCrashBehavior __instance, ImpactData impactData)
|
||||||
|
{
|
||||||
|
if (impactData.speed > 10f && Time.time > __instance._lastCrashTime + 1f)
|
||||||
|
{
|
||||||
|
new CrashModelShipMessage().Send();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
31
QSB/ModelShip/Patches/ModelShipThrusterAudioPatches.cs
Normal file
31
QSB/ModelShip/Patches/ModelShipThrusterAudioPatches.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.ModelShip.TransformSync;
|
||||||
|
using QSB.Patches;
|
||||||
|
using QSB.Player;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace QSB.ModelShip.Patches;
|
||||||
|
|
||||||
|
internal class ModelShipThrusterAudioPatches : QSBPatch
|
||||||
|
{
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ThrusterModel), nameof(ThrusterModel.GetThrustFraction))]
|
||||||
|
public static bool ThrusterModel_GetThrustFraction(ThrusterModel __instance, ref float __result)
|
||||||
|
{
|
||||||
|
if (__instance == ModelShipTransformSync.LocalInstance.ThrusterVariableSyncer.ThrusterModel && !QSBPlayerManager.LocalPlayer.FlyingModelShip)
|
||||||
|
{
|
||||||
|
__result = ModelShipTransformSync.LocalInstance.ThrusterVariableSyncer.AccelerationSyncer.Value.magnitude / __instance._maxTranslationalThrust;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
QSB/ModelShip/Patches/ModelShipThrusterPatches.cs
Normal file
32
QSB/ModelShip/Patches/ModelShipThrusterPatches.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.ModelShip.TransformSync;
|
||||||
|
using QSB.Patches;
|
||||||
|
using QSB.Player;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace QSB.ModelShip.Patches;
|
||||||
|
|
||||||
|
internal class ModelShipThrusterPatches : QSBPatch
|
||||||
|
{
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ThrusterFlameController), nameof(ThrusterFlameController.GetThrustFraction))]
|
||||||
|
public static bool GetThrustFraction(ThrusterFlameController __instance, ref float __result)
|
||||||
|
{
|
||||||
|
var modelShipThrusters = ModelShipTransformSync.LocalInstance?.ThrusterVariableSyncer;
|
||||||
|
|
||||||
|
if (modelShipThrusters == null) return true;
|
||||||
|
|
||||||
|
if (modelShipThrusters.ThrusterFlameControllers.Contains(__instance) && !QSBPlayerManager.LocalPlayer.FlyingModelShip)
|
||||||
|
{
|
||||||
|
if(__instance._thrusterModel.IsThrusterBankEnabled(OWUtilities.GetShipThrusterBank(__instance._thruster)))
|
||||||
|
{
|
||||||
|
__result = Vector3.Dot(modelShipThrusters.AccelerationSyncer.Value, __instance._thrusterFilter);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using QSB.Syncs.Sectored.Rigidbodies;
|
using QSB.ShipSync;
|
||||||
|
using QSB.Syncs.Sectored.Rigidbodies;
|
||||||
using QSB.Utility;
|
using QSB.Utility;
|
||||||
using QSB.WorldSync;
|
using QSB.WorldSync;
|
||||||
|
|
||||||
@ -8,6 +9,8 @@ internal class ModelShipTransformSync : SectoredRigidbodySync
|
|||||||
{
|
{
|
||||||
public static ModelShipTransformSync LocalInstance { get; private set; }
|
public static ModelShipTransformSync LocalInstance { get; private set; }
|
||||||
|
|
||||||
|
public ModelShipThrusterVariableSyncer ThrusterVariableSyncer { get; private set; }
|
||||||
|
|
||||||
public override void OnStartClient()
|
public override void OnStartClient()
|
||||||
{
|
{
|
||||||
base.OnStartClient();
|
base.OnStartClient();
|
||||||
@ -31,6 +34,14 @@ internal class ModelShipTransformSync : SectoredRigidbodySync
|
|||||||
return modelShip;
|
return modelShip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
|
||||||
|
ThrusterVariableSyncer = this.GetRequiredComponent<ModelShipThrusterVariableSyncer>();
|
||||||
|
ThrusterVariableSyncer.Init(AttachedRigidbody.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// replacement for base method
|
/// replacement for base method
|
||||||
/// using SetPos/Rot instead of Move
|
/// using SetPos/Rot instead of Move
|
||||||
|
@ -3,6 +3,7 @@ using QSB.Animation.Player;
|
|||||||
using QSB.Audio;
|
using QSB.Audio;
|
||||||
using QSB.ClientServerStateSync;
|
using QSB.ClientServerStateSync;
|
||||||
using QSB.Messaging;
|
using QSB.Messaging;
|
||||||
|
using QSB.ModelShip;
|
||||||
using QSB.Player.Messages;
|
using QSB.Player.Messages;
|
||||||
using QSB.Player.TransformSync;
|
using QSB.Player.TransformSync;
|
||||||
using QSB.QuantumSync.WorldObjects;
|
using QSB.QuantumSync.WorldObjects;
|
||||||
@ -34,6 +35,7 @@ public partial class PlayerInfo
|
|||||||
public bool IsLocalPlayer => TransformSync.isLocalPlayer; // if TransformSync is ever null, i give permission for nebula to make fun of me about it for the rest of time - johncorby
|
public bool IsLocalPlayer => TransformSync.isLocalPlayer; // if TransformSync is ever null, i give permission for nebula to make fun of me about it for the rest of time - johncorby
|
||||||
public ThrusterLightTracker ThrusterLightTracker;
|
public ThrusterLightTracker ThrusterLightTracker;
|
||||||
public bool FlyingShip => ShipManager.Instance.CurrentFlyer == PlayerId;
|
public bool FlyingShip => ShipManager.Instance.CurrentFlyer == PlayerId;
|
||||||
|
public bool FlyingModelShip => ModelShipManager.Instance.CurrentFlyer == PlayerId;
|
||||||
|
|
||||||
public PlayerInfo(PlayerTransformSync transformSync)
|
public PlayerInfo(PlayerTransformSync transformSync)
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,7 @@ using QSB.EchoesOfTheEye.EclipseElevators.VariableSync;
|
|||||||
using QSB.EchoesOfTheEye.RaftSync.TransformSync;
|
using QSB.EchoesOfTheEye.RaftSync.TransformSync;
|
||||||
using QSB.JellyfishSync.TransformSync;
|
using QSB.JellyfishSync.TransformSync;
|
||||||
using QSB.Messaging;
|
using QSB.Messaging;
|
||||||
|
using QSB.ModelShip;
|
||||||
using QSB.ModelShip.TransformSync;
|
using QSB.ModelShip.TransformSync;
|
||||||
using QSB.OrbSync.Messages;
|
using QSB.OrbSync.Messages;
|
||||||
using QSB.OrbSync.TransformSync;
|
using QSB.OrbSync.TransformSync;
|
||||||
@ -149,6 +150,9 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
|
|||||||
spawnPrefabs.Add(ShipLegPrefab);
|
spawnPrefabs.Add(ShipLegPrefab);
|
||||||
|
|
||||||
ModelShipPrefab = MakeNewNetworkObject(14, "NetworkModelShip", typeof(ModelShipTransformSync));
|
ModelShipPrefab = MakeNewNetworkObject(14, "NetworkModelShip", typeof(ModelShipTransformSync));
|
||||||
|
var modelShipVector3Syncer = ModelShipPrefab.AddComponent<Vector3VariableSyncer>();
|
||||||
|
var modelShipThrusterVariableSyncer = ModelShipPrefab.AddComponent<ModelShipThrusterVariableSyncer>();
|
||||||
|
modelShipThrusterVariableSyncer.AccelerationSyncer = modelShipVector3Syncer;
|
||||||
spawnPrefabs.Add(ModelShipPrefab);
|
spawnPrefabs.Add(ModelShipPrefab);
|
||||||
|
|
||||||
StationaryProbeLauncherPrefab = MakeNewNetworkObject(15, "NetworkStationaryProbeLauncher", typeof(StationaryProbeLauncherVariableSyncer));
|
StationaryProbeLauncherPrefab = MakeNewNetworkObject(15, "NetworkStationaryProbeLauncher", typeof(StationaryProbeLauncherVariableSyncer));
|
||||||
|
@ -53,6 +53,8 @@ public class QSBMarshmallow : MonoBehaviour
|
|||||||
_mallowRenderer.enabled = true;
|
_mallowRenderer.enabled = true;
|
||||||
_mallowState = Marshmallow.MallowState.Default;
|
_mallowState = Marshmallow.MallowState.Default;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
|
||||||
|
_attachedPlayer.AudioController.PlayOneShot(AudioType.ToolMarshmallowReplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disable()
|
public void Disable()
|
||||||
@ -68,6 +70,8 @@ public class QSBMarshmallow : MonoBehaviour
|
|||||||
{
|
{
|
||||||
_fireRenderer.enabled = false;
|
_fireRenderer.enabled = false;
|
||||||
_mallowState = Marshmallow.MallowState.Default;
|
_mallowState = Marshmallow.MallowState.Default;
|
||||||
|
|
||||||
|
_attachedPlayer.AudioController.PlayOneShot(AudioType.ToolMarshmallowBlowOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +146,8 @@ public class QSBMarshmallow : MonoBehaviour
|
|||||||
_toastedFraction = 1f;
|
_toastedFraction = 1f;
|
||||||
_initBurnTime = Time.time;
|
_initBurnTime = Time.time;
|
||||||
_mallowState = Marshmallow.MallowState.Burning;
|
_mallowState = Marshmallow.MallowState.Burning;
|
||||||
|
|
||||||
|
_attachedPlayer.AudioController.PlayOneShot(AudioType.ToolMarshmallowIgnite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,10 +39,12 @@ internal class FlyShipMessage : QSBMessage<bool>
|
|||||||
var shipCockpitController = ShipManager.Instance.CockpitController;
|
var shipCockpitController = ShipManager.Instance.CockpitController;
|
||||||
if (Data)
|
if (Data)
|
||||||
{
|
{
|
||||||
|
QSBPlayerManager.GetPlayer(From)?.AudioController?.PlayOneShot(AudioType.ShipCockpitBuckleUp);
|
||||||
shipCockpitController._interactVolume.DisableInteraction();
|
shipCockpitController._interactVolume.DisableInteraction();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
QSBPlayerManager.GetPlayer(From)?.AudioController?.PlayOneShot(AudioType.ShipCockpitUnbuckle);
|
||||||
shipCockpitController._interactVolume.EnableInteraction();
|
shipCockpitController._interactVolume.EnableInteraction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
QSB/ShipSync/Messages/ShipIgnitionMessage.cs
Normal file
48
QSB/ShipSync/Messages/ShipIgnitionMessage.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using QSB.Messaging;
|
||||||
|
using QSB.Player;
|
||||||
|
using static QSB.ShipSync.Messages.ShipIgnitionMessage;
|
||||||
|
|
||||||
|
namespace QSB.ShipSync.Messages;
|
||||||
|
|
||||||
|
internal class ShipIgnitionMessage : QSBMessage<ShipIgnitionType>
|
||||||
|
{
|
||||||
|
public enum ShipIgnitionType
|
||||||
|
{
|
||||||
|
START_IGNITION,
|
||||||
|
COMPLETE_IGNITION,
|
||||||
|
CANCEL_IGNITION
|
||||||
|
}
|
||||||
|
|
||||||
|
static ShipIgnitionMessage()
|
||||||
|
{
|
||||||
|
GlobalMessenger.AddListener(OWEvents.StartShipIgnition, () => Handler(ShipIgnitionType.START_IGNITION));
|
||||||
|
GlobalMessenger.AddListener(OWEvents.CompleteShipIgnition, () => Handler(ShipIgnitionType.COMPLETE_IGNITION));
|
||||||
|
GlobalMessenger.AddListener(OWEvents.CancelShipIgnition, () => Handler(ShipIgnitionType.CANCEL_IGNITION));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShipIgnitionMessage(ShipIgnitionType data) : base(data) { }
|
||||||
|
|
||||||
|
private static void Handler(ShipIgnitionType type)
|
||||||
|
{
|
||||||
|
if (QSBPlayerManager.LocalPlayer.FlyingShip)
|
||||||
|
{
|
||||||
|
new ShipIgnitionMessage(type).Send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnReceiveRemote()
|
||||||
|
{
|
||||||
|
switch (Data)
|
||||||
|
{
|
||||||
|
case ShipIgnitionType.START_IGNITION:
|
||||||
|
GlobalMessenger.FireEvent(OWEvents.StartShipIgnition);
|
||||||
|
break;
|
||||||
|
case ShipIgnitionType.COMPLETE_IGNITION:
|
||||||
|
GlobalMessenger.FireEvent(OWEvents.CompleteShipIgnition);
|
||||||
|
break;
|
||||||
|
case ShipIgnitionType.CANCEL_IGNITION:
|
||||||
|
GlobalMessenger.FireEvent(OWEvents.CancelShipIgnition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
QSB/ShipSync/Patches/ShipAudioPatches.cs
Normal file
44
QSB/ShipSync/Patches/ShipAudioPatches.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using QSB.Patches;
|
||||||
|
using QSB.Player;
|
||||||
|
using QSB.ShipSync.TransformSync;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace QSB.ShipSync.Patches;
|
||||||
|
|
||||||
|
internal class ShipAudioPatches : QSBPatch
|
||||||
|
{
|
||||||
|
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ShipThrusterAudio), nameof(ShipThrusterAudio.Update))]
|
||||||
|
public static bool ShipThrusterAudio_Update(ShipThrusterAudio __instance)
|
||||||
|
{
|
||||||
|
if (!QSBPlayerManager.LocalPlayer.FlyingShip)
|
||||||
|
{
|
||||||
|
// Just copy pasted the original method with this one line changed
|
||||||
|
Vector3 localAcceleration = ShipTransformSync.LocalInstance.ThrusterVariableSyncer.AccelerationSyncer.Value;
|
||||||
|
localAcceleration.y *= 0.5f;
|
||||||
|
localAcceleration.z *= 0.5f;
|
||||||
|
Vector3 vector = __instance._thrusterModel.IsThrusterBankEnabled(ThrusterBank.Left) ? localAcceleration : Vector3.zero;
|
||||||
|
vector.x = Mathf.Max(0f, vector.x);
|
||||||
|
Vector3 vector2 = __instance._thrusterModel.IsThrusterBankEnabled(ThrusterBank.Right) ? localAcceleration : Vector3.zero;
|
||||||
|
vector2.x = Mathf.Min(0f, vector2.x);
|
||||||
|
float maxTranslationalThrust = __instance._thrusterModel.GetMaxTranslationalThrust();
|
||||||
|
__instance.UpdateTranslationalSourceVolume(__instance._leftTranslationalSource, __instance._thrustToVolumeCurve.Evaluate(vector.magnitude / maxTranslationalThrust), !__instance._underwater);
|
||||||
|
__instance.UpdateTranslationalSourceVolume(__instance._rightTranslationalSource, __instance._thrustToVolumeCurve.Evaluate(vector2.magnitude / maxTranslationalThrust), !__instance._underwater);
|
||||||
|
__instance.UpdateTranslationalSourceVolume(__instance._leftUnderwaterSource, __instance._thrustToVolumeCurve.Evaluate(vector.magnitude / maxTranslationalThrust), __instance._underwater);
|
||||||
|
__instance.UpdateTranslationalSourceVolume(__instance._rightUnderwaterSource, __instance._thrustToVolumeCurve.Evaluate(vector2.magnitude / maxTranslationalThrust), __instance._underwater);
|
||||||
|
if (!__instance._thrustersFiring && !__instance._leftTranslationalSource.isPlaying && !__instance._rightTranslationalSource.isPlaying && !__instance._leftUnderwaterSource.isPlaying && !__instance._rightUnderwaterSource.isPlaying)
|
||||||
|
{
|
||||||
|
__instance.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using QSB.ModelShip;
|
||||||
|
using QSB.ModelShip.TransformSync;
|
||||||
using QSB.Patches;
|
using QSB.Patches;
|
||||||
using QSB.Player;
|
using QSB.Player;
|
||||||
using QSB.ShipSync.TransformSync;
|
using QSB.ShipSync.TransformSync;
|
||||||
@ -41,16 +43,34 @@ internal class ShipFlameWashPatches : QSBPatch
|
|||||||
[HarmonyPatch(typeof(ThrusterWashController), nameof(ThrusterWashController.Update))]
|
[HarmonyPatch(typeof(ThrusterWashController), nameof(ThrusterWashController.Update))]
|
||||||
public static bool Update(ThrusterWashController __instance)
|
public static bool Update(ThrusterWashController __instance)
|
||||||
{
|
{
|
||||||
if (ShipThrusterManager.ShipWashController != __instance)
|
var isShip = ShipThrusterManager.ShipWashController == __instance;
|
||||||
|
var isModelShip = ModelShipTransformSync.LocalInstance.ThrusterVariableSyncer.ThrusterWashController == __instance;
|
||||||
|
|
||||||
|
if (!isShip && !isModelShip)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isLocal;
|
||||||
|
Vector3 remoteAcceleration;
|
||||||
|
if (isShip)
|
||||||
|
{
|
||||||
|
isLocal = QSBPlayerManager.LocalPlayer.FlyingShip;
|
||||||
|
remoteAcceleration = ShipTransformSync.LocalInstance.ThrusterVariableSyncer.AccelerationSyncer.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isLocal = QSBPlayerManager.LocalPlayer.FlyingModelShip;
|
||||||
|
remoteAcceleration = ModelShipTransformSync.LocalInstance.ThrusterVariableSyncer.AccelerationSyncer.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var localAcceleration = isLocal
|
||||||
|
? __instance._thrusterModel.GetLocalAcceleration()
|
||||||
|
: remoteAcceleration;
|
||||||
|
|
||||||
|
// The rest of this is just copy pasted from the original method
|
||||||
var hitInfo = default(RaycastHit);
|
var hitInfo = default(RaycastHit);
|
||||||
var aboveGround = false;
|
var aboveGround = false;
|
||||||
var localAcceleration = QSBPlayerManager.LocalPlayer.FlyingShip
|
|
||||||
? __instance._thrusterModel.GetLocalAcceleration()
|
|
||||||
: ShipTransformSync.LocalInstance.ThrusterVariableSyncer.AccelerationSyncer.Value;
|
|
||||||
var emissionScale = __instance._emissionThrusterScale.Evaluate(localAcceleration.y);
|
var emissionScale = __instance._emissionThrusterScale.Evaluate(localAcceleration.y);
|
||||||
if (emissionScale > 0f)
|
if (emissionScale > 0f)
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@ internal class ShipManager : WorldObjectManager
|
|||||||
|
|
||||||
public static ShipManager Instance;
|
public static ShipManager Instance;
|
||||||
|
|
||||||
|
public ShipThrusterAudio ShipThrusterAudio;
|
||||||
public InteractZone HatchInteractZone;
|
public InteractZone HatchInteractZone;
|
||||||
public HatchController HatchController;
|
public HatchController HatchController;
|
||||||
public ShipTractorBeamSwitch ShipTractorBeam;
|
public ShipTractorBeamSwitch ShipTractorBeam;
|
||||||
@ -92,6 +93,7 @@ internal class ShipManager : WorldObjectManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShipThrusterAudio = QSBWorldSync.GetUnityObject<ShipThrusterAudio>();
|
||||||
HatchInteractZone = HatchController.GetComponent<InteractZone>();
|
HatchInteractZone = HatchController.GetComponent<InteractZone>();
|
||||||
ShipTractorBeam = QSBWorldSync.GetUnityObject<ShipTractorBeamSwitch>();
|
ShipTractorBeam = QSBWorldSync.GetUnityObject<ShipTractorBeamSwitch>();
|
||||||
CockpitController = QSBWorldSync.GetUnityObject<ShipCockpitController>();
|
CockpitController = QSBWorldSync.GetUnityObject<ShipCockpitController>();
|
||||||
@ -136,6 +138,10 @@ internal class ShipManager : WorldObjectManager
|
|||||||
|
|
||||||
QSBWorldSync.Init<QSBShipDetachableModule, ShipDetachableModule>();
|
QSBWorldSync.Init<QSBShipDetachableModule, ShipDetachableModule>();
|
||||||
QSBWorldSync.Init<QSBShipDetachableLeg, ShipDetachableLeg>();
|
QSBWorldSync.Init<QSBShipDetachableLeg, ShipDetachableLeg>();
|
||||||
|
|
||||||
|
// Make sure all relevant audio sources are 3D
|
||||||
|
QSBWorldSync.GetUnityObject<ShipThrusterAudio>()._ignitionSource.spatialBlend = 1f;
|
||||||
|
QSBWorldSync.GetUnityObject<ShipThrusterAudio>()._rotationalSource.spatialBlend = 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UnbuildWorldObjects()
|
public override void UnbuildWorldObjects()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Mirror;
|
using Mirror;
|
||||||
using QSB.Player;
|
using QSB.Player;
|
||||||
using QSB.Utility.VariableSync;
|
using QSB.Utility.VariableSync;
|
||||||
|
using QSB.WorldSync;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace QSB.ShipSync;
|
namespace QSB.ShipSync;
|
||||||
@ -10,10 +11,12 @@ public class ShipThrusterVariableSyncer : NetworkBehaviour
|
|||||||
public Vector3VariableSyncer AccelerationSyncer;
|
public Vector3VariableSyncer AccelerationSyncer;
|
||||||
|
|
||||||
private ShipThrusterModel _thrusterModel;
|
private ShipThrusterModel _thrusterModel;
|
||||||
|
private ShipThrusterAudio _thrusterAudio;
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
_thrusterModel = Locator.GetShipBody().GetComponent<ShipThrusterModel>();
|
_thrusterModel = Locator.GetShipBody().GetComponent<ShipThrusterModel>();
|
||||||
|
_thrusterAudio = Locator.GetShipBody().GetComponentInChildren<ShipThrusterAudio>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@ -33,6 +36,8 @@ public class ShipThrusterVariableSyncer : NetworkBehaviour
|
|||||||
item.OnStopTranslationalThrust();
|
item.OnStopTranslationalThrust();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_thrusterAudio.OnStopTranslationalThrust();
|
||||||
|
|
||||||
ShipThrusterManager.ShipWashController.OnStopTranslationalThrust();
|
ShipThrusterManager.ShipWashController.OnStopTranslationalThrust();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -42,6 +47,8 @@ public class ShipThrusterVariableSyncer : NetworkBehaviour
|
|||||||
item.OnStartTranslationalThrust();
|
item.OnStartTranslationalThrust();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_thrusterAudio.OnStartTranslationalThrust();
|
||||||
|
|
||||||
ShipThrusterManager.ShipWashController.OnStartTranslationalThrust();
|
ShipThrusterManager.ShipWashController.OnStartTranslationalThrust();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user