Merge remote-tracking branch 'origin/dev-0.20.0' into dev

This commit is contained in:
JohnCorby 2022-05-29 14:35:02 -07:00
commit dd9e7ba17f
47 changed files with 807 additions and 129 deletions

View File

@ -102,7 +102,7 @@ public class AnimationSync : PlayerSyncObject
private void InitCrouchSync()
{
_crouchSync = GetComponent<CrouchSync>();
_crouchSync = this.GetRequiredComponent<CrouchSync>();
_crouchSync.Init(_playerController, VisibleAnimator);
}

View File

@ -6,7 +6,6 @@ namespace QSB.Animation.Player.Thrusters;
public class JetpackAccelerationSync : NetworkBehaviour
{
public Vector3VariableSyncer AccelerationVariableSyncer;
public BoolVariableSyncer ThrustingVariableSyncer;
private ThrusterModel _thrusterModel;
@ -25,7 +24,6 @@ public class JetpackAccelerationSync : NetworkBehaviour
if (_thrusterModel != null)
{
AccelerationVariableSyncer.Value = _thrusterModel.GetLocalAcceleration();
ThrustingVariableSyncer.Value = _thrusterModel.IsTranslationalThrusterFiring();
}
}
}

View File

@ -15,30 +15,6 @@ public class DeathPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
// TODO : Remove with future functionality.
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipEjectionSystem), nameof(ShipEjectionSystem.OnPressInteract))]
public static bool DisableEjection()
=> false;
// TODO : Remove with future functionality.
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipDetachableLeg), nameof(ShipDetachableLeg.Detach))]
public static bool ShipDetachableLeg_Detach(out OWRigidbody __result)
{
__result = null;
return false;
}
// TODO : Remove with future functionality.
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipDetachableModule), nameof(ShipDetachableModule.Detach))]
public static bool ShipDetachableModule_Detach(out OWRigidbody __result)
{
__result = null;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerResources), nameof(PlayerResources.OnImpact))]
public static bool PlayerResources_OnImpact(PlayerResources __instance, ImpactData impact) =>
@ -260,35 +236,29 @@ public class DeathPatches : QSBPatch
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipDamageController), nameof(ShipDamageController.Explode))]
public static bool ShipDamageController_Explode()
// prevent ship from exploding
// todo remove this when sync ship explosions
=> false;
[HarmonyPrefix]
[HarmonyPatch(typeof(DestructionVolume), nameof(DestructionVolume.VanishShip))]
public static bool DestructionVolume_VanishShip(DestructionVolume __instance)
public static bool DestructionVolume_VanishShip(DestructionVolume __instance, OWRigidbody shipBody, RelativeLocationData entryLocation)
{
if (RespawnOnDeath.Instance == null)
var cockpitIntact = !shipBody.GetComponent<ShipDamageController>().IsCockpitDetached();
if (PlayerState.IsInsideShip() || PlayerState.UsingShipComputer() || (cockpitIntact && PlayerState.AtFlightConsole()))
{
return true;
}
var autopilot = shipBody.GetComponent<Autopilot>();
if (autopilot != null && autopilot.IsFlyingToDestination())
{
var astroObject = __instance.GetComponentInParent<AstroObject>();
if (astroObject != null && astroObject.GetAstroObjectType() == AstroObject.Type.Star)
{
PlayerData.SetPersistentCondition("AUTOPILOT_INTO_SUN", true);
MonoBehaviour.print("AUTOPILOT_INTO_SUN");
}
}
// apparently this is to fix a weird bug when flying into the sun. idk this is 2-year-old code.
if (!ShipTransformSync.LocalInstance.hasAuthority)
{
return false;
}
if (PlayerState.IsInsideShip() || PlayerState.UsingShipComputer() || PlayerState.AtFlightConsole())
{
Locator.GetDeathManager().KillPlayer(__instance._deathType);
}
// don't actually delete the ship to allow respawns or something
return true;
__instance.Vanish(shipBody, entryLocation);
GlobalMessenger.FireEvent("ShipDestroyed");
return false;
}
}

View File

