Merge branch 'dev' into model-ship-sync

This commit is contained in:
JohnCorby 2022-06-07 17:30:58 -07:00
commit 121f044d50
37 changed files with 454 additions and 72 deletions

View File

@ -25,7 +25,8 @@ internal class RemoteThrusterFlameController : MonoBehaviour
private Vector3 _thrusterFilter;
private float _baseLightRadius;
private float _currentScale;
private RemotePlayerFluidDetector _fluidDetector;
private bool _underwater;
private bool _initialized;
private PlayerInfo _attachedPlayer;
@ -43,6 +44,19 @@ internal class RemoteThrusterFlameController : MonoBehaviour
_light.enabled = false;
_light.shadows = LightShadows.Soft;
_initialized = true;
_underwater = false;
_fluidDetector = player.FluidDetector;
_fluidDetector.OnEnterFluidType += OnEnterExitFluidType;
_fluidDetector.OnExitFluidType += OnEnterExitFluidType;
}
private void OnDestroy()
{
if (_fluidDetector != null)
{
_fluidDetector.OnEnterFluidType -= OnEnterExitFluidType;
_fluidDetector.OnExitFluidType -= OnEnterExitFluidType;
}
}
private void Update()
@ -52,7 +66,10 @@ internal class RemoteThrusterFlameController : MonoBehaviour
return;
}
var num = _scaleByThrust.Evaluate(GetThrustFraction());
var num = _underwater
? 0f
: _scaleByThrust.Evaluate(GetThrustFraction());
if (_belowMaxThrustScalar < 1f)
{
num *= _belowMaxThrustScalar;
@ -65,7 +82,7 @@ internal class RemoteThrusterFlameController : MonoBehaviour
_scaleSpring.ResetVelocity();
}
if (_currentScale <= 0.001f)
if (_underwater && _currentScale <= 0.001f)
{
_currentScale = 0f;
_scaleSpring.ResetVelocity();
@ -73,10 +90,15 @@ internal class RemoteThrusterFlameController : MonoBehaviour
transform.localScale = Vector3.one * _currentScale;
_light.range = _baseLightRadius * _currentScale;
_thrusterRenderer.enabled = _currentScale > 0f;
_thrusterRenderer.enabled = _currentScale > 0f && _attachedPlayer.Visible;
_light.enabled = _currentScale > 0f;
}
private void OnEnterExitFluidType(FluidVolume.Type type)
{
this._underwater = this._fluidDetector.InFluidType(FluidVolume.Type.WATER);
}
private float GetThrustFraction() => Vector3.Dot(_attachedPlayer.JetpackAcceleration.AccelerationVariableSyncer.Value, _thrusterFilter);
private void OnRenderObject()

View File

@ -0,0 +1,75 @@
using QSB.Player;
using QSB.Utility;
using UnityEngine;
namespace QSB.Animation.Player.Thrusters;
internal class RemoteThrusterParticlesBehaviour : MonoBehaviour
{
[SerializeField]
private Thruster _thruster;
[SerializeField]
private bool _underwaterParticles;
private bool _initialized;
private PlayerInfo _attachedPlayer;
private RemotePlayerFluidDetector _fluidDetector;
private ParticleSystem _thrustingParticles;
private Vector3 _thrusterFilter;
private bool _underwater;
public void Init(PlayerInfo player)
{
_attachedPlayer = player;
_fluidDetector = player.FluidDetector;
_thrustingParticles = gameObject.GetComponent<ParticleSystem>();
_thrustingParticles.GetComponent<CustomRelativisticParticleSystem>().Init(player);
_thrusterFilter = OWUtilities.GetShipThrusterFilter(_thruster);
_underwater = false;
_thrustingParticles.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
_fluidDetector.OnEnterFluidType += OnEnterExitFluidType;
_fluidDetector.OnExitFluidType += OnEnterExitFluidType;
_initialized = true;
}
private void OnDestroy()
{
_initialized = false;
if (_fluidDetector != null)
{
_fluidDetector.OnEnterFluidType -= OnEnterExitFluidType;
_fluidDetector.OnExitFluidType -= OnEnterExitFluidType;
}
}
private void Update()
{
if (!_initialized)
{
return;
}
if (((_underwater != _underwaterParticles)
? 0f
: Vector3.Dot(_attachedPlayer.JetpackAcceleration.AccelerationVariableSyncer.Value, _thrusterFilter)) > 1f)
{
if (!_thrustingParticles.isPlaying)
{
_thrustingParticles.Play();
return;
}
}
else if (_thrustingParticles.isPlaying)
{
_thrustingParticles.Stop();
}
}
private void OnEnterExitFluidType(FluidVolume.Type type)
{
_underwater = _fluidDetector.InFluidType(FluidVolume.Type.WATER);
}
}

