mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-19 12:40:56 +00:00
Merge branch 'dev' into model-ship-sync
This commit is contained in:
commit
121f044d50
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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.
@ -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)
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
|
43
QSB/Player/Patches/VolumePatches.cs
Normal file
43
QSB/Player/Patches/VolumePatches.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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})";
|
||||
|
@ -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; }
|
||||
}
|
||||
|
196
QSB/Player/RemotePlayerFluidDetector.cs
Normal file
196
QSB/Player/RemotePlayerFluidDetector.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -104,6 +104,13 @@ public class QSBCore : ModBehaviour
|
||||
);
|
||||
}
|
||||
|
||||
if (DebugSettings.AutoStart)
|
||||
{
|
||||
DebugSettings.UseKcpTransport = true;
|
||||
DebugSettings.SkipTitleScreen = true;
|
||||
DebugSettings.DebugMode = true;
|
||||
}
|
||||
|
||||
RegisterAddons();
|
||||
|
||||
InitAssemblies();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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() =>
|
||||
|
@ -48,7 +48,7 @@ public class QSBTool : PlayerTool
|
||||
|
||||
public virtual void OnEnable()
|
||||
{
|
||||
if (!Player.FlyingShip)
|
||||
if (!Player?.FlyingShip ?? false)
|
||||
{
|
||||
ToolGameObject?.SetActive(true);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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()));
|
||||
|
@ -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;
|
||||
|
@ -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>();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>();
|
||||
|
@ -4,4 +4,8 @@ namespace QSB.Utility.VariableSync;
|
||||
|
||||
public class Vector3VariableSyncer : BaseVariableSyncer<Vector3>
|
||||
{
|
||||
/// <summary>
|
||||
/// hack for ShipThrusterVariableSyncer
|
||||
/// </summary>
|
||||
public bool public_HasChanged() => HasChanged();
|
||||
}
|
@ -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
|
||||
}
|
@ -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" ]
|
||||
|
12
README.md
12
README.md
@ -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**.
|
||||
|
Loading…
x
Reference in New Issue
Block a user