@ -33,7 +33,7 @@ internal abstract class RotatingElementsVariableSyncer<TWorldObject> : BaseVaria
protected abstract Transform[] RotatingElements { get; }
protected override bool HasChanged()
protected override bool CheckChanged()
{
var rotatingElements = RotatingElements;
Value ??= new Quaternion[rotatingElements.Length];

View File

@ -12,7 +12,7 @@ public class PlayerInformationMessage : QSBMessage
private bool IsReady;
private bool FlashlightActive;
private bool SuitedUp;
private bool ProbeLauncherEquipped;
private bool LocalProbeLauncherEquipped;
private bool SignalscopeEquipped;
private bool TranslatorEquipped;
private bool ProbeActive;
@ -25,7 +25,7 @@ public class PlayerInformationMessage : QSBMessage
IsReady = player.IsReady;
FlashlightActive = player.FlashlightActive;
SuitedUp = player.SuitedUp;
ProbeLauncherEquipped = player.ProbeLauncherEquipped;
LocalProbeLauncherEquipped = player.LocalProbeLauncherEquipped;
SignalscopeEquipped = player.SignalscopeEquipped;
TranslatorEquipped = player.TranslatorEquipped;
ProbeActive = player.ProbeActive;
@ -39,7 +39,7 @@ public class PlayerInformationMessage : QSBMessage
writer.Write(IsReady);
writer.Write(FlashlightActive);
writer.Write(SuitedUp);
writer.Write(ProbeLauncherEquipped);
writer.Write(LocalProbeLauncherEquipped);
writer.Write(SignalscopeEquipped);
writer.Write(TranslatorEquipped);
writer.Write(ProbeActive);
@ -53,7 +53,7 @@ public class PlayerInformationMessage : QSBMessage
IsReady = reader.Read<bool>();
FlashlightActive = reader.Read<bool>();
SuitedUp = reader.Read<bool>();
ProbeLauncherEquipped = reader.Read<bool>();
LocalProbeLauncherEquipped = reader.Read<bool>();
SignalscopeEquipped = reader.Read<bool>();
TranslatorEquipped = reader.Read<bool>();
ProbeActive = reader.Read<bool>();
@ -70,7 +70,7 @@ public class PlayerInformationMessage : QSBMessage
player.IsReady = IsReady;
player.FlashlightActive = FlashlightActive;
player.SuitedUp = SuitedUp;
player.ProbeLauncherEquipped = ProbeLauncherEquipped;
player.LocalProbeLauncherEquipped = LocalProbeLauncherEquipped;
player.SignalscopeEquipped = SignalscopeEquipped;
player.TranslatorEquipped = TranslatorEquipped;
player.ProbeActive = ProbeActive;

View File

@ -28,6 +28,7 @@ public class PlayerJoinMessage : QSBMessage
var allEnabledMods = QSBCore.Helper.Interaction.GetMods();
FirstIncompatibleMod = "";
foreach (var mod in allEnabledMods)
{
if (QSBCore.IncompatibleMods.Contains(mod.ModHelper.Manifest.UniqueName))

View File

@ -6,6 +6,7 @@ using QSB.Messaging;
using QSB.Player.Messages;
using QSB.Player.TransformSync;
using QSB.QuantumSync.WorldObjects;
using QSB.ShipSync;
using QSB.Tools;
using QSB.Utility;
using System.Linq;
@ -32,6 +33,7 @@ public partial class PlayerInfo
public QSBPlayerAudioController AudioController { get; set; }
public bool IsLocalPlayer => TransformSync.isLocalPlayer;
public ThrusterLightTracker ThrusterLightTracker;
public bool FlyingShip => ShipManager.Instance.CurrentFlyer == PlayerId;
public PlayerInfo(PlayerTransformSync transformSync)
{
@ -63,17 +65,19 @@ public partial class PlayerInfo
HeldItem = default;
FlashlightActive = default;
SuitedUp = default;
ProbeLauncherEquipped = default;
LocalProbeLauncherEquipped = default;
SignalscopeEquipped = default;
TranslatorEquipped = default;
ProbeActive = default;
ProbeLauncherEquipped = default;
}
public void UpdateObjectsFromStates()
{
FlashLight.UpdateState(FlashlightActive);
Translator.ChangeEquipState(TranslatorEquipped);
ProbeLauncher.ChangeEquipState(ProbeLauncherEquipped);
ProbeLauncherTool.ChangeEquipState(LocalProbeLauncherEquipped);
Signalscope.ChangeEquipState(SignalscopeEquipped);
AnimationSync.SetSuitState(SuitedUp);
}

View File

@ -5,6 +5,7 @@ using QSB.RoastingSync;
using QSB.Tools;
using QSB.Tools.FlashlightTool;
using QSB.Tools.ProbeLauncherTool;
using QSB.Tools.ProbeLauncherTool.WorldObjects;
using QSB.Tools.ProbeTool;
using QSB.Utility;
using UnityEngine;
@ -18,7 +19,7 @@ public partial class PlayerInfo
public QSBFlashlight FlashLight => CameraBody == null ? null : CameraBody.GetComponentInChildren<QSBFlashlight>();
public QSBTool Signalscope => GetToolByType(ToolType.Signalscope);
public QSBTool Translator => GetToolByType(ToolType.Translator);
public QSBProbeLauncherTool ProbeLauncher => (QSBProbeLauncherTool)GetToolByType(ToolType.ProbeLauncher);
public QSBProbeLauncherTool ProbeLauncherTool => (QSBProbeLauncherTool)GetToolByType(ToolType.ProbeLauncher);
private Transform _handPivot;
public Transform HandPivot
{
@ -80,9 +81,10 @@ public partial class PlayerInfo
public IQSBItem HeldItem { get; set; }
public bool FlashlightActive { get; set; }
public bool SuitedUp { get; set; }
public bool ProbeLauncherEquipped { get; set; }
public bool LocalProbeLauncherEquipped { get; set; }
public bool SignalscopeEquipped { get; set; }
public bool TranslatorEquipped { get; set; }
public bool ProbeActive { get; set; }
public GameObject RoastingStick { get; set; }
public QSBProbeLauncher ProbeLauncherEquipped { get; set; }
}

View File

@ -20,11 +20,13 @@ using QSB.Patches;
using QSB.Player;
using QSB.Player.Messages;
using QSB.Player.TransformSync;
using QSB.ShipSync;
using QSB.ShipSync.TransformSync;
using QSB.Syncs.Occasional;
using QSB.TimeSync;
using QSB.Tools.ProbeTool.TransformSync;
using QSB.Utility;
using QSB.Utility.VariableSync;
using QSB.WorldSync;
using System;
using System.Linq;
@ -49,6 +51,8 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
public GameObject DoorPrefab { get; private set; }
public GameObject ElevatorPrefab { get; private set; }
public GameObject AirlockPrefab { get; private set; }
public GameObject ShipModulePrefab { get; private set; }
public GameObject ShipLegPrefab { get; private set; }
private string PlayerName { get; set; }
private GameObject _probePrefab;
@ -101,6 +105,9 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
playerPrefab.GetRequiredComponent<NetworkIdentity>().SetValue("m_AssetId", 1.ToGuid().ToString("N"));
ShipPrefab = MakeNewNetworkObject(2, "NetworkShip", typeof(ShipTransformSync));
var shipVector3Sync = ShipPrefab.AddComponent<Vector3VariableSyncer>();
var shipThrustSync = ShipPrefab.AddComponent<ShipThrusterVariableSyncer>();
shipThrustSync.AccelerationSyncer = shipVector3Sync;
spawnPrefabs.Add(ShipPrefab);
_probePrefab = MakeNewNetworkObject(3, "NetworkProbe", typeof(PlayerProbeSync));
@ -130,6 +137,12 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
AirlockPrefab = MakeNewNetworkObject(11, "NetworkGhostAirlock", typeof(AirlockVariableSyncer));
spawnPrefabs.Add(AirlockPrefab);
ShipModulePrefab = MakeNewNetworkObject(12, "NetworkShipModule", typeof(ShipModuleTransformSync));
spawnPrefabs.Add(ShipModulePrefab);
ShipLegPrefab = MakeNewNetworkObject(13, "NetworkShipLeg", typeof(ShipLegTransformSync));
spawnPrefabs.Add(ShipLegPrefab);
ConfigureNetworkManager();
}

View File

@ -1,4 +1,5 @@
using UnityEngine;
using QSB.ShipSync;
using UnityEngine;
namespace QSB.RespawnSync;
@ -26,10 +27,12 @@ public class RespawnHUDMarker : HUDDistanceMarker
if (_canvasMarker != null)
{
var isVisible = _canvasMarker.IsVisible();
var shouldBeVisible = RespawnManager.Instance.RespawnNeeded
&& !ShipManager.Instance.ShipCockpitUI._shipDamageCtrlr.IsDestroyed();
if (RespawnManager.Instance.RespawnNeeded != isVisible)
if (shouldBeVisible != isVisible)
{
_isVisible = RespawnManager.Instance.RespawnNeeded;
_isVisible = shouldBeVisible;
_canvasMarker.SetVisibility(_isVisible);
}
}

View File

@ -35,7 +35,6 @@ internal class RespawnManager : MonoBehaviour, IAddComponentOnStart
QSBPlayerManager.OnRemovePlayer += player =>
{
_playersPendingRespawn.Remove(player);
UpdateRespawnNotification();
};
}
@ -148,7 +147,6 @@ internal class RespawnManager : MonoBehaviour, IAddComponentOnStart
player.IsDead = true;
_playersPendingRespawn.Add(player);
UpdateRespawnNotification();
var deadPlayersCount = QSBPlayerManager.PlayerList.Count(x => x.IsDead);
@ -172,7 +170,6 @@ internal class RespawnManager : MonoBehaviour, IAddComponentOnStart
player.IsDead = false;
_playersPendingRespawn.Remove(player);
UpdateRespawnNotification();
player.SetVisible(true, 1);
}
@ -182,18 +179,4 @@ internal class RespawnManager : MonoBehaviour, IAddComponentOnStart
var playerToRespawn = _playersPendingRespawn.First();
new PlayerRespawnMessage(playerToRespawn.PlayerId).Send();
}
private void UpdateRespawnNotification()
{
NotificationManager.SharedInstance.UnpinNotification(_previousNotification);
if (_playersPendingRespawn.Count == 0)
{
return;
}
var data = new NotificationData(NotificationTarget.Player, $"[{_playersPendingRespawn.Count}] PLAYER(S) AWAITING RESPAWN");
NotificationManager.SharedInstance.PostNotification(data, true);
_previousNotification = data;
}
}