View File

@ -60,7 +60,7 @@ internal class RemoteThrusterWashController : MonoBehaviour
emissionThrusterScale = (!aboveSurface) ? 0f : (emissionThrusterScale * _emissionDistanceScale.Evaluate(hitInfo.distance));
if (emissionThrusterScale > 0f)
if (emissionThrusterScale > 0f && _attachedPlayer.Visible)
{
var position = hitInfo.point + (hitInfo.normal * 0.25f);
var rotation = Quaternion.LookRotation(hitInfo.normal);

View File

@ -9,11 +9,12 @@ internal static class ThrusterManager
{
var newVfx = player.Body.transform.Find("REMOTE_PlayerVFX").gameObject;
CreateThrusterWashController(newVfx.transform.Find("ThrusterWash").gameObject, player);
CreateThrusterFlameController(newVfx, player);
InitWashController(newVfx.transform.Find("ThrusterWash").gameObject, player);
InitFlameControllers(newVfx, player);
InitParticleControllers(newVfx, player);
}
private static void CreateThrusterFlameController(GameObject root, PlayerInfo player)
private static void InitFlameControllers(GameObject root, PlayerInfo player)
{
var existingControllers = root.GetComponentsInChildren<RemoteThrusterFlameController>(true);
foreach (var controller in existingControllers)
@ -22,7 +23,16 @@ internal static class ThrusterManager
}
}
private static void CreateThrusterWashController(GameObject root, PlayerInfo player)
private static void InitParticleControllers(GameObject root, PlayerInfo player)
{
var existingBehaviours = root.GetComponentsInChildren<RemoteThrusterParticlesBehaviour>(true);
foreach (var item in existingBehaviours)
{
item.Init(player);
}
}
private static void InitWashController(GameObject root, PlayerInfo player)
{
var newObj = root.GetComponent<RemoteThrusterWashController>();
newObj.Init(player);

Binary file not shown.

Binary file not shown.

View File

@ -87,6 +87,8 @@ public class RespawnOnDeath : MonoBehaviour
_playerResources._isSuffocating = false;
_playerResources.DebugRefillResources();
// death by oxygen turns this off, so we gotta enable it again
Delay.RunNextFrame(() => _playerResources.enabled = true);
_spaceSuit.RemoveSuit(true);
foreach (var pickupVolume in _suitPickupVolumes)

View File

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

View File

@ -42,7 +42,7 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
private const string DisconnectString = "DISCONNECT";
private const string StopHostingString = "STOP HOSTING";
private const string UpdateChangelog = $"QSB Version 0.19.0\r\nThis update syncs Echoes of the Eye content! A bit rough around the edges, but things will be polished up in later updates. Enjoy!";
private const string UpdateChangelog = $"QSB Version 0.20.0\r\nThis updates brings better ship syncing (including destruction), more things around the village being synced, and general bug fixes.";
private Action<bool> PopupClose;
@ -70,6 +70,23 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
QSBCore.Helper.Storage.Save(QSBCore.Storage, "storage.json");
QSBCore.MenuApi.RegisterStartupPopup(UpdateChangelog);
}
if (QSBCore.DebugSettings.AutoStart)
{
// auto host/connect
Delay.RunWhen(PlayerData.IsLoaded, () =>
{
if (DebugLog.ProcessInstanceId == 0)
{
Host(false);
}
else
{
QSBCore.DefaultServerIP = "localhost";
Connect();
}
});
}
}
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isUniverse)

View File

@ -40,10 +40,8 @@ public static class JoinLeaveSingularity
}
var go = new GameObject($"player {player} JoinLeaveSingularity");
var ct = CancellationTokenSource.CreateLinkedTokenSource(
go.GetCancellationTokenOnDestroy(),
player.TransformSync.GetCancellationTokenOnDestroy()
).Token;
// yes, it throws sometimes, but i cant destroy when the transform sync destroy or else the black hole doesn't happen
var ct = go.GetCancellationTokenOnDestroy();
UniTask.Create(async () =>
{
DebugLog.DebugWrite($"{go.name}: WARP TASK");

View File

@ -0,0 +1,43 @@
using HarmonyLib;
using QSB.Patches;
using UnityEngine;
namespace QSB.Player.Patches;
internal class VolumePatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
[HarmonyPostfix]
[HarmonyPatch(typeof(FluidVolume), nameof(FluidVolume.OnEffectVolumeEnter))]
public static void OnEffectVolumeEnter(FluidVolume __instance, GameObject hitObj)
{
var comp = hitObj.GetComponent<RemotePlayerFluidDetector>();
if (comp != null)
{
comp.AddVolume(__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(FluidVolume), nameof(FluidVolume.OnEffectVolumeExit))]
public static void OnEffectVolumeExit(FluidVolume __instance, GameObject hitObj)
{
var comp = hitObj.GetComponent<RemotePlayerFluidDetector>();
if (comp != null)
{
comp.RemoveVolume(__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(RingRiverFluidVolume), nameof(RingRiverFluidVolume.OnEffectVolumeEnter))]
public static void OnEffectVolumeEnter(RingRiverFluidVolume __instance, GameObject hitObj)
{
var comp = hitObj.GetComponent<RemotePlayerFluidDetector>();
if (comp != null)
{
comp.AddVolume(__instance);
}
}
}

View File

@ -69,13 +69,12 @@ public partial class PlayerInfo
SignalscopeEquipped = default;
TranslatorEquipped = default;
ProbeActive = default;
ProbeLauncherEquipped = default;
}
public void UpdateObjectsFromStates()
{
FlashLight.UpdateState(FlashlightActive);
FlashLight.UpdateState(FlashlightActive && Visible);
Translator.ChangeEquipState(TranslatorEquipped);
ProbeLauncherTool.ChangeEquipState(LocalProbeLauncherEquipped);
Signalscope.ChangeEquipState(SignalscopeEquipped);
@ -138,6 +137,14 @@ public partial class PlayerInfo
}
_ditheringAnimator.SetVisible(visible, seconds);
if (!visible)
{
FlashLight.UpdateState(false);
}
else
{
FlashLight.UpdateState(FlashlightActive);
}
}
public override string ToString() => $"{PlayerId}:{GetType().Name} ({Name})";

View File

@ -11,4 +11,5 @@ public partial class PlayerInfo
public JetpackAccelerationSync JetpackAcceleration { get; set; }
internal QSBDitheringAnimator _ditheringAnimator;
public DreamWorldSpawnAnimator DreamWorldSpawnAnimator { get; set; }
public RemotePlayerFluidDetector FluidDetector { get; set; }
}

View File