View File

@ -1,4 +1,5 @@
using QSB.Messaging;
using QSB.ShipSync;
using QSB.Utility;
using UnityEngine;
@ -56,7 +57,7 @@ internal class ShipRecoveryPoint : MonoBehaviour
_playerResources = Locator.GetPlayerTransform().GetComponent<PlayerResources>();
}
if (RespawnManager.Instance.RespawnNeeded)
if (RespawnManager.Instance.RespawnNeeded && !ShipManager.Instance.ShipCockpitUI._shipDamageCtrlr.IsDestroyed())
{
_interactVolume.EnableSingleInteraction(true, _respawnIndex);
_interactVolume.SetKeyCommandVisible(true, _respawnIndex);
@ -124,7 +125,7 @@ internal class ShipRecoveryPoint : MonoBehaviour
}
else if (inputCommand == _interactVolume.GetInteractionAt(_respawnIndex).inputCommand)
{
if (!RespawnManager.Instance.RespawnNeeded)
if (!RespawnManager.Instance.RespawnNeeded || ShipManager.Instance.ShipCockpitUI._shipDamageCtrlr.IsDestroyed())
{
return;
}

View File

@ -0,0 +1,19 @@
using QSB.Messaging;
using QSB.Utility;
namespace QSB.ShipSync.Messages;
internal class LandingCameraMessage : QSBMessage<bool>
{
public LandingCameraMessage(bool on) : base(on) { }
public override void OnReceiveRemote()
{
if (From != ShipManager.Instance.CurrentFlyer)
{
DebugLog.ToConsole($"Warning - Received LandingCameraMessage from someone who isn't flying the ship!", OWML.Common.MessageType.Warning);
}
ShipManager.Instance.UpdateLandingCamera(Data);
}
}

View File

@ -0,0 +1,11 @@
using QSB.Messaging;
using QSB.Patches;
using QSB.ShipSync.WorldObjects;
namespace QSB.ShipSync.Messages;
internal class LegDetachMessage : QSBWorldObjectMessage<QSBShipDetachableLeg>
{
public override void OnReceiveRemote() =>
QSBPatch.RemoteCall(WorldObject.AttachedObject.Detach);
}

View File

@ -0,0 +1,11 @@
using QSB.Messaging;
using QSB.Patches;
using QSB.ShipSync.WorldObjects;
namespace QSB.ShipSync.Messages;
internal class ModuleDetachMessage : QSBWorldObjectMessage<QSBShipDetachableModule>
{
public override void OnReceiveRemote() =>
QSBPatch.RemoteCall(WorldObject.AttachedObject.Detach);
}

View File

@ -0,0 +1,17 @@
using QSB.Messaging;
using QSB.WorldSync;
namespace QSB.ShipSync.Messages;
internal class ReactorCountdownMessage : QSBMessage<float>
{
public ReactorCountdownMessage(float countdown) : base(countdown) { }
public override void OnReceiveRemote()
{
var reactor = QSBWorldSync.GetUnityObject<ShipReactorComponent>();
reactor._criticalCountdown = Data;
reactor._criticalTimer = Data;
reactor.enabled = true;
}
}

View File

@ -0,0 +1,13 @@
using QSB.Messaging;
using QSB.Patches;
using QSB.ShipSync.WorldObjects;
namespace QSB.ShipSync.Messages;
internal class ShipLightMessage : QSBWorldObjectMessage<QSBShipLight, bool>
{
public ShipLightMessage(bool on) : base(on) { }
public override void OnReceiveRemote() =>
QSBPatch.RemoteCall(() => WorldObject.AttachedObject.SetOn(Data));
}

View File

@ -0,0 +1,58 @@
using HarmonyLib;
using QSB.Messaging;
using QSB.Patches;
using QSB.ShipSync.Messages;
using QSB.ShipSync.WorldObjects;
using QSB.WorldSync;
namespace QSB.ShipSync.Patches;
[HarmonyPatch(typeof(ShipDetachableModule))]
internal class ShipDetachableModulePatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
[HarmonyPrefix]
[HarmonyPatch(nameof(ShipDetachableModule.Detach))]
public static void Detach(ShipDetachableModule __instance)
{
if (Remote)
{
return;
}
if (__instance.isDetached)
{
return;
}
if (!QSBWorldSync.AllObjectsReady)
{
return;
}
__instance.GetWorldObject<QSBShipDetachableModule>().SendMessage(new ModuleDetachMessage());
}
[HarmonyPrefix]
[HarmonyPatch(nameof(ShipDetachableLeg.Detach))]
public static void Detach(ShipDetachableLeg __instance)
{
if (Remote)
{
return;
}
if (__instance.isDetached)
{
return;
}
if (!QSBWorldSync.AllObjectsReady)
{
return;
}
__instance.GetWorldObject<QSBShipDetachableLeg>().SendMessage(new LegDetachMessage());
}
}