@ -0,0 +1,196 @@
using QSB.Utility;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace QSB.Player;
public class RemotePlayerFluidDetector : PriorityDetector
{
private SplashEffect[] _splashEffects;
[SerializeField]
private Transform _splashSpawnRoot;
private FluidTypeData[] _fluidDataByType;
protected RemotePlayerVelocity _velocity;
public event SpawnSplashEvent OnSpawnSplashEvent;
public event FluidTypeEvent OnEnterFluidType;
public event FluidTypeEvent OnExitFluidType;
public event FluidEvent OnEnterFluid;
public event FluidEvent OnExitFluid;
public delegate void SpawnSplashEvent(FluidVolume splashFluid);
public delegate void FluidTypeEvent(FluidVolume.Type fluidType);
public delegate void FluidEvent(FluidVolume volume);
public override void Awake()
{
base.Awake();
_velocity = gameObject.GetComponentInParent<RemotePlayerVelocity>();
_fluidDataByType = new FluidTypeData[9];
_splashSpawnRoot = _velocity.transform;
_splashEffects = new SplashEffect[4]
{
new SplashEffect()
{
fluidType = FluidVolume.Type.WATER,
minImpactSpeed = 15,
triggerEvent = SplashEffect.TriggerEvent.OnEntry,
splashPrefab = Resources.Load<GameObject>("prefabs/particles/Prefab_OceanEntry_Player"),
ignoreSphereAligment = false
},
new SplashEffect()
{
fluidType = FluidVolume.Type.CLOUD,
minImpactSpeed = 15,
triggerEvent = SplashEffect.TriggerEvent.OnEntry,
splashPrefab = Resources.Load<GameObject>("prefabs/particles/Prefab_CloudEntry_Player"),
ignoreSphereAligment = false
},
new SplashEffect()
{
fluidType = FluidVolume.Type.CLOUD,
minImpactSpeed = 15,
triggerEvent = SplashEffect.TriggerEvent.OnExit,
splashPrefab = Resources.Load<GameObject>("prefabs/particles/Prefab_CloudExit_Player"),
ignoreSphereAligment = true
},
new SplashEffect()
{
fluidType = FluidVolume.Type.SAND,
minImpactSpeed = 15,
triggerEvent = SplashEffect.TriggerEvent.OnEntryOrExit,
splashPrefab = Resources.Load<GameObject>("prefabs/particles/Prefab_HEA_Player_SandSplash"),
ignoreSphereAligment = false
}
};
}
public bool InFluidType(FluidVolume.Type fluidType)
{
return _fluidDataByType[(int)fluidType].count > 0;
}
public override void AddVolume(EffectVolume eVol)
{
var fluidVolume = eVol as FluidVolume;
if (fluidVolume != null && (!fluidVolume.IsInheritible()))
{
base.AddVolume(eVol);
}
}
public override void RemoveVolume(EffectVolume eVol)
{
var fluidVolume = eVol as FluidVolume;
if (fluidVolume != null && (!fluidVolume.IsInheritible()))
{
base.RemoveVolume(eVol);
}
}
public override void OnVolumeActivated(PriorityVolume volume)
{
var fluidVolume = volume as FluidVolume;
var fluidType = fluidVolume.GetFluidType();
var fluidDataByType = _fluidDataByType;
var type = fluidType;
fluidDataByType[(int)type].count = fluidDataByType[(int)type].count + 1;
OnEnterFluid?.Invoke(fluidVolume);
if (_fluidDataByType[(int)fluidType].count == 1)
{
OnEnterFluidType_Internal(fluidVolume);
OnEnterFluidType?.Invoke(fluidType);
}
}
public override void OnVolumeDeactivated(PriorityVolume volume)
{
var fluidVolume = volume as FluidVolume;
var fluidType = fluidVolume.GetFluidType();
var fluidDataByType = _fluidDataByType;
var type = fluidType;
fluidDataByType[(int)type].count = fluidDataByType[(int)type].count - 1;
OnExitFluid?.Invoke(fluidVolume);
if (_fluidDataByType[(int)fluidType].count == 0)
{
OnExitFluidType_Internal(fluidVolume);
OnExitFluidType?.Invoke(fluidType);
}
}
protected virtual void OnEnterFluidType_Internal(FluidVolume fluid)
{
SpawnSplash(fluid, SplashEffect.TriggerEvent.OnEntry);
if (fluid is SphereOceanFluidVolume)
{
var component = GetComponent<OceanSplasher>();
var magnitude = (_velocity.Velocity - fluid._attachedBody.GetVelocity()).magnitude;
if (component != null && magnitude >= component.minSplashSpeed)
{
component.Splash();
}
}
}
protected virtual void OnExitFluidType_Internal(FluidVolume fluid)
{
SpawnSplash(fluid, SplashEffect.TriggerEvent.OnExit);
}
private void SpawnSplash(FluidVolume fluid, SplashEffect.TriggerEvent triggerEvent)
{
if (CompareName(Name.Player) && PlayerState.IsRidingRaft(false) && fluid.GetFluidType() == FluidVolume.Type.WATER)
{
return;
}
if (fluid.GetFluidType() == FluidVolume.Type.CLOUD && InFluidType(FluidVolume.Type.WATER))
{
return;
}
var impactVelocity = _velocity.Velocity - fluid._attachedBody.GetVelocity();
var magnitude = impactVelocity.magnitude;
var num = -1;
for (var i = 0; i < _splashEffects.Length; i++)
{
if (_splashEffects[i].fluidType == fluid.GetFluidType() && magnitude > _splashEffects[i].minImpactSpeed && (triggerEvent & _splashEffects[i].triggerEvent) > (SplashEffect.TriggerEvent)0 && (num == -1 || _splashEffects[i].minImpactSpeed > _splashEffects[num].minImpactSpeed))
{
num = i;
}
}
if (num > -1)
{
var splashPrefab = _splashEffects[num].splashPrefab;
var toDirection = (_splashEffects[num].ignoreSphereAligment ? (-impactVelocity) : fluid.GetSplashAlignment(_splashSpawnRoot.position, impactVelocity));
var rotation = Quaternion.FromToRotation(_splashSpawnRoot.up, toDirection) * _splashSpawnRoot.rotation;
var gameObject = Instantiate(splashPrefab, _splashSpawnRoot.position, rotation);
if (gameObject.GetComponent<OWRigidbody>() != null)
{
Debug.LogError("SPLASHES SHOULD NO LONGER HAVE RIGIDBODIES!!!", gameObject);
gameObject.GetComponent<OWRigidbody>().MakeKinematic();
}
gameObject.transform.parent = fluid.transform;
fluid.RegisterSplashTransform(gameObject.transform);
var component = gameObject.GetComponent<SplashAudioController>();
if (component != null)
{
component.PlaySplash();
}
OnSpawnSplashEvent?.Invoke(fluid);
}
}
}