View File

@ -0,0 +1,126 @@
using HarmonyLib;
using QSB.Patches;
using QSB.Player;
using QSB.ShipSync.TransformSync;
using UnityEngine;
namespace QSB.ShipSync.Patches;
internal class ShipFlameWashPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
[HarmonyPrefix]
[HarmonyPatch(typeof(ThrusterFlameController), nameof(ThrusterFlameController.GetThrustFraction))]
public static bool GetThrustFraction(ThrusterFlameController __instance, ref float __result)
{
if (!ShipThrusterManager.ShipFlameControllers.Contains(__instance))
{
return true;
}
if (!__instance._thrusterModel.IsThrusterBankEnabled(OWUtilities.GetShipThrusterBank(__instance._thruster)))
{
__result = 0f;
return false;
}
if (QSBPlayerManager.LocalPlayer.FlyingShip)
{
__result = Vector3.Dot(__instance._thrusterModel.GetLocalAcceleration(), __instance._thrusterFilter);
}
else
{
__result = Vector3.Dot(ShipTransformSync.LocalInstance.ThrusterVariableSyncer.AccelerationSyncer.Value, __instance._thrusterFilter);
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ThrusterWashController), nameof(ThrusterWashController.Update))]
public static bool Update(ThrusterWashController __instance)
{
if (ShipThrusterManager.ShipWashController != __instance)
{
return true;
}
var hitInfo = default(RaycastHit);
var aboveGround = false;
var localAcceleration = QSBPlayerManager.LocalPlayer.FlyingShip
? __instance._thrusterModel.GetLocalAcceleration()
: ShipTransformSync.LocalInstance.ThrusterVariableSyncer.AccelerationSyncer.Value;
var emissionScale = __instance._emissionThrusterScale.Evaluate(localAcceleration.y);
if (emissionScale > 0f)
{
aboveGround = Physics.Raycast(__instance.transform.position, __instance.transform.forward, out hitInfo, __instance._raycastDistance, OWLayerMask.physicalMask);
}
emissionScale = aboveGround ? (emissionScale * __instance._emissionDistanceScale.Evaluate(hitInfo.distance)) : 0f;
if (emissionScale > 0f)
{
var position = hitInfo.point + (hitInfo.normal * 0.25f);
var rotation = Quaternion.LookRotation(hitInfo.normal);
if (!__instance._defaultParticleSystem.isPlaying)
{
__instance._defaultParticleSystem.Play();
}
__instance._defaultEmissionModule.rateOverTimeMultiplier = __instance._baseDefaultEmissionRate * emissionScale;
__instance._defaultParticleSystem.transform.SetPositionAndRotation(position, rotation);
if (__instance._defaultMainModule.customSimulationSpace != hitInfo.transform)
{
__instance._defaultMainModule.customSimulationSpace = hitInfo.transform;
__instance._defaultParticleSystem.Clear();
}
var hitSurfaceType = Locator.GetSurfaceManager().GetHitSurfaceType(hitInfo);
var particleSystem = __instance._particleSystemBySurfaceType[(int)hitSurfaceType];
if (particleSystem != __instance._activeSurfaceParticleSystem)
{
if (__instance._activeSurfaceParticleSystem != null)
{
__instance._activeSurfaceParticleSystem.Stop(false, ParticleSystemStopBehavior.StopEmitting);
}
if (particleSystem != null)
{
particleSystem.Play();
}
__instance._activeSurfaceParticleSystem = particleSystem;
}
if (__instance._activeSurfaceParticleSystem != null)
{
var es = __instance._activeSurfaceParticleSystem.emission;
es.rateOverTimeMultiplier = __instance._baseSurfaceEmissionRate[(int)hitSurfaceType] * emissionScale;
__instance._activeSurfaceParticleSystem.transform.position = hitInfo.point + (hitInfo.normal * 0.25f);
__instance._activeSurfaceParticleSystem.transform.rotation = Quaternion.LookRotation(hitInfo.normal);
var main = __instance._activeSurfaceParticleSystem.main;
if (main.customSimulationSpace != hitInfo.transform)
{
main.customSimulationSpace = hitInfo.transform;
__instance._activeSurfaceParticleSystem.Clear();
return false;
}
}
}
else
{
if (__instance._defaultParticleSystem.isPlaying)
{
__instance._defaultParticleSystem.Stop(false, ParticleSystemStopBehavior.StopEmitting);
}
if (__instance._activeSurfaceParticleSystem != null)
{
__instance._activeSurfaceParticleSystem.Stop(false, ParticleSystemStopBehavior.StopEmitting);
__instance._activeSurfaceParticleSystem = null;
}
}
return false;
}
}

View File