View File

@ -43,6 +43,7 @@ public static class RemotePlayerCreation
// Variable naming convention is broken here to reflect OW unity project (with REMOTE_ prefixed) for readability
var REMOTE_Player_Body = Object.Instantiate(GetPrefab());
var REMOTE_PlayerDetector = REMOTE_Player_Body.transform.Find("REMOTE_PlayerDetector");
var REMOTE_PlayerCamera = REMOTE_Player_Body.transform.Find("REMOTE_PlayerCamera").gameObject;
var REMOTE_RoastingSystem = REMOTE_Player_Body.transform.Find("REMOTE_RoastingSystem").gameObject;
var REMOTE_Stick_Root = REMOTE_RoastingSystem.transform.Find("REMOTE_Stick_Root").gameObject;
@ -56,6 +57,7 @@ public static class RemotePlayerCreation
player.Body = REMOTE_Player_Body;
player.ThrusterLightTracker = player.Body.GetComponentInChildren<ThrusterLightTracker>();
player.FluidDetector = REMOTE_PlayerDetector.GetComponent<RemotePlayerFluidDetector>();
player.AnimationSync.InitRemote(REMOTE_Traveller_HEA_Player_v2.transform);

View File

@ -104,6 +104,13 @@ public class QSBCore : ModBehaviour
);
}
if (DebugSettings.AutoStart)
{
DebugSettings.UseKcpTransport = true;
DebugSettings.SkipTitleScreen = true;
DebugSettings.DebugMode = true;
}
RegisterAddons();
InitAssemblies();

View File

@ -24,7 +24,7 @@ public class ShipThrusterVariableSyncer : NetworkBehaviour
return;
}
if (AccelerationSyncer.HasChanged)
if (AccelerationSyncer.public_HasChanged())
{
if (AccelerationSyncer.Value == Vector3.zero)
{
@ -47,6 +47,11 @@ public class ShipThrusterVariableSyncer : NetworkBehaviour
}
}
private void GetFromShip() => AccelerationSyncer.Value = _thrusterModel.GetLocalAcceleration();
private void GetFromShip()
{
if (_thrusterModel)
{
AccelerationSyncer.Value = _thrusterModel.GetLocalAcceleration();
}
}
}

View File

@ -15,10 +15,7 @@ internal class ShipLegTransformSync : SectoredRigidbodySync, ILinkedNetworkBehav
=> AttachedTransform
&& base.CheckValid();
protected override bool CheckReady()
=> _qsbModule != null
&& _qsbModule.AttachedObject.isDetached
&& base.CheckReady();
protected override bool CheckReady() => base.CheckReady() && _qsbModule.AttachedObject.isDetached;
protected override bool UseInterpolation => true;

View File