@ -252,4 +252,90 @@ internal class ShipPatches : QSBPatch
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipCockpitController), nameof(ShipCockpitController.EnterLandingView))]
public static void EnterLandingView() =>
new LandingCameraMessage(true).Send();
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipCockpitController), nameof(ShipCockpitController.ExitLandingView))]
public static void ExitLandingView() =>
new LandingCameraMessage(false).Send();
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipLight), nameof(ShipLight.SetOn))]
public static void SetOn(ShipLight __instance, bool on)
{
if (Remote)
{
return;
}
if (__instance._on == on)
{
return;
}
if (!QSBWorldSync.AllObjectsReady)
{
return;
}
if (!__instance.TryGetWorldObject(out QSBShipLight qsbShipLight))
{
return;
}
qsbShipLight.SendMessage(new ShipLightMessage(on));
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipCockpitUI), nameof(ShipCockpitUI.UpdateSignalscopeCanvas))]
public static bool UpdateSignalscopeCanvas(ShipCockpitUI __instance)
{
var flag = false;
if (Locator.GetToolModeSwapper().GetToolMode() != ToolMode.SignalScope)
{
if (__instance._signalscopeUI.IsActivated())
{
__instance._signalscopeUI.Deactivate();
}
}
else if (ShipManager.Instance.CurrentFlyer != uint.MaxValue)
{
flag = true;
if (!__instance._signalscopeUI.IsActivated())
{
if (__instance._reticuleController == null)
{
Debug.LogError("ReticuleController cannot be null!");
}
__instance._signalscopeUI.Activate(__instance._signalscopeTool, __instance._reticuleController);
}
}
__instance._scopeScreenMaterial.SetColor(__instance._propID_EmissionColor, __instance._scopeScreenColor * (flag ? 1f : 0f));
__instance._sigScopeScreenLight.SetOn(flag);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ShipReactorComponent), nameof(ShipReactorComponent.OnComponentDamaged))]
public static bool ByeByeReactor(ShipReactorComponent __instance)
{
if (!QSBCore.IsHost)
{
return false;
}
__instance._criticalCountdown = UnityEngine.Random.Range(__instance._minCountdown, __instance._maxCountdown);
__instance._criticalTimer = __instance._criticalCountdown;
__instance.enabled = true;
new ReactorCountdownMessage(__instance._criticalCountdown).Send();
return false;
}
}

View File

@ -1,6 +1,7 @@
using Cysharp.Threading.Tasks;
using Mirror;
using OWML.Common;
using QSB.Animation.Player.Thrusters;
using QSB.Messaging;
using QSB.Player;
using QSB.ShipSync.Messages;
@ -26,6 +27,7 @@ internal class ShipManager : WorldObjectManager
public ShipTractorBeamSwitch ShipTractorBeam;
public ShipCockpitController CockpitController;
public ShipElectricalComponent ShipElectricalComponent;
public ShipCockpitUI ShipCockpitUI;
private GameObject _shipCustomAttach;
public uint CurrentFlyer
{
@ -79,6 +81,7 @@ internal class ShipManager : WorldObjectManager
ShipTractorBeam = QSBWorldSync.GetUnityObject<ShipTractorBeamSwitch>();
CockpitController = QSBWorldSync.GetUnityObject<ShipCockpitController>();
ShipElectricalComponent = QSBWorldSync.GetUnityObject<ShipElectricalComponent>();
ShipCockpitUI = QSBWorldSync.GetUnityObject<ShipCockpitUI>();
var sphereShape = HatchController.GetComponent<SphereShape>();
sphereShape.radius = 2.5f;
@ -111,6 +114,24 @@ internal class ShipManager : WorldObjectManager
_shipCustomAttach = new GameObject(nameof(ShipCustomAttach));
_shipCustomAttach.transform.SetParent(shipBody.transform, false);
_shipCustomAttach.AddComponent<ShipCustomAttach>();
QSBWorldSync.Init<QSBShipLight, ShipLight>(new List<ShipLight>()
{
CockpitController._headlight,
CockpitController._landingLight,
ShipCockpitUI._altimeterLight,
ShipCockpitUI._landingCamScreenLight,
ShipCockpitUI._minimapLight,
ShipCockpitUI._minimapNorthPoleLight,
ShipCockpitUI._minimapProbeLight,
ShipCockpitUI._minimapShipLight,
ShipCockpitUI._minimapSouthPoleLight,
ShipCockpitUI._probeLauncherScreenLight,
ShipCockpitUI._sigScopeScreenLight
});
QSBWorldSync.Init<QSBShipDetachableModule, ShipDetachableModule>();
QSBWorldSync.Init<QSBShipDetachableLeg, ShipDetachableLeg>();
}
public override void UnbuildWorldObjects() => Destroy(_shipCustomAttach);
@ -150,4 +171,51 @@ internal class ShipManager : WorldObjectManager
}
}
}
public void UpdateSignalscope(bool equipped)
{
ShipCockpitUI._displaySignalscopeScreen = equipped;
ShipCockpitUI._shipAudioController.PlaySigScopeSlide();
}
public void UpdateProbeLauncher(bool equipped)
{
ShipCockpitUI._displayProbeLauncherScreen = equipped;
ShipCockpitUI._shipAudioController.PlayProbeScreenMotor();
}
public void UpdateLandingCamera(bool on)
{
if (on)
{
EnterLandingView();
return;
}
ExitLandingView();
}
private void EnterLandingView()
{
if (CockpitController._landingCam.mode == LandingCamera.Mode.Double)
{
CockpitController._landingCam.enabled = true;
}
if (CockpitController._landingCamComponent.isDamaged)
{
CockpitController._shipAudioController.PlayLandingCamOn(AudioType.ShipCockpitLandingCamStatic_LP);
CockpitController._shipAudioController.PlayLandingCamStatic(0.25f);
return;
}
CockpitController._shipAudioController.PlayLandingCamOn(AudioType.ShipCockpitLandingCamAmbient_LP);
CockpitController._shipAudioController.PlayLandingCamAmbient(0.25f);
}
private void ExitLandingView()
{
CockpitController._landingCam.enabled = false;
CockpitController._shipAudioController.PlayLandingCamOff();
}
}

View File

@ -0,0 +1,48 @@
using System.Collections.Generic;
using UnityEngine;
namespace QSB.ShipSync;
public static class ShipThrusterManager
{
public static List<ThrusterFlameController> ShipFlameControllers = new();
public static ThrusterWashController ShipWashController = new();
public static void CreateShipVFX()
{
var shipBody = Locator.GetShipBody();
var Module_Cabin = shipBody.transform.Find("Module_Cabin");
var Effects_Cabin = Module_Cabin.Find("Effects_Cabin");
var ThrusterWash = Effects_Cabin.Find("ThrusterWash");
ShipWashController = ThrusterWash.GetComponent<ThrusterWashController>();
var Module_Supplies = shipBody.transform.Find("Module_Supplies");
var Effects_Supplies = Module_Supplies.Find("Effects_Supplies");
var SuppliesThrusters = Effects_Supplies.Find("Thrusters");
foreach (Transform thruster in SuppliesThrusters)
{
if (thruster.name == "Particles")
{
continue;
}
var flame = thruster.GetChild(0);
ShipFlameControllers.Add(flame.GetComponent<ThrusterFlameController>());
}
var Module_Engine = shipBody.transform.Find("Module_Engine");
var Effects_Engine = Module_Engine.Find("Effects_Engine");
var EngineThrusters = Effects_Engine.Find("Thrusters");
foreach (Transform thruster in EngineThrusters)
{
if (thruster.name == "Particles")
{
continue;
}
var flame = thruster.GetChild(0);
ShipFlameControllers.Add(flame.GetComponent<ThrusterFlameController>());
}
}
}