@ -15,10 +15,7 @@ internal class ShipModuleTransformSync : SectoredRigidbodySync, ILinkedNetworkBe
=> AttachedTransform
&& base.CheckValid();
protected override bool CheckReady()
=> _qsbModule != null
&& _qsbModule.AttachedObject.isDetached
&& base.CheckReady();
protected override bool CheckReady() => base.CheckReady() && _qsbModule.AttachedObject.isDetached;
protected override bool UseInterpolation => true;

View File

@ -14,7 +14,7 @@ public class QSBNetworkTransform : QSBNetworkBehaviour
private Vector3 _prevPosition;
private Quaternion _prevRotation;
protected override bool CheckChanged() =>
protected override bool HasChanged() =>
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 CheckChanged() =>
protected override bool HasChanged() =>
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 CheckChanged() =>
base.CheckChanged() ||
protected override bool HasChanged() =>
base.HasChanged() ||
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 CheckChanged()
protected override bool HasChanged()
{
GetFromAttached();
if (UseInterpolation)
@ -207,7 +207,7 @@ public abstract class SyncBase : QSBNetworkTransform
SmoothRotation = transform.rotation;
}
return base.CheckChanged();
return base.HasChanged();
}
/// <summary>

View File

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

View File

@ -1,4 +1,5 @@
using HarmonyLib;
using QSB.Inputs;
using QSB.Patches;
using QSB.Utility;
@ -17,6 +18,16 @@ internal class TimePatches : QSBPatch
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerCameraEffectController), nameof(PlayerCameraEffectController.WakeUp))]
public static void PlayerCameraEffectController_WakeUp(PlayerCameraEffectController __instance)
{
// prevent funny thing when you pause while waking up
QSBInputManager.Instance.SetInputsEnabled(false);
Delay.RunWhen(() => !__instance._isOpeningEyes, () => QSBInputManager.Instance.SetInputsEnabled(true));
}
[HarmonyPrefix]
[HarmonyPatch(typeof(OWTime), nameof(OWTime.Pause))]
public static bool StopPausing(OWTime.PauseType pauseType)

View File

@ -26,7 +26,7 @@ public class PlayerFlashlightMessage : QSBMessage<bool>
{
var player = QSBPlayerManager.GetPlayer(From);
player.FlashlightActive = Data;
player.FlashLight?.UpdateState(Data);
player.FlashLight?.UpdateState(Data && player.Visible);
}
public override void OnReceiveLocal() =>

View File