View File

@ -0,0 +1,52 @@
using Mirror;
using QSB.Player;
using QSB.Utility.VariableSync;
using UnityEngine;
namespace QSB.ShipSync;
public class ShipThrusterVariableSyncer : NetworkBehaviour
{
public Vector3VariableSyncer AccelerationSyncer;
private ShipThrusterModel _thrusterModel;
public void Init()
{
_thrusterModel = Locator.GetShipBody().GetComponent<ShipThrusterModel>();
}
public void Update()
{
if (QSBPlayerManager.LocalPlayer.FlyingShip)
{
GetFromShip();
return;
}
if (AccelerationSyncer.HasChanged)
{
if (AccelerationSyncer.Value == Vector3.zero)
{
foreach (var item in ShipThrusterManager.ShipFlameControllers)
{
item.OnStopTranslationalThrust();
}
ShipThrusterManager.ShipWashController.OnStopTranslationalThrust();
}
else
{
foreach (var item in ShipThrusterManager.ShipFlameControllers)
{
item.OnStartTranslationalThrust();
}
ShipThrusterManager.ShipWashController.OnStartTranslationalThrust();
}
}
}
private void GetFromShip() => AccelerationSyncer.Value = _thrusterModel.GetLocalAcceleration();
}

View File

@ -0,0 +1,34 @@
using QSB.ShipSync.WorldObjects;
using QSB.Syncs.Sectored.Rigidbodies;
using QSB.Utility.LinkedWorldObject;
using QSB.WorldSync;
namespace QSB.ShipSync.TransformSync;
internal class ShipLegTransformSync : SectoredRigidbodySync, ILinkedNetworkBehaviour
{
/// <summary>
/// normally prints error when attached object is null.
/// this overrides it so that doesn't happen, since the module can be destroyed.
/// </summary>
protected override bool CheckValid()
=> AttachedTransform
&& base.CheckValid();
protected override bool CheckReady()
=> _qsbModule != null
&& _qsbModule.AttachedObject.isDetached
&& base.CheckReady();
protected override bool UseInterpolation => true;
private QSBShipDetachableLeg _qsbModule;
public void SetWorldObject(IWorldObject worldObject) => _qsbModule = (QSBShipDetachableLeg)worldObject;
protected override OWRigidbody InitAttachedRigidbody()
{
var owRigidbody = _qsbModule.AttachedObject.GetComponent<OWRigidbody>();
SectorDetector.Init(owRigidbody.transform.Find("DetectorVolume").GetComponent<SectorDetector>());
return owRigidbody;
}
}

View File

@ -0,0 +1,34 @@
using QSB.ShipSync.WorldObjects;
using QSB.Syncs.Sectored.Rigidbodies;
using QSB.Utility.LinkedWorldObject;
using QSB.WorldSync;
namespace QSB.ShipSync.TransformSync;
internal class ShipModuleTransformSync : SectoredRigidbodySync, ILinkedNetworkBehaviour
{
/// <summary>
/// normally prints error when attached object is null.
/// this overrides it so that doesn't happen, since the module can be destroyed.
/// </summary>
protected override bool CheckValid()
=> AttachedTransform
&& base.CheckValid();
protected override bool CheckReady()
=> _qsbModule != null
&& _qsbModule.AttachedObject.isDetached
&& base.CheckReady();
protected override bool UseInterpolation => true;
private QSBShipDetachableModule _qsbModule;
public void SetWorldObject(IWorldObject worldObject) => _qsbModule = (QSBShipDetachableModule)worldObject;
protected override OWRigidbody InitAttachedRigidbody()
{
var owRigidbody = _qsbModule.AttachedObject.GetComponent<OWRigidbody>();
SectorDetector.Init(owRigidbody.transform.Find("DetectorVolume").GetComponent<SectorDetector>());
return owRigidbody;
}
}

View File

@ -8,9 +8,19 @@ public class ShipTransformSync : SectoredRigidbodySync
{
public static ShipTransformSync LocalInstance { get; private set; }
public ShipThrusterVariableSyncer ThrusterVariableSyncer { get; private set; }
private float _lastSetPositionTime;
private const float ForcePositionAfterTime = 1;
/// <summary>
/// normally prints error when attached object is null.
/// this overrides it so that doesn't happen, since the ship can be destroyed.
/// </summary>
protected override bool CheckValid()
=> AttachedTransform
&& base.CheckValid();
protected override bool CheckReady() =>
base.CheckReady() &&
Locator.GetShipBody();
@ -27,6 +37,16 @@ public class ShipTransformSync : SectoredRigidbodySync
return Locator.GetShipBody();
}
protected override void Init()
{
base.Init();
ThrusterVariableSyncer = this.GetRequiredComponent<ShipThrusterVariableSyncer>();
ThrusterVariableSyncer.Init();
ShipThrusterManager.CreateShipVFX();
}
/// Dont do base... this is a replacement!
protected override void ApplyToAttached()
{
@ -72,4 +92,4 @@ public class ShipTransformSync : SectoredRigidbodySync
}
protected override bool UseInterpolation => false;
}
}

View File

@ -0,0 +1,21 @@
using QSB.ShipSync.TransformSync;
using QSB.Utility.LinkedWorldObject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace QSB.ShipSync.WorldObjects;
internal class QSBShipDetachableLeg : LinkedWorldObject<ShipDetachableLeg, ShipLegTransformSync>
{
protected override GameObject NetworkObjectPrefab => QSBNetworkManager.singleton.ShipLegPrefab;
protected override bool SpawnWithServerAuthority => true;
public override void SendInitialState(uint to)
{
}
}

View File