@ -48,7 +48,7 @@ public class QSBTool : PlayerTool
public virtual void OnEnable()
{
if (!Player.FlyingShip)
if (!Player?.FlyingShip ?? false)
{
ToolGameObject?.SetActive(true);
}

View File

@ -46,19 +46,6 @@ public class DebugActions : MonoBehaviour, IAddComponentOnStart
return;
}
/*
* 1 - Warp to first non local player
* 2 - Enter dream world
* 3 - Destroy probe
* 4 - Damage ship electricals
* 5 - Trigger supernova
* 6 - Set MET_SOLANUM
* 7 - Warp to vessel
* 8 - Place warp core into vessel
* 9 - Load eye scene
* 0 - Respawn some player
*/
if (Keyboard.current[Key.Numpad1].wasPressedThisFrame)
{
var otherPlayers = QSBPlayerManager.PlayerList.Where(x => !x.IsLocalPlayer).ToList();

View File

@ -6,14 +6,14 @@ namespace QSB.Utility;
public static class DebugLog
{
private static readonly int _processInstanceId = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName)
public static readonly int ProcessInstanceId = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName)
.IndexOf(x => x.Id == Process.GetCurrentProcess().Id);
public static void ToConsole(string message, MessageType type = MessageType.Message)
{
if (QSBCore.DebugSettings.InstanceIdInLogs)
{
message = $"[{_processInstanceId}] " + message;
message = $"[{ProcessInstanceId}] " + message;
}
QSBCore.Helper.Console.WriteLine(message, type, GetCallingType(new StackTrace()));

View File

@ -20,6 +20,12 @@ public class DebugSettings
[JsonProperty("avoidTimeSync")]
public bool AvoidTimeSync;
[JsonProperty("autoStart")]
public bool AutoStart;
[JsonProperty("skipTitleScreen")]
public bool SkipTitleScreen;
[JsonProperty("debugMode")]
public bool DebugMode;
@ -43,10 +49,6 @@ public class DebugSettings
private bool _drawGhostAI;
public bool DrawGhostAI => DebugMode && _drawGhostAI;
[JsonProperty("skipTitleScreen")]
private bool _skipTitleScreen;
public bool SkipTitleScreen => DebugMode && _skipTitleScreen;
[JsonProperty("greySkybox")]
private bool _greySkybox;
public bool GreySkybox => DebugMode && _greySkybox;

View File

@ -22,8 +22,6 @@ 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,12 +20,10 @@ 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 CheckChanged();
protected abstract bool HasChanged();
protected abstract void Serialize(NetworkWriter writer);
@ -56,8 +54,7 @@ public abstract class QSBNetworkBehaviour : NetworkBehaviour
{
_lastSendTime = NetworkTime.localTime;
HasChanged = CheckChanged();
if (!HasChanged)
if (!HasChanged())
{
return;
}

View File

@ -12,7 +12,8 @@ public abstract class BaseVariableSyncer<T> : QSBNetworkBehaviour
[NonSerialized]
public T Value;
protected override bool CheckChanged() => !EqualityComparer<T>.Default.Equals(PrevValue, Value);
public bool Bruh() => HasChanged();
protected override bool HasChanged() => !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

@ -4,4 +4,8 @@ namespace QSB.Utility.VariableSync;
public class Vector3VariableSyncer : BaseVariableSyncer<Vector3>
{
/// <summary>
/// hack for ShipThrusterVariableSyncer
/// </summary>
public bool public_HasChanged() => HasChanged();
}

View File

@ -4,12 +4,13 @@
"instanceIdInLogs": false,
"hookDebugLogs": false,
"avoidTimeSync": false,
"autoStart": false,
"skipTitleScreen": false,
"debugMode": false,
"drawGui": false,
"drawLines": false,
"drawLabels": false,
"drawQuantumVisibilityObjects": false,
"drawGhostAI": false,
"skipTitleScreen": false,
"greySkybox": false
}

View File

@ -7,7 +7,7 @@
"body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications."
},
"uniqueName": "Raicuparta.QuantumSpaceBuddies",
"version": "0.19.0",
"version": "0.20.0",
"owmlVersion": "2.3.3",
"dependencies": [ "_nebula.MenuFramework", "JohnCorby.VanillaFix" ],
"pathsToPreserve": [ "debugsettings.json", "storage.json" ]

View File

@ -132,14 +132,15 @@ The template for this file is this :
"instanceIdInLogs": false,
"hookDebugLogs": false,
"avoidTimeSync": false,
"autoStart": false,
"skipTitleScreen": false,
"debugMode": false,
"drawGui": false,
"drawLines": false,
"drawLabels": false,
"drawQuantumVisibilityObjects": false,
"skipTitleScreen": false,
"greySkybox": false,
"drawGhostAI": false
"drawGhostAI": false,
"greySkybox": false
}
```
@ -148,14 +149,15 @@ The template for this file is this :
- instanceIdInLogs - Appends the game instance id to every log message sent.
- hookDebugLogs - Print Unity logs and warnings.
- avoidTimeSync - Disables the syncing of time.
- autoStart - Host/connect automatically for faster testing.
- skipTitleScreen - Auto-skips the splash screen.
- debugMode - Enables debug mode. If this is set to `false`, none of the following settings do anything.
- drawGui - Draws a GUI at the top of the screen that gives information on many things.
- drawLines - Draws gizmo-esque lines around things. Indicates reference sectors/transforms, triggers, etc. LAGGY.
- drawLabels - Draws GUI labels attached to some objects. LAGGY.
- drawQuantumVisibilityObjects - Indicates visibility objects with an orange shape.
- skipTitleScreen - Auto-skips the splash screen.
- greySkybox - Turns the skybox grey. Useful in the Eye, where it's pretty dark.
- drawGhostAI - Draws debug lines and labels just for the ghosts.
- greySkybox - Turns the skybox grey. Useful in the Eye, where it's pretty dark.
**Warning : Mod development can lead to unexpected errors in your computer system.**
- **When editing the networking code, mistakes can lead to QSB overwhelming your network connection with excess packets**.