@ -0,0 +1,21 @@
using QSB.ShipSync.TransformSync;
using QSB.Utility.LinkedWorldObject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace QSB.ShipSync.WorldObjects;
internal class QSBShipDetachableModule : LinkedWorldObject<ShipDetachableModule, ShipModuleTransformSync>
{
protected override GameObject NetworkObjectPrefab => QSBNetworkManager.singleton.ShipModulePrefab;
protected override bool SpawnWithServerAuthority => true;
public override void SendInitialState(uint to)
{
}
}

View File

@ -0,0 +1,11 @@
using QSB.Messaging;
using QSB.ShipSync.Messages;
using QSB.WorldSync;
namespace QSB.ShipSync.WorldObjects;
internal class QSBShipLight : WorldObject<ShipLight>
{
public override void SendInitialState(uint to) =>
this.SendMessage(new ShipLightMessage(AttachedObject._on) { To = to });
}

View File

@ -14,7 +14,7 @@ public class QSBNetworkTransform : QSBNetworkBehaviour
private Vector3 _prevPosition;
private Quaternion _prevRotation;
protected override bool HasChanged() =>
protected override bool CheckChanged() =>
Vector3.Distance(transform.position, _prevPosition) > PositionChangeThreshold ||
Quaternion.Angle(transform.rotation, _prevRotation) > RotationChangeThreshold;

View File

@ -16,7 +16,7 @@ public class QSBNetworkTransformChild : QSBNetworkBehaviour
private Vector3 _prevPosition;
private Quaternion _prevRotation;
protected override bool HasChanged() =>
protected override bool CheckChanged() =>
Vector3.Distance(Target.localPosition, _prevPosition) > PositionChangeThreshold ||
Quaternion.Angle(Target.localRotation, _prevRotation) > RotationChangeThreshold;

View File

@ -36,8 +36,8 @@ public abstract class SectoredRigidbodySync : BaseSectoredSync
ReferenceRigidbody = ReferenceTransform ? ReferenceTransform.GetAttachedOWRigidbody() : null;
}
protected override bool HasChanged() =>
base.HasChanged() ||
protected override bool CheckChanged() =>
base.CheckChanged() ||
Vector3.Distance(Velocity, _prevVelocity) > VelocityChangeThreshold ||
Vector3.Distance(AngularVelocity, _prevAngularVelocity) > AngularVelocityChangeThreshold;

View File

@ -198,7 +198,7 @@ public abstract class SyncBase : QSBNetworkTransform
/// <summary>
/// call the base method FIRST
/// </summary>
protected override bool HasChanged()
protected override bool CheckChanged()
{
GetFromAttached();
if (UseInterpolation)
@ -207,7 +207,7 @@ public abstract class SyncBase : QSBNetworkTransform
SmoothRotation = transform.rotation;
}
return base.HasChanged();
return base.CheckChanged();
}
/// <summary>

View File

@ -36,8 +36,8 @@ public abstract class UnsectoredRigidbodySync : BaseUnsectoredSync
ReferenceRigidbody = ReferenceTransform ? ReferenceTransform.GetAttachedOWRigidbody() : null;
}
protected override bool HasChanged() =>
base.HasChanged() ||
protected override bool CheckChanged() =>
base.CheckChanged() ||
Vector3.Distance(Velocity, _prevVelocity) > VelocityChangeThreshold ||
Vector3.Distance(AngularVelocity, _prevAngularVelocity) > AngularVelocityChangeThreshold;

View File

@ -1,12 +1,14 @@
using OWML.Common;
using QSB.Messaging;
using QSB.Messaging;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.ShipSync;
using QSB.Tools.ProbeLauncherTool.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
namespace QSB.Tools.ProbeLauncherTool.Messages;
public class EquipProbeLauncherMessage : QSBMessage<bool>
public class EquipProbeLauncherMessage : QSBWorldObjectMessage<QSBProbeLauncher, bool>
{
static EquipProbeLauncherMessage()
{
@ -14,37 +16,42 @@ public class EquipProbeLauncherMessage : QSBMessage<bool>
GlobalMessenger<ProbeLauncher>.AddListener(OWEvents.ProbeLauncherUnequipped, launcher => Handle(launcher, false));
}
private static bool _nonPlayerLauncherEquipped;
private static void Handle(ProbeLauncher launcher, bool equipped)
{
if (PlayerTransformSync.LocalInstance)
if (PlayerTransformSync.LocalInstance == null)
{
if (launcher != QSBPlayerManager.LocalPlayer.LocalProbeLauncher)
{
_nonPlayerLauncherEquipped = equipped;
return;
}
if (_nonPlayerLauncherEquipped)
{
DebugLog.ToConsole($"Warning - Trying to equip/unequip player launcher whilst non player launcher is still equipped?", MessageType.Warning);
return;
}
new EquipProbeLauncherMessage(equipped).Send();
return;
}
var local = launcher == QSBPlayerManager.LocalPlayer.LocalProbeLauncher;
if (local)
{
new PlayerEquipLauncherMessage(equipped).Send();
return;
}
var worldObject = launcher.GetWorldObject<QSBProbeLauncher>();
worldObject.SendMessage(new EquipProbeLauncherMessage(equipped));
}
private EquipProbeLauncherMessage(bool equipped) : base(equipped) { }
public override void OnReceiveRemote()
{
DebugLog.DebugWrite($"{From} equip {WorldObject}");
var player = QSBPlayerManager.GetPlayer(From);
player.ProbeLauncherEquipped = Data;
player.ProbeLauncher?.ChangeEquipState(Data);
player.ProbeLauncherEquipped = Data ? WorldObject : null;
if (player.FlyingShip && WorldObject.AttachedObject == ShipManager.Instance.CockpitController.GetShipProbeLauncher())
{
ShipManager.Instance.UpdateProbeLauncher(Data);
}
}
public override void OnReceiveLocal() =>
QSBPlayerManager.LocalPlayer.ProbeLauncherEquipped = Data;
public override void OnReceiveLocal()
{
QSBPlayerManager.LocalPlayer.ProbeLauncherEquipped = Data ? WorldObject : null;
}
}

View File

@ -0,0 +1,21 @@
using QSB.Messaging;
using QSB.Player;
namespace QSB.Tools.ProbeLauncherTool.Messages;
internal class PlayerEquipLauncherMessage : QSBMessage<bool>
{
public PlayerEquipLauncherMessage(bool equipped) : base(equipped) { }
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);
player.LocalProbeLauncherEquipped = Data;
player.ProbeLauncherTool?.ChangeEquipState(Data);
}
public override void OnReceiveLocal()
{
QSBPlayerManager.LocalPlayer.LocalProbeLauncherEquipped = Data;
}
}

View File

@ -11,6 +11,6 @@ internal class PlayerLaunchProbeMessage : QSBMessage
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);
player.ProbeLauncher.LaunchProbe();
player.ProbeLauncherTool.LaunchProbe();
}
}

View File

@ -13,6 +13,6 @@ internal class PlayerRetrieveProbeMessage : QSBMessage<bool>
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);
player.ProbeLauncher.RetrieveProbe(Data);
player.ProbeLauncherTool.RetrieveProbe(Data);
}
}

View File

@ -6,7 +6,7 @@ using System.Threading;
namespace QSB.Tools.ProbeLauncherTool.WorldObjects;
internal class QSBProbeLauncher : WorldObject<ProbeLauncher>
public class QSBProbeLauncher : WorldObject<ProbeLauncher>
{
public override async UniTask Init(CancellationToken ct) =>
AttachedObject.OnLaunchProbe += OnLaunchProbe;

View File

@ -86,8 +86,8 @@ public class QSBProbe : MonoBehaviour, ILightSource
gameObject.SetActive(true);
_lightSourceVol.SetVolumeActivation(true);
transform.position = _owner.ProbeLauncher.transform.position;
transform.rotation = _owner.ProbeLauncher.transform.rotation;
transform.position = _owner.ProbeLauncherTool.transform.position;
transform.rotation = _owner.ProbeLauncherTool.transform.rotation;
if (OnLaunchProbe == null)
{

View File

@ -1,7 +1,9 @@
using OWML.Common;
using QSB.Syncs.Sectored.Transforms;
using QSB.Tools.ProbeLauncherTool;
using QSB.Tools.ProbeLauncherTool.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.Tools.ProbeTool.TransformSync;
@ -58,9 +60,11 @@ public class PlayerProbeSync : SectoredTransformSync
DebugLog.ToConsole($"Warning - Could not find OWRigidbody of local probe.", MessageType.Warning);
}
var probeLauncher = Player.LocalProbeLauncher;
// TODO : make this sync to the *active* probe launcher's _launcherTransform
var launcherTransform = probeLauncher._launcherTransform;
var probeLauncher = Player.ProbeLauncherEquipped;
var launcherTransform = probeLauncher == null
? Player.LocalProbeLauncher._launcherTransform
: probeLauncher.AttachedObject._launcherTransform;
probeBody.SetPosition(launcherTransform.position);
probeBody.SetRotation(launcherTransform.rotation);

View File

@ -46,7 +46,13 @@ public class QSBTool : PlayerTool
_ditheringAnimator.SetVisible(false);
}
public virtual void OnEnable() => ToolGameObject?.SetActive(true);
public virtual void OnEnable()
{
if (!Player.FlyingShip)
{
ToolGameObject?.SetActive(true);
}
}
public virtual void OnDisable()
{
@ -71,13 +77,17 @@ public class QSBTool : PlayerTool
{
base.EquipTool();
if (_ditheringAnimator != null)
if (!Player.FlyingShip)
{
ToolGameObject?.SetActive(true);
_ditheringAnimator.SetVisible(true, .2f);
Player.AudioController.PlayEquipTool();
}
Player.AudioController.PlayEquipTool();
if (_ditheringAnimator != null)
{
_ditheringAnimator.SetVisible(true, .2f);
}
}
public override void UnequipTool()

View File

@ -1,6 +1,7 @@
using QSB.Messaging;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.ShipSync;
namespace QSB.Tools.SignalscopeTool.Messages;
@ -27,6 +28,11 @@ public class PlayerSignalscopeMessage : QSBMessage<bool>
var player = QSBPlayerManager.GetPlayer(From);
player.SignalscopeEquipped = Data;
player.Signalscope?.ChangeEquipState(Data);
if (player.FlyingShip)
{
ShipManager.Instance.UpdateSignalscope(Data);
}
}
public override void OnReceiveLocal() =>

View File

@ -22,6 +22,8 @@ public static class Extensions
/// </summary>
public static void SpawnLinked(this ILinkedWorldObject<NetworkBehaviour> worldObject, GameObject prefab, bool spawnWithServerAuthority)
{
DebugLog.DebugWrite($"SpawnLinked {prefab.name}");
var go = Object.Instantiate(prefab);
var networkBehaviour = go.GetComponent<ILinkedNetworkBehaviour>();

View File

@ -20,10 +20,12 @@ public abstract class QSBNetworkBehaviour : NetworkBehaviour
public override void OnStopClient() => RequestInitialStatesMessage.SendInitialState -= SendInitialState;
public bool HasChanged { get; private set; }
/// <summary>
/// checked before serializing
/// </summary>
protected abstract bool HasChanged();
protected abstract bool CheckChanged();
protected abstract void Serialize(NetworkWriter writer);
@ -54,7 +56,8 @@ public abstract class QSBNetworkBehaviour : NetworkBehaviour
{
_lastSendTime = NetworkTime.localTime;
if (!HasChanged())
HasChanged = CheckChanged();
if (!HasChanged)
{
return;
}

View File

@ -12,7 +12,7 @@ public abstract class BaseVariableSyncer<T> : QSBNetworkBehaviour
[NonSerialized]
public T Value;
protected override bool HasChanged() => !EqualityComparer<T>.Default.Equals(PrevValue, Value);
protected override bool CheckChanged() => !EqualityComparer<T>.Default.Equals(PrevValue, Value);
protected override void UpdatePrevData() => PrevValue = Value;
protected override void Serialize(NetworkWriter writer) => writer.Write(Value);
protected override void Deserialize(NetworkReader reader) => Value = reader.Read<T>();

View File

@ -9,6 +9,6 @@
"uniqueName": "Raicuparta.QuantumSpaceBuddies",
"version": "0.19.0",
"owmlVersion": "2.3.3",
"dependencies": [ "_nebula.MenuFramework" ],
"dependencies": [ "_nebula.MenuFramework", "JohnCorby.VanillaFix" ],
"pathsToPreserve": [ "debugsettings.json", "storage.json" ]
}