Merge branch 'dev' into mirror

This commit is contained in:
JohnCorby 2022-01-13 14:58:02 -08:00
commit 66d088b727
63 changed files with 713 additions and 317 deletions

View File

@ -53,6 +53,7 @@ namespace QSB.Anglerfish.Patches
{
return true;
}
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
switch (__instance._currentState)
@ -64,6 +65,7 @@ namespace QSB.Anglerfish.Patches
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
break;
case AnglerfishController.AnglerState.Chasing:
if (qsbAngler.TargetTransform == null)
@ -72,6 +74,7 @@ namespace QSB.Anglerfish.Patches
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
if ((qsbAngler.TargetTransform.position - __instance._anglerBody.GetPosition()).sqrMagnitude > __instance._escapeDistance * __instance._escapeDistance)
{
qsbAngler.TargetTransform = null;
@ -79,6 +82,7 @@ namespace QSB.Anglerfish.Patches
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
break;
case AnglerfishController.AnglerState.Consuming:
if (!__instance._consumeComplete)
@ -89,6 +93,7 @@ namespace QSB.Anglerfish.Patches
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
var num = Time.time - __instance._consumeStartTime;
if (qsbAngler.TargetTransform.CompareTag("Player") && num > __instance._consumeDeathDelay)
{
@ -96,18 +101,21 @@ namespace QSB.Anglerfish.Patches
__instance._consumeComplete = true;
return false;
}
if (qsbAngler.TargetTransform.CompareTag("Ship"))
{
if (num > __instance._consumeShipCrushDelay)
{
qsbAngler.TargetTransform.GetComponentInChildren<ShipDamageController>().TriggerSystemFailure();
}
if (num > __instance._consumeDeathDelay)
{
if (PlayerState.IsInsideShip())
{
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
}
__instance._consumeComplete = true;
return false;
}
@ -118,6 +126,7 @@ namespace QSB.Anglerfish.Patches
qsbAngler.TargetTransform = null;
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
break;
case AnglerfishController.AnglerState.Stunned:
__instance._stunTimer -= Time.deltaTime;
@ -129,9 +138,11 @@ namespace QSB.Anglerfish.Patches
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
break;
default:
return false;
@ -148,6 +159,7 @@ namespace QSB.Anglerfish.Patches
{
return true;
}
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
qsbAngler.UpdateTargetVelocity();
@ -155,6 +167,7 @@ namespace QSB.Anglerfish.Patches
{
__instance.ApplyDrag(10f);
}
switch (__instance._currentState)
{
case AnglerfishController.AnglerState.Lurking:
@ -169,6 +182,7 @@ namespace QSB.Anglerfish.Patches
__instance.MoveTowardsTarget(targetPos, __instance._investigateSpeed, __instance._acceleration);
return false;
}
break;
}
case AnglerfishController.AnglerState.Chasing:
@ -200,6 +214,7 @@ namespace QSB.Anglerfish.Patches
d = Mathf.Lerp(num4, 0f, num8 * num8);
}
}
__instance._targetPos = qsbAngler.TargetTransform.position + normalized * d;
__instance.RotateTowardsTarget(__instance._targetPos, __instance._turnSpeed, __instance._quickTurnSpeed);
if (!__instance._turningInPlace)
@ -207,6 +222,7 @@ namespace QSB.Anglerfish.Patches
__instance.MoveTowardsTarget(__instance._targetPos, __instance._chaseSpeed, __instance._acceleration);
return false;
}
break;
}
case AnglerfishController.AnglerState.Consuming:
@ -254,6 +270,7 @@ namespace QSB.Anglerfish.Patches
{
return false;
}
if ((noiseMaker.GetNoiseOrigin() - __instance.transform.position).sqrMagnitude < __instance._pursueDistance * __instance._pursueDistance)
{
if (qsbAngler.TargetTransform != noiseMaker.GetAttachedBody().transform)
@ -263,6 +280,7 @@ namespace QSB.Anglerfish.Patches
{
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
}
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
@ -274,6 +292,7 @@ namespace QSB.Anglerfish.Patches
{
__instance.ChangeState(AnglerfishController.AnglerState.Investigating);
}
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
@ -293,8 +312,10 @@ namespace QSB.Anglerfish.Patches
{
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
}
return false;
}
if (caughtBody.CompareTag("Player") || caughtBody.CompareTag("Ship"))
{
qsbAngler.TargetTransform = caughtBody.transform;

View File

@ -35,6 +35,7 @@ namespace QSB.Anglerfish.TransformSync
{
NetIdentity.UnregisterAuthQueue();
}
AttachedObject.OnUnsuspendOWRigidbody -= OnUnsuspend;
AttachedObject.OnSuspendOWRigidbody -= OnSuspend;
}
@ -53,6 +54,7 @@ namespace QSB.Anglerfish.TransformSync
{
NetIdentity.RegisterAuthQueue();
}
AttachedObject.OnUnsuspendOWRigidbody += OnUnsuspend;
AttachedObject.OnSuspendOWRigidbody += OnSuspend;
NetIdentity.SendAuthQueueMessage(AttachedObject.IsSuspended() ? AuthQueueAction.Remove : AuthQueueAction.Add);

View File

@ -110,6 +110,7 @@ namespace QSB.Animation.NPC.Patches
var qsbObj = __instance.GetWorldObject<QSBCharacterAnimController>();
new EnterLeaveMessage(EnterLeaveType.EnterNonNomaiHeadZone, qsbObj.ObjectId).Send();
}
return false;
}

View File

@ -63,6 +63,7 @@ namespace QSB.Animation.NPC.Patches
var qsbObj = __instance._solanumAnimController.GetWorldObject<QSBSolanumAnimController>();
new EnterLeaveMessage(EnterLeaveType.ExitNomaiHeadZone, qsbObj.ObjectId).Send();
}
return false;
}

View File

@ -32,7 +32,6 @@ namespace QSB.Animation.NPC.Patches
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TravelerController), nameof(TravelerController.StartConversation))]
public static bool StartConversation(TravelerController __instance)
@ -44,6 +43,7 @@ namespace QSB.Animation.NPC.Patches
: __instance._animator.GetCurrentAnimatorStateInfo(0).fullPathHash;
__instance._animator.SetTrigger("Talking");
}
Locator.GetTravelerAudioManager().StopTravelerAudio(__instance);
return false;
@ -58,6 +58,7 @@ namespace QSB.Animation.NPC.Patches
__instance._animator.CrossFadeInFixedTime("Gabbro_Talking", 1.8f);
__instance._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Talking", 1.8f);
}
Locator.GetTravelerAudioManager().StopTravelerAudio(__instance);
return false;
@ -78,6 +79,7 @@ namespace QSB.Animation.NPC.Patches
__instance._animator.SetTrigger("Playing");
}
}
Locator.GetTravelerAudioManager().PlayTravelerAudio(__instance, audioDelay);
return false;
@ -92,6 +94,7 @@ namespace QSB.Animation.NPC.Patches
__instance._animator.CrossFadeInFixedTime("Gabbro_Playing", audioDelay, -1, -audioDelay);
__instance._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Playing", audioDelay, -1, -audioDelay);
}
Locator.GetTravelerAudioManager().PlayTravelerAudio(__instance, audioDelay);
if (DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_REMINDER") || DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION"))
{

View File

@ -41,9 +41,8 @@ namespace QSB.Animation.Player
QSBSceneManager.OnUniverseSceneLoaded += OnUniverseSceneLoaded;
}
protected override void OnDestroy()
protected void OnDestroy()
{
base.OnDestroy();
Destroy(InvisibleAnimator);
Destroy(NetworkAnimator);
QSBSceneManager.OnUniverseSceneLoaded -= OnUniverseSceneLoaded;

View File

@ -7,26 +7,26 @@ namespace QSB.Animation.Player.Messages
{
internal class AnimationTriggerMessage : QSBMessage
{
private uint AttachedNetId;
private uint PlayerId;
private string Name;
public AnimationTriggerMessage(uint attachedNetId, string name)
public AnimationTriggerMessage(uint playerId, string name)
{
AttachedNetId = attachedNetId;
PlayerId = playerId;
Name = name;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(AttachedNetId);
writer.Write(PlayerId);
writer.Write(Name);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
AttachedNetId = reader.ReadUInt32();
PlayerId = reader.ReadUInt32();
Name = reader.ReadString();
}
@ -34,7 +34,7 @@ namespace QSB.Animation.Player.Messages
public override void OnReceiveRemote()
{
var animationSync = QSBPlayerManager.GetSyncObject<AnimationSync>(AttachedNetId);
var animationSync = QSBPlayerManager.GetPlayer(PlayerId).AnimationSync;
if (animationSync == null)
{
return;

View File

@ -1,5 +1,4 @@
using QSB.Instruments;
using QSB.Messaging;
using QSB.Messaging;
using QSB.Player;
using QSB.WorldSync;
using QuantumUNET.Transport;
@ -39,7 +38,7 @@ namespace QSB.Animation.Player.Messages
}
player.AnimationSync.SetAnimationType(Value);
QSBPlayerManager.GetSyncObject<InstrumentsManager>(PlayerId).CheckInstrumentProps(Value);
player.InstrumentsManager.CheckInstrumentProps(Value);
}
}
}

View File

@ -62,16 +62,15 @@ namespace QSB.Animation.Player.Patches
__instance._animator.SetBool("UsingJetpack", isInZeroG && PlayerState.IsWearingSuit());
if (__instance._justBecameGrounded)
{
var playerAnimationSync = QSBPlayerManager.LocalPlayer.AnimationSync;
if (__instance._justTookFallDamage)
{
__instance._animator.SetTrigger("LandHard");
new AnimationTriggerMessage(playerAnimationSync.AttachedNetId, "LandHard").Send();
new AnimationTriggerMessage(QSBPlayerManager.LocalPlayerId, "LandHard").Send();
}
else
{
__instance._animator.SetTrigger("Land");
new AnimationTriggerMessage(playerAnimationSync.AttachedNetId, "Land").Send();
new AnimationTriggerMessage(QSBPlayerManager.LocalPlayerId, "Land").Send();
}
}
@ -128,8 +127,7 @@ namespace QSB.Animation.Player.Patches
}
__instance._animator.SetTrigger("Jump");
var playerAnimationSync = QSBPlayerManager.LocalPlayer.AnimationSync;
new AnimationTriggerMessage(playerAnimationSync.AttachedNetId, "Jump").Send();
new AnimationTriggerMessage(QSBPlayerManager.LocalPlayerId, "Jump").Send();
return false;
}
}

View File

@ -135,6 +135,7 @@ namespace QSB.ClientServerStateSync
{
newState = ClientState.AliveInEye;
}
break;
default:
newState = ClientState.NotLoaded;

View File

@ -11,7 +11,11 @@ namespace QSB.DeathSync.Messages
{
private int NecronomiconIndex;
public PlayerDeathMessage(DeathType type) => NecronomiconIndex = Necronomicon.GetRandomIndex(type);
public PlayerDeathMessage(DeathType type)
{
Value = type;
NecronomiconIndex = Necronomicon.GetRandomIndex(type);
}
public override void Serialize(QNetworkWriter writer)
{
@ -37,7 +41,7 @@ namespace QSB.DeathSync.Messages
var player = QSBPlayerManager.GetPlayer(From);
var playerName = player.Name;
var deathMessage = Necronomicon.GetPhrase(Value, NecronomiconIndex);
if (deathMessage != string.Empty)
if (deathMessage != null)
{
DebugLog.ToAll(string.Format(deathMessage, playerName));
}

View File

@ -144,11 +144,13 @@ namespace QSB.DeathSync
};
public static string GetPhrase(DeathType deathType, int index)
=> !Darkhold.ContainsKey(deathType)
? string.Empty
: Darkhold[deathType][index];
=> Darkhold.ContainsKey(deathType)
? Darkhold[deathType][index]
: null;
public static int GetRandomIndex(DeathType deathType)
=> new Random().Next(0, Darkhold[deathType].Length);
=> Darkhold.ContainsKey(deathType)
? new Random().Next(0, Darkhold[deathType].Length)
: -1;
}
}

View File

@ -0,0 +1,127 @@
using QSB.Messaging;
using QSB.Player;
using QSB.Player.Messages;
using QSB.Utility;
using QSB.WorldSync;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace QSB.EyeOfTheUniverse.CosmicInflation
{
internal class InflationManager : WorldObjectManager
{
public static InflationManager Instance { get; private set; }
private readonly List<PlayerInfo> _playersInFog = new();
private CosmicInflationController _controller;
public override WorldObjectType WorldObjectType => WorldObjectType.Eye;
public override void Awake()
{
base.Awake();
Instance = this;
QSBPlayerManager.OnRemovePlayer += OnPlayerLeave;
}
private void OnPlayerLeave(uint id)
{
_playersInFog.Remove(QSBPlayerManager.GetPlayer(id));
// wait 1 frame for player to be removed
QSBCore.UnityEvents.FireOnNextUpdate(() =>
{
if (QSBCore.IsInMultiplayer && _playersInFog.Count == QSBPlayerManager.PlayerList.Count)
{
StartCollapse();
}
});
}
protected override void RebuildWorldObjects(OWScene scene)
{
_playersInFog.Clear();
if (_controller != null)
{
_controller._smokeSphereTrigger.OnEntry -= OnEntry;
}
_controller = QSBWorldSync.GetUnityObjects<CosmicInflationController>().First();
_controller._smokeSphereTrigger.OnEntry -= _controller.OnEnterFogSphere;
_controller._smokeSphereTrigger.OnEntry += OnEntry;
}
private void OnEntry(GameObject hitObj)
{
if (hitObj.CompareTag("PlayerCameraDetector") && _controller._state == CosmicInflationController.State.ReadyToCollapse)
{
_controller._smokeSphereTrigger.SetTriggerActivation(false);
_controller._probeDestroyTrigger.SetTriggerActivation(false);
new EnterLeaveMessage(EnterLeaveType.EnterCosmicFog).Send();
DebugLog.DebugWrite("disable input, wait for other players to enter");
var repelVolume = (WhiteHoleFluidVolume)_controller._repelVolume;
repelVolume._flowSpeed = -repelVolume._flowSpeed;
repelVolume._massiveFlowSpeed = -repelVolume._massiveFlowSpeed;
repelVolume.SetVolumeActivation(true);
QSBPlayerManager.HideAllPlayers();
ReticleController.Hide();
Locator.GetFlashlight().TurnOff(false);
Locator.GetPromptManager().SetPromptsVisible(false);
OWInput.ChangeInputMode(InputMode.None);
}
}
public void Enter(PlayerInfo player)
{
_playersInFog.Add(player);
if (player != QSBPlayerManager.LocalPlayer)
{
DebugLog.DebugWrite($"fade out player {player.PlayerId}");
player.DitheringAnimator.SetVisible(false, 3);
}
if (_playersInFog.Count == QSBPlayerManager.PlayerList.Count)
{
StartCollapse();
}
}
private void StartCollapse()
{
DebugLog.DebugWrite("fade in everyone, fog sphere collapse");
var repelVolume = (WhiteHoleFluidVolume)_controller._repelVolume;
repelVolume.SetVolumeActivation(false);
QSBPlayerManager.ShowAllPlayers();
_controller._state = CosmicInflationController.State.Collapsing;
_controller._stateChangeTime = Time.time;
_controller._collapseStartPos = _controller._possibilitySphereRoot.localPosition;
_controller._smokeSphereTrigger.SetTriggerActivation(false);
_controller._inflationLight.FadeTo(1f, 1f);
_controller._possibilitySphereController.OnCollapse();
if (_controller._campsiteController.GetUseAltPostCollapseSocket())
{
_controller._playerPostCollapseSocket = _controller._altPlayerPostCollapseSocket;
_controller._altTravelerToHidePostCollapse.SetActive(false);
}
Locator.GetPlayerBody().SetPosition(_controller._playerPostCollapseSocket.position);
Locator.GetPlayerBody().SetRotation(_controller._playerPostCollapseSocket.rotation);
Locator.GetPlayerBody().SetVelocity(-_controller._playerPostCollapseSocket.forward);
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().LockOn(_controller._possibilitySphereRoot, 2f);
foreach (var particles in _controller._smokeSphereParticles)
{
particles.Stop();
}
}
}
}

View File

@ -0,0 +1,9 @@
using QSB.Patches;
namespace QSB.EyeOfTheUniverse.CosmicInflation.Patches
{
internal class InflationPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
}
}

View File

@ -17,7 +17,6 @@ namespace QSB.EyeOfTheUniverse.EyeStateSync.Messages
}
}
private EyeStateMessage(EyeState state) => Value = state;
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;

View File

@ -0,0 +1,85 @@
using QSB.Messaging;
using QSB.Player.TransformSync;
using QSB.Utility;
using QSB.WorldSync;
using QuantumUNET.Transport;
using System;
using UnityEngine;
namespace QSB.EyeOfTheUniverse.EyeStateSync.Messages
{
internal class FlickerMessage : QSBMessage
{
static FlickerMessage() => GlobalMessenger<float, float>.AddListener(OWEvents.FlickerOffAndOn, Handler);
private static void Handler(float offDuration, float onDuration)
{
if (PlayerTransformSync.LocalInstance)
{
new FlickerMessage(offDuration, onDuration).Send();
}
}
private float _offDuration;
private float _onDuration;
private FlickerMessage(float offDuration, float onDuration)
{
_offDuration = offDuration;
_onDuration = onDuration;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(_offDuration);
writer.Write(_onDuration);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
_offDuration = reader.ReadSingle();
_onDuration = reader.ReadSingle();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
// manually fire callbacks
var eventTable = GlobalMessenger<float, float>.eventTable;
lock (eventTable)
{
var eventData = eventTable[OWEvents.FlickerOffAndOn];
if (eventData.isInvoking)
{
throw new InvalidOperationException("GlobalMessenger does not support recursive FireEvent calls to the same eventType.");
}
eventData.isInvoking = true;
eventData.temp.AddRange(eventData.callbacks);
foreach (var callback in eventData.temp)
{
// ignore callback for this message to prevent infinite loop
if (callback == Handler)
{
continue;
}
try
{
callback(_offDuration, _onDuration);
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
eventData.temp.Clear();
eventData.isInvoking = false;
}
}
}
}

View File

@ -0,0 +1,22 @@
using QSB.Messaging;
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
using UnityEngine;
namespace QSB.EyeOfTheUniverse.ForestOfGalaxies.Messages
{
internal class EyeCloneSeenMessage : QSBMessage
{
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
var controller = QSBWorldSync.GetUnityObjects<PlayerCloneController>().First();
controller._warpFlickerActivated = true;
controller._warpTime = Time.time + 0.5f;
}
}
}

View File

@ -9,12 +9,10 @@ namespace QSB.EyeOfTheUniverse.ForestOfGalaxies.Messages
{
internal class KillGalaxiesMessage : QSBMessage
{
private List<float> _deathDelays = new();
private List<float> _deathDelays;
public KillGalaxiesMessage(List<float> deathDelays) => _deathDelays = deathDelays;
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
@ -29,20 +27,22 @@ namespace QSB.EyeOfTheUniverse.ForestOfGalaxies.Messages
{
base.Deserialize(reader);
var length = reader.ReadInt32();
_deathDelays = new List<float>();
_deathDelays = new List<float>(length);
for (var i = 0; i < length; i++)
{
_deathDelays.Add(reader.ReadSingle());
}
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
var galaxyController = QSBWorldSync.GetUnityObjects<MiniGalaxyController>().First();
galaxyController._killTrigger.OnEntry -= galaxyController.OnEnterKillTrigger;
galaxyController._galaxies = galaxyController.GetComponentsInChildren<MiniGalaxy>(true);
galaxyController._galaxies = galaxyController.GetComponentsInChildren<MiniGalaxy>(true);
for (var i = 0; i < galaxyController._galaxies.Length; i++)
{
galaxyController._galaxies[i].DieAfterSeconds(_deathDelays[i], true, AudioType.EyeGalaxyBlowAway);
@ -52,7 +52,7 @@ namespace QSB.EyeOfTheUniverse.ForestOfGalaxies.Messages
galaxyController.enabled = true;
galaxyController._musicSource.SetLocalVolume(0f);
galaxyController._musicSource.FadeIn(5f, false, false, 1f);
galaxyController._musicSource.FadeIn(5f);
}
}
}

View File

@ -69,21 +69,52 @@ namespace QSB.EyeOfTheUniverse.ForestOfGalaxies.Patches
[HarmonyPatch(typeof(MiniGalaxyController), nameof(MiniGalaxyController.KillGalaxies))]
public static bool KillGalaxiesReplacement(MiniGalaxyController __instance)
{
var num = 60f;
const float delay = 60f;
__instance._galaxies = __instance.GetComponentsInChildren<MiniGalaxy>(true);
var delayList = new List<float>();
for (var i = 0; i < __instance._galaxies.Length; i++)
foreach (var galaxy in __instance._galaxies)
{
var rnd = Random.Range(30f, num);
var rnd = Random.Range(30f, delay);
delayList.Add(rnd);
__instance._galaxies[i].DieAfterSeconds(rnd, true, AudioType.EyeGalaxyBlowAway);
galaxy.DieAfterSeconds(rnd, true, AudioType.EyeGalaxyBlowAway);
}
new KillGalaxiesMessage(delayList).Send();
__instance._forestIsDarkTime = Time.time + num + 5f;
new KillGalaxiesMessage(delayList).Send();
__instance._forestIsDarkTime = Time.time + delay + 5f;
__instance.enabled = true;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerCloneController), nameof(PlayerCloneController.FixedUpdate))]
public static bool CloneFixedUpdate(PlayerCloneController __instance)
{
var playerTransform = Locator.GetPlayerTransform();
var vector = __instance.transform.parent.InverseTransformPoint(playerTransform.position);
var b = __instance._localMirrorPos - vector;
var position = __instance._localMirrorPos + b;
position.y = vector.y;
__instance.transform.position = __instance.transform.parent.TransformPoint(position);
var normalized = (__instance.transform.position - playerTransform.position).normalized;
var forward = Vector3.Reflect(playerTransform.forward, normalized);
var upwards = Vector3.Reflect(playerTransform.up, normalized);
__instance.transform.rotation = Quaternion.LookRotation(forward, upwards);
var num = Vector3.Distance(__instance.transform.position, playerTransform.position);
if (!__instance._warpFlickerActivated && num < 10f)
{
__instance._warpFlickerActivated = true;
__instance._warpTime = Time.time + 0.5f;
GlobalMessenger<float, float>.FireEvent(OWEvents.FlickerOffAndOn, 0.5f, 0.5f);
new EyeCloneSeenMessage().Send();
}
if (__instance._warpPlayerNextFrame)
{
__instance.WarpPlayerToCampfire();
}
return false;
}
}
}

View File

@ -22,7 +22,6 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
private DialogueBoxVer2 _currentDialogueBox;
private bool _wasFlashlightOn;
private bool _timeFrozen;
private bool _isRecording;
private const string SIGN_NAME = "SIGN";
private const string RECORDING_NAME = "RECORDING";
@ -356,7 +355,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
Locator.GetToolModeSwapper().UnequipTool();
GlobalMessenger.FireEvent("EnterConversation");
Locator.GetPlayerAudioController().PlayDialogueEnter(_isRecording);
Locator.GetPlayerAudioController().PlayDialogueEnter();
_wasFlashlightOn = Locator.GetFlashlight().IsFlashlightOn();
if (_wasFlashlightOn && _turnOffFlashlight)
{
@ -394,7 +393,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
_interactVolume.ResetInteraction();
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().BreakLock();
GlobalMessenger.FireEvent("ExitConversation");
Locator.GetPlayerAudioController().PlayDialogueExit(_isRecording);
Locator.GetPlayerAudioController().PlayDialogueExit();
if (_wasFlashlightOn && _turnOffFlashlight && _turnOnFlashlight)
{
Locator.GetFlashlight().TurnOn(false);

View File

@ -3,6 +3,7 @@ using QSB.Player;
using QSB.Player.Messages;
using QSB.WorldSync;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace QSB.EyeOfTheUniverse.VesselSync
@ -24,13 +25,15 @@ namespace QSB.EyeOfTheUniverse.VesselSync
protected override void RebuildWorldObjects(OWScene scene)
{
_playersInCage.Clear();
if (_warpController != null)
{
_warpController._cageTrigger.OnEntry -= OnEntry;
_warpController._cageTrigger.OnExit -= OnExit;
}
_warpController = FindObjectOfType<VesselWarpController>();
_warpController = QSBWorldSync.GetUnityObjects<VesselWarpController>().First();
_warpController._cageTrigger.OnExit -= _warpController.OnExitCageTrigger;
_warpController._cageTrigger.OnEntry += OnEntry;
@ -53,7 +56,6 @@ namespace QSB.EyeOfTheUniverse.VesselSync
}
}
public void Enter(PlayerInfo player)
{
_playersInCage.Add(player);

View File

@ -36,9 +36,8 @@ namespace QSB.Instruments
QSBCore.UnityEvents.RunWhen(() => Locator.GetPlayerBody() != null, SetupInstruments);
}
protected override void OnDestroy()
protected void OnDestroy()
{
base.OnDestroy();
if (!IsLocalPlayer)
{
return;

View File

@ -19,6 +19,7 @@ namespace QSB.JellyfishSync.Patches
{
return true;
}
var qsbJellyfish = __instance.GetWorldObject<QSBJellyfish>();
var sqrMagnitude = (__instance._jellyfishBody.GetPosition() - __instance._planetBody.GetPosition()).sqrMagnitude;

View File

@ -36,6 +36,7 @@ namespace QSB.JellyfishSync.TransformSync
{
NetIdentity.UnregisterAuthQueue();
}
AttachedObject.OnUnsuspendOWRigidbody -= OnUnsuspend;
AttachedObject.OnSuspendOWRigidbody -= OnSuspend;
}
@ -54,6 +55,7 @@ namespace QSB.JellyfishSync.TransformSync
{
NetIdentity.RegisterAuthQueue();
}
AttachedObject.OnUnsuspendOWRigidbody += OnUnsuspend;
AttachedObject.OnSuspendOWRigidbody += OnSuspend;
NetIdentity.SendAuthQueueMessage(AttachedObject.IsSuspended() ? AuthQueueAction.Remove : AuthQueueAction.Add);
@ -138,7 +140,6 @@ namespace QSB.JellyfishSync.TransformSync
return true;
}
protected override void OnRenderObject()
{
if (!QSBCore.ShowLinesInDebug

View File

@ -32,7 +32,6 @@ namespace QSB.JellyfishSync.WorldObjects
}
}
public bool IsRising
{
get => AttachedObject._isRising;

View File

@ -49,6 +49,15 @@ namespace QSB.Menus
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isUniverse)
{
if (newScene == OWScene.EyeOfTheUniverse)
{
GlobalMessenger<EyeState>.AddListener(OWEvents.EyeStateChanged, OnEyeStateChanged);
}
else
{
GlobalMessenger<EyeState>.RemoveListener(OWEvents.EyeStateChanged, OnEyeStateChanged);
}
if (isUniverse)
{
InitPauseMenus();
@ -68,6 +77,7 @@ namespace QSB.Menus
_nowLoadingSB = new StringBuilder();
return;
}
_nowLoadingSB.Length = 0;
}
@ -199,6 +209,14 @@ namespace QSB.Menus
DisconnectPopup._labelText.text = popupText;
}
private void OnEyeStateChanged(EyeState state)
{
if (state >= EyeState.IntoTheVortex)
{
SetButtonActive(HostButton, false);
}
}
private void MakeTitleMenus()
{
CreateCommonPopups();
@ -294,7 +312,13 @@ namespace QSB.Menus
private void Connect()
{
QSBNetworkManager.Instance.networkAddress = string.Concat((IPPopup as PopupInputMenu).GetInputText().Where(c => !char.IsWhiteSpace(c)));
var address = string.Concat(((PopupInputMenu)IPPopup).GetInputText().Where(c => !char.IsWhiteSpace(c)));
if (address.Length == 0)
{
address = QSBCore.DefaultServerIP;
}
QSBNetworkManager.Instance.networkAddress = address;
QSBNetworkManager.Instance.StartClient();
if (QSBSceneManager.CurrentScene == OWScene.TitleScreen)

View File

@ -29,5 +29,6 @@
public const string EnterShip = nameof(EnterShip);
public const string ExitShip = nameof(ExitShip);
public const string EyeStateChanged = nameof(EyeStateChanged);
public const string FlickerOffAndOn = nameof(FlickerOffAndOn);
}
}

View File

@ -47,7 +47,6 @@ namespace QSB.Messaging
public override string ToString() => GetType().Name;
}
public abstract class QSBBoolMessage : QSBMessage
{
protected bool Value;

View File

@ -104,6 +104,7 @@ namespace QSB.Messaging
DebugLog.ToConsole($"SendTo unknown player! id: {msg.To}, message: {msg}", MessageType.Error);
return;
}
conn.Send(msgType, msg);
}
}
@ -158,7 +159,6 @@ namespace QSB.Messaging
#endregion
public static void SendRaw<M>(this M msg)
where M : QSBMessageRaw
{

View File

@ -42,7 +42,6 @@ namespace QSB.Messaging
}
}
public abstract class QSBBoolWorldObjectMessage<T> : QSBWorldObjectMessage<T> where T : IWorldObject
{
protected bool Value;

View File

@ -168,7 +168,6 @@ namespace QSB.MeteorSync.Patches
}
}
/// <summary>
/// client only
/// </summary>
@ -271,7 +270,6 @@ namespace QSB.MeteorSync.Patches
}
}
/// <summary>
/// both server and client
/// </summary>
@ -320,6 +318,7 @@ namespace QSB.MeteorSync.Patches
{
return true;
}
if (!WorldObjectManager.AllObjectsReady)
{
return true;

View File

@ -21,10 +21,12 @@ namespace QSB.OrbSync.Patches
{
return;
}
if (!__instance._isBeingDragged)
{
return;
}
var qsbOrb = __instance.GetWorldObject<QSBOrb>();
qsbOrb.SendMessage(new OrbDragMessage(true));
}
@ -37,15 +39,18 @@ namespace QSB.OrbSync.Patches
{
return true;
}
if (!__instance._isBeingDragged)
{
return false;
}
var qsbOrb = __instance.GetWorldObject<QSBOrb>();
if (!qsbOrb.TransformSync.HasAuthority)
{
return false;
}
qsbOrb.SendMessage(new OrbDragMessage(false));
return true;
}
@ -58,6 +63,7 @@ namespace QSB.OrbSync.Patches
{
return true;
}
var qsbOrb = __instance.GetWorldObject<QSBOrb>();
if (!qsbOrb.TransformSync.HasAuthority)
{
@ -77,10 +83,12 @@ namespace QSB.OrbSync.Patches
{
__instance.CancelDrag();
}
if (__instance._orbAudio != null && slot.GetPlayActivationAudio())
{
__instance._orbAudio.PlaySlotActivatedClip();
}
qsbOrb.SendMessage(new OrbSlotMessage(slotIndex));
break;
}
@ -91,6 +99,7 @@ namespace QSB.OrbSync.Patches
__instance._occupiedSlot = null;
qsbOrb.SendMessage(new OrbSlotMessage(-1));
}
__instance._owCollider.SetActivation(__instance._occupiedSlot == null || !__instance._occupiedSlot.IsAttractive() || __instance._isBeingDragged);
return false;

View File

@ -38,6 +38,7 @@ namespace QSB.OrbSync.TransformSync
{
NetIdentity.UnregisterAuthQueue();
}
_attachedBody.OnUnsuspendOWRigidbody -= OnUnsuspend;
_attachedBody.OnSuspendOWRigidbody -= OnSuspend;
}
@ -50,6 +51,7 @@ namespace QSB.OrbSync.TransformSync
DebugLog.ToConsole($"Error - No orb at index {index}.", MessageType.Error);
return;
}
_qsbOrb = orb.GetWorldObject<QSBOrb>();
_qsbOrb.TransformSync = this;
@ -68,6 +70,7 @@ namespace QSB.OrbSync.TransformSync
{
NetIdentity.RegisterAuthQueue();
}
_attachedBody.OnUnsuspendOWRigidbody += OnUnsuspend;
_attachedBody.OnSuspendOWRigidbody += OnSuspend;
NetIdentity.SendAuthQueueMessage(_attachedBody.IsSuspended() ? AuthQueueAction.Remove : AuthQueueAction.Add);

View File

@ -83,6 +83,7 @@ namespace QSB.OrbSync.WorldObjects
{
AttachedObject.CancelDrag();
}
if (AttachedObject._orbAudio != null && newSlot.GetPlayActivationAudio())
{
AttachedObject._orbAudio.PlaySlotActivatedClip();

View File

@ -65,6 +65,7 @@ namespace QSB.Patches
DebugLog.ToConsole($"Error while patching {patch.GetType().Name} :\r\n{ex}", MessageType.Error);
}
}
_patchedTypes.Add(type);
}

View File

@ -15,6 +15,7 @@
EnterNomaiHeadZone = 10,
ExitNomaiHeadZone = 11,
EnterVesselCage = 12,
ExitVesselCage = 13
ExitVesselCage = 13,
EnterCosmicFog = 14,
}
}

View File

@ -1,5 +1,6 @@
using OWML.Common;
using QSB.Animation.NPC.WorldObjects;
using QSB.EyeOfTheUniverse.CosmicInflation;
using QSB.EyeOfTheUniverse.VesselSync;
using QSB.Messaging;
using QSB.Player.TransformSync;
@ -29,7 +30,6 @@ namespace QSB.Player.Messages
}
}
private int ObjectId;
public EnterLeaveMessage(EnterLeaveType type, int objectId = -1)
@ -103,6 +103,9 @@ namespace QSB.Player.Messages
case EnterLeaveType.ExitVesselCage:
VesselManager.Instance.Exit(player);
break;
case EnterLeaveType.EnterCosmicFog:
InflationManager.Instance.Enter(player);
break;
default:
DebugLog.ToConsole($"Warning - Unknown EnterLeaveType : {Value}", MessageType.Warning);
break;

View File

@ -64,18 +64,18 @@ namespace QSB.Player.Messages
if (Platform != QSBCore.Platform)
{
DebugLog.ToConsole($"Error - Client {PlayerName} connecting with wrong game platform. (Client:{Platform}, Server:{QSBCore.Platform})", MessageType.Error);
new PlayerKickMessage(From, KickReason.DLCNotMatching).Send();
new PlayerKickMessage(From, KickReason.GamePlatformNotMatching).Send();
return;
}
if (DlcInstalled != QSBCore.DLCInstalled)
{
DebugLog.ToConsole($"Error - Client {PlayerName} connecting with wrong DLC installation state. (Client:{DlcInstalled}, Server:{QSBCore.DLCInstalled})", MessageType.Error);
new PlayerKickMessage(From, KickReason.GamePlatformNotMatching).Send();
new PlayerKickMessage(From, KickReason.DLCNotMatching).Send();
return;
}
if (QSBPlayerManager.PlayerList.Any(x => x.EyeState > EyeState.WarpedToSurface))
if (QSBPlayerManager.PlayerList.Any(x => x.EyeState >= EyeState.IntoTheVortex))
{
DebugLog.ToConsole($"Error - Client {PlayerName} connecting too late into eye scene.", MessageType.Error);
new PlayerKickMessage(From, KickReason.InEye).Send();

View File

@ -4,6 +4,7 @@ using QSB.Animation.Player.Thrusters;
using QSB.Audio;
using QSB.CampfireSync.WorldObjects;
using QSB.ClientServerStateSync;
using QSB.Instruments;
using QSB.ItemSync.WorldObjects.Items;
using QSB.Messaging;
using QSB.Player.Messages;
@ -22,19 +23,25 @@ namespace QSB.Player
{
public class PlayerInfo
{
/// <summary>
/// the player transform sync's net id
/// </summary>
public uint PlayerId { get; }
public string Name { get; set; }
public PlayerHUDMarker HudMarker { get; set; }
public PlayerTransformSync TransformSync { get; set; }
public PlayerTransformSync TransformSync { get; }
public AnimationSync AnimationSync { get; }
public InstrumentsManager InstrumentsManager { get; }
public ClientState State { get; set; }
public EyeState EyeState { get; set; }
public bool IsDead { get; set; }
public bool Visible { get; set; } = true;
public bool Visible => DitheringAnimator != null && DitheringAnimator._visible;
public bool IsReady { get; set; }
public bool IsInMoon { get; set; }
public bool IsInShrine { get; set; }
public IQSBQuantumObject EntangledObject { get; set; }
public QSBPlayerAudioController AudioController { get; set; }
public DitheringAnimator DitheringAnimator { get; set; }
// Body Objects
public OWCamera Camera
@ -114,11 +121,10 @@ namespace QSB.Player
public bool ProbeActive { get; set; }
// Conversation
public int CurrentCharacterDialogueTreeId { get; set; }
public int CurrentCharacterDialogueTreeId { get; set; } = -1;
public GameObject CurrentDialogueBox { get; set; }
// Animation
public AnimationSync AnimationSync => QSBPlayerManager.GetSyncObject<AnimationSync>(PlayerId);
public bool PlayingInstrument => AnimationSync.CurrentType
is not AnimationType.PlayerSuited
and not AnimationType.PlayerUnsuited;
@ -181,10 +187,12 @@ namespace QSB.Player
}
}
public PlayerInfo(uint id)
public PlayerInfo(PlayerTransformSync transformSync)
{
PlayerId = id;
CurrentCharacterDialogueTreeId = -1;
PlayerId = transformSync.NetId.Value;
TransformSync = transformSync;
AnimationSync = transformSync.GetComponent<AnimationSync>();
InstrumentsManager = transformSync.GetComponent<InstrumentsManager>();
}
public void UpdateObjectsFromStates()
@ -204,8 +212,7 @@ namespace QSB.Player
Translator?.ChangeEquipState(TranslatorEquipped);
ProbeLauncher?.ChangeEquipState(ProbeLauncherEquipped);
Signalscope?.ChangeEquipState(SignalscopeEquipped);
QSBCore.UnityEvents.RunWhen(() => QSBPlayerManager.GetSyncObject<AnimationSync>(PlayerId) != null,
() => QSBPlayerManager.GetSyncObject<AnimationSync>(PlayerId).SetSuitState(SuitedUp));
AnimationSync.SetSuitState(SuitedUp);
}
public void UpdateStatesFromObjects()

View File

@ -4,11 +4,7 @@ namespace QSB.Player
{
public abstract class PlayerSyncObject : QNetworkBehaviour
{
public uint AttachedNetId => NetIdentity?.NetId.Value ?? uint.MaxValue;
public uint PlayerId => NetIdentity.RootIdentity?.NetId.Value ?? NetIdentity.NetId.Value;
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
protected virtual void Start() => QSBPlayerManager.AddSyncObject(this);
protected virtual void OnDestroy() => QSBPlayerManager.RemoveSyncObject(this);
protected uint PlayerId => NetId.Value;
protected PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
}
}

View File

@ -12,39 +12,37 @@ namespace QSB.Player
{
public static class QSBPlayerManager
{
public static uint LocalPlayerId
public static PlayerInfo LocalPlayer
{
get
{
var localInstance = PlayerTransformSync.LocalInstance;
if (localInstance == null)
{
DebugLog.ToConsole($"Error - Trying to get LocalPlayerId when the local PlayerTransformSync instance is null." +
DebugLog.ToConsole("Error - Trying to get LocalPlayer when the local PlayerTransformSync instance is null." +
$"{Environment.NewLine} Stacktrace : {Environment.StackTrace} ", MessageType.Error);
return uint.MaxValue;
return null;
}
if (localInstance.NetIdentity == null)
{
DebugLog.ToConsole($"Error - Trying to get LocalPlayerId when the local PlayerTransformSync instance's QNetworkIdentity is null.", MessageType.Error);
return uint.MaxValue;
}
return localInstance.NetIdentity.NetId.Value;
return localInstance.Player;
}
}
public static uint LocalPlayerId => LocalPlayer.PlayerId;
public static Action<uint> OnRemovePlayer;
/// <summary>
/// called right after player is added
/// </summary>
public static Action<uint> OnAddPlayer;
/// <summary>
/// called right before player is removed
/// </summary>
public static Action<uint> OnRemovePlayer;
public static PlayerInfo LocalPlayer => GetPlayer(LocalPlayerId);
public static List<PlayerInfo> PlayerList { get; } = new List<PlayerInfo>();
private static readonly List<PlayerSyncObject> PlayerSyncObjects = new();
public static readonly List<PlayerInfo> PlayerList = new();
public static PlayerInfo GetPlayer(uint id)
{
if (id is uint.MaxValue or 0U)
if (id is uint.MaxValue or 0)
{
return default;
}
@ -59,39 +57,15 @@ namespace QSB.Player
return player;
}
public static void AddPlayer(uint id)
{
DebugLog.DebugWrite($"Create Player : id<{id}>", MessageType.Info);
var player = new PlayerInfo(id);
PlayerList.Add(player);
OnAddPlayer?.Invoke(id);
}
public static void RemovePlayer(uint id)
{
DebugLog.DebugWrite($"Remove Player : id<{id}>", MessageType.Info);
PlayerList.RemoveAll(x => x.PlayerId == id);
}
public static bool PlayerExists(uint id) =>
id != uint.MaxValue && PlayerList.Any(x => x.PlayerId == id);
public static IEnumerable<T> GetSyncObjects<T>() where T : PlayerSyncObject =>
PlayerSyncObjects.OfType<T>().Where(x => x != null);
public static T GetSyncObject<T>(uint id) where T : PlayerSyncObject =>
GetSyncObjects<T>().FirstOrDefault(x => x != null && x.AttachedNetId == id);
public static void AddSyncObject(PlayerSyncObject obj) => PlayerSyncObjects.Add(obj);
public static void RemoveSyncObject(PlayerSyncObject obj) => PlayerSyncObjects.Remove(obj);
id is not (uint.MaxValue or 0) && PlayerList.Any(x => x.PlayerId == id);
public static List<PlayerInfo> GetPlayersWithCameras(bool includeLocalCamera = true)
{
var cameraList = PlayerList.Where(x => x.Camera != null && x.PlayerId != LocalPlayerId).ToList();
if (includeLocalCamera
&& LocalPlayer != default
&& LocalPlayer.Camera != null)
&& LocalPlayer != default
&& LocalPlayer.Camera != null)
{
cameraList.Add(LocalPlayer);
}
@ -114,27 +88,10 @@ namespace QSB.Player
=> new(Locator.GetFlashlight(), PlayerList.Where(x => x.FlashLight != null).Select(x => x.FlashLight));
public static void ShowAllPlayers()
=> PlayerList.Where(x => x != LocalPlayer).ToList().ForEach(x => ChangePlayerVisibility(x.PlayerId, true));
=> PlayerList.Where(x => x != LocalPlayer && x.DitheringAnimator != null).ForEach(x => x.DitheringAnimator.SetVisible(true, 0.5f));
public static void HideAllPlayers()
=> PlayerList.Where(x => x != LocalPlayer).ToList().ForEach(x => ChangePlayerVisibility(x.PlayerId, false));
public static void ChangePlayerVisibility(uint playerId, bool visible)
{
var player = GetPlayer(playerId);
player.Visible = visible;
if (player.Body == null)
{
DebugLog.ToConsole($"Warning - Player {playerId} has a null player model!", MessageType.Warning);
return;
}
foreach (var renderer in player.Body.GetComponentsInChildren<Renderer>())
{
renderer.enabled = visible;
}
}
=> PlayerList.Where(x => x != LocalPlayer && x.DitheringAnimator != null).ForEach(x => x.DitheringAnimator.SetVisible(false, 0.5f));
public static PlayerInfo GetClosestPlayerToWorldPoint(Vector3 worldPoint, bool includeLocalPlayer) => includeLocalPlayer
? GetClosestPlayerToWorldPoint(PlayerList, worldPoint)

View File

@ -1,6 +1,5 @@
using QSB.Animation.Player;
using OWML.Common;
using QSB.Audio;
using QSB.Instruments;
using QSB.Messaging;
using QSB.Player.Messages;
using QSB.RoastingSync;
@ -48,9 +47,11 @@ namespace QSB.Player.TransformSync
public override void Start()
{
var player = new PlayerInfo(this);
QSBPlayerManager.PlayerList.SafeAdd(player);
base.Start();
QSBPlayerManager.AddPlayer(PlayerId);
Player.TransformSync = this;
QSBPlayerManager.OnAddPlayer?.Invoke(Player.PlayerId);
DebugLog.DebugWrite($"Create Player : id<{Player.PlayerId}>", MessageType.Info);
}
protected override void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse)
@ -86,13 +87,11 @@ namespace QSB.Player.TransformSync
protected override void OnDestroy()
{
// TODO : Maybe move this to a leave event...? Would ensure everything could finish up before removing the player
QSBPlayerManager.OnRemovePlayer?.Invoke(PlayerId);
QSBPlayerManager.OnRemovePlayer?.Invoke(Player.PlayerId);
base.OnDestroy();
if (QSBPlayerManager.PlayerExists(PlayerId))
{
Player.HudMarker?.Remove();
QSBPlayerManager.RemovePlayer(PlayerId);
}
Player.HudMarker?.Remove();
QSBPlayerManager.PlayerList.Remove(Player);
DebugLog.DebugWrite($"Remove Player : id<{Player.PlayerId}>", MessageType.Info);
}
protected override Transform InitLocalTransform()
@ -102,8 +101,8 @@ namespace QSB.Player.TransformSync
// player body
var player = Locator.GetPlayerTransform();
var playerModel = player.Find("Traveller_HEA_Player_v2");
GetComponent<AnimationSync>().InitLocal(playerModel);
GetComponent<InstrumentsManager>().InitLocal(player);
Player.AnimationSync.InitLocal(playerModel);
Player.InstrumentsManager.InitLocal(player);
Player.Body = player.gameObject;
// camera
@ -164,14 +163,12 @@ namespace QSB.Player.TransformSync
Player.Body = REMOTE_Player_Body;
GetComponent<AnimationSync>().InitRemote(REMOTE_Traveller_HEA_Player_v2);
GetComponent<InstrumentsManager>().InitRemote(REMOTE_Player_Body.transform);
var marker = REMOTE_Player_Body.AddComponent<PlayerHUDMarker>();
marker.Init(Player);
Player.AnimationSync.InitRemote(REMOTE_Traveller_HEA_Player_v2);
Player.InstrumentsManager.InitRemote(REMOTE_Player_Body.transform);
REMOTE_Player_Body.AddComponent<PlayerHUDMarker>().Init(Player);
REMOTE_Player_Body.AddComponent<PlayerMapMarker>().PlayerName = Player.Name;
Player.DitheringAnimator = REMOTE_Player_Body.AddComponent<DitheringAnimator>();
Player.AudioController = PlayerAudioManager.InitRemote(REMOTE_Player_Body.transform);
/*

View File

@ -33,7 +33,6 @@ namespace QSB.QuantumSync.Messages
public override void OnReceiveRemote()
{
DebugLog.DebugWrite($"Get moon state active:{Active} angle:{Angle}");
WorldObject.AttachedObject._moonStateRoot.SetActive(Active);
if (Angle != -1f)
{

View File

@ -60,7 +60,7 @@ namespace QSB.QuantumSync.WorldObjects
{
if (shape is BoxShape boxShape)
{
var newCube = UnityEngine.Object.Instantiate(cube);
var newCube = Object.Instantiate(cube);
newCube.transform.parent = shape.transform;
newCube.transform.localPosition = Vector3.zero;
newCube.transform.localRotation = Quaternion.Euler(0, 0, 0);
@ -68,7 +68,7 @@ namespace QSB.QuantumSync.WorldObjects
}
else if (shape is SphereShape sphereShape)
{
var newSphere = UnityEngine.Object.Instantiate(sphere);
var newSphere = Object.Instantiate(sphere);
newSphere.transform.parent = shape.transform;
newSphere.transform.localPosition = Vector3.zero;
newSphere.transform.localRotation = Quaternion.Euler(0, 0, 0);
@ -180,33 +180,34 @@ namespace QSB.QuantumSync.WorldObjects
((IQSBQuantumObject)this).SendMessage(new QuantumAuthorityMessage(QSBPlayerManager.LocalPlayerId));
}
private void OnDisable(Shape s)
{
if (!IsEnabled)
private void OnDisable(Shape s) =>
// we wait a frame here in case the shapes get disabled as we switch from 1 visibility tracker to another
QSBCore.UnityEvents.FireOnNextUpdate(() =>
{
return;
}
if (!IsEnabled)
{
return;
}
if (GetAttachedShapes().Any(x => x.isActiveAndEnabled))
{
return;
}
if (GetAttachedShapes().Any(x => x.isActiveAndEnabled))
{
return;
}
IsEnabled = false;
if (!WorldObjectManager.AllObjectsReady && !QSBCore.IsHost)
{
return;
}
IsEnabled = false;
if (!WorldObjectManager.AllObjectsReady && !QSBCore.IsHost)
{
return;
}
if (ControllingPlayer != QSBPlayerManager.LocalPlayerId)
{
// not being controlled by us, don't care if we leave area
return;
}
if (ControllingPlayer != QSBPlayerManager.LocalPlayerId)
{
// not being controlled by us, don't care if we leave area
return;
}
var id = ObjectId;
// send event to other players that we're releasing authority
((IQSBQuantumObject)this).SendMessage(new QuantumAuthorityMessage(0u));
}
// send event to other players that we're releasing authority
((IQSBQuantumObject)this).SendMessage(new QuantumAuthorityMessage(0u));
});
}
}

View File

@ -153,7 +153,14 @@ namespace QSB.RespawnSync
return;
}
QSBPlayerManager.ChangePlayerVisibility(player.PlayerId, false);
if (player.DitheringAnimator != null)
{
player.DitheringAnimator.SetVisible(false, 1);
}
else
{
DebugLog.ToConsole($"Warning - {player.PlayerId}.DitheringAnimator is null!", OWML.Common.MessageType.Warning);
}
}
public void OnPlayerRespawn(PlayerInfo player)
@ -169,7 +176,14 @@ namespace QSB.RespawnSync
_playersPendingRespawn.Remove(player);
UpdateRespawnNotification();
QSBPlayerManager.ChangePlayerVisibility(player.PlayerId, true);
if (player.DitheringAnimator != null)
{
player.DitheringAnimator.SetVisible(true, 1);
}
else
{
DebugLog.ToConsole($"Warning - {player.PlayerId}.DitheringAnimator is null!", OWML.Common.MessageType.Warning);
}
}
public void RespawnSomePlayer()

View File

@ -35,7 +35,6 @@ namespace QSB.StatueSync.Messages
CameraDegrees = reader.ReadSingle();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveLocal()

View File

@ -127,12 +127,7 @@ namespace QSB.Syncs.Sectored
{
if (IsPlayerObject)
{
if (!QSBPlayerManager.PlayerExists(PlayerId))
{
writer.Write(-1);
return;
}
else if (!Player.IsReady)
if (!Player.IsReady)
{
writer.Write(-1);
return;

View File

@ -1,6 +1,5 @@
using OWML.Common;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.Utility;
using QSB.WorldSync;
using QuantumUNET.Components;
@ -17,48 +16,16 @@ namespace QSB.Syncs
public abstract class SyncBase<T> : QNetworkTransform where T : Component
{
public uint AttachedNetId
{
get
{
if (NetIdentity == null)
{
DebugLog.ToConsole($"Error - Trying to get AttachedNetId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
return uint.MaxValue;
}
return NetIdentity.NetId.Value;
}
}
public uint PlayerId
{
get
{
if (!IsPlayerObject)
{
return uint.MaxValue;
}
if (NetIdentity == null)
{
DebugLog.ToConsole($"Error - Trying to get PlayerId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
return uint.MaxValue;
}
return NetIdentity.RootIdentity != null
? NetIdentity.RootIdentity.NetId.Value
: AttachedNetId;
}
}
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
/// <summary>
/// valid if IsPlayerObject, otherwise null
/// </summary>
public PlayerInfo Player { get; private set; }
private bool _baseIsReady
{
get
{
if (NetId.Value is uint.MaxValue or 0U)
if (NetId.Value is uint.MaxValue or 0)
{
return false;
}
@ -70,16 +37,6 @@ namespace QSB.Syncs
if (IsPlayerObject)
{
if (!QSBPlayerManager.PlayerExists(PlayerId))
{
return false;
}
if (Player == null)
{
return false;
}
if (!Player.IsReady && !IsLocalPlayer)
{
return false;
@ -100,7 +57,7 @@ namespace QSB.Syncs
public T AttachedObject { get; set; }
public Transform ReferenceTransform { get; set; }
public string LogName => $"{PlayerId}.{NetId.Value}:{GetType().Name}";
public string LogName => $"{(IsPlayerObject ? Player.PlayerId : "<non player object>")}.{NetId.Value}:{GetType().Name}";
protected virtual float DistanceLeeway { get; } = 5f;
private float _previousDistance;
protected const float SmoothTime = 0.1f;
@ -117,9 +74,11 @@ namespace QSB.Syncs
{
if (IsPlayerObject)
{
var lowestBound = QSBWorldSync.GetUnityObjects<PlayerTransformSync>()
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
// get player objects spawned before this object (or is this one)
// and use the closest one
Player = QSBPlayerManager.PlayerList
.Where(x => x.PlayerId <= NetId.Value)
.OrderBy(x => x.PlayerId).Last();
}
DontDestroyOnLoad(gameObject);

View File

@ -26,23 +26,14 @@ namespace QSB.Tools
{
CreateStowTransforms(player.CameraBody.transform);
Props_HEA_PlayerTool_mat = GameObject.Find("Props_HEA_ProbeLauncher_ProbeCamera/ProbeLauncherChassis").GetComponent<MeshRenderer>().materials[0];
Props_HEA_Lightbulb_OFF_mat = GameObject.Find("Props_HEA_Probe_Prelaunch").GetComponent<MeshRenderer>().materials[1];
var surfaceData = Locator.GetSurfaceManager()._surfaceLookupAsset;
var metal = surfaceData.surfaceTypeGroups[15].materials;
var glass = surfaceData.surfaceTypeGroups[19].materials;
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
{
Structure_HEA_PlayerShip_Screens_mat = GameObject.Find("ProbeScreen (1)/ProbeScreenPivot/ProbeScreen").GetComponent<MeshRenderer>().materials[2];
Props_HEA_Lightbulb_mat = GameObject.Find("Props_HEA_Lantern (10)/Lantern_Lamp").GetComponent<MeshRenderer>().materials[0];
Props_HEA_Lightbulb_OFF_mat = GameObject.Find("NomaiResearchExhibit/Props_HEA_Probe_STATIC").GetComponent<MeshRenderer>().materials[1];
}
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
{
Props_HEA_Lightbulb_mat = GameObject.Find("lantern_lamp").GetComponent<MeshRenderer>().materials[0];
// BUG : uhhhhh fuckin' uhhhhhhhh (find a material)
Props_HEA_Lightbulb_OFF_mat = null;
Structure_HEA_PlayerShip_Screens_mat = null;
}
Props_HEA_PlayerTool_mat = metal[27];
Props_HEA_Lightbulb_mat = glass[47];
Props_HEA_Lightbulb_OFF_mat = glass[48];
Structure_HEA_PlayerShip_Screens_mat = glass[41];
}
catch (Exception ex)
{

View File

@ -7,7 +7,20 @@ namespace QSB.Tools
{
public PlayerInfo Player { get; set; }
public ToolType Type { get; set; }
public GameObject ToolGameObject { get; set; }
public GameObject ToolGameObject
{
get => _toolGameObject;
set
{
_toolGameObject = value;
QSBCore.UnityEvents.FireInNUpdates(
() => DitheringAnimator = _toolGameObject.AddComponent<DitheringAnimator>(),
5);
}
}
private GameObject _toolGameObject;
public DitheringAnimator DitheringAnimator { get; set; }
public DampedSpringQuat MoveSpring
{
@ -33,8 +46,23 @@ namespace QSB.Tools
set => _arrivalDegrees = value;
}
protected bool _isDitheringOut;
public override void Start()
{
base.Start();
ToolGameObject?.SetActive(false);
}
public virtual void OnEnable() => ToolGameObject?.SetActive(true);
public virtual void OnDisable() => ToolGameObject?.SetActive(false);
public virtual void OnDisable()
{
if (!_isDitheringOut)
{
ToolGameObject?.SetActive(false);
}
}
public void ChangeEquipState(bool equipState)
{
@ -50,13 +78,34 @@ namespace QSB.Tools
public override void EquipTool()
{
base.EquipTool();
if (DitheringAnimator != null && DitheringAnimator._renderers != null)
{
ToolGameObject?.SetActive(true);
DitheringAnimator.SetVisible(true, 5f);
}
Player.AudioController.PlayEquipTool();
}
public override void UnequipTool()
{
base.UnequipTool();
if (DitheringAnimator != null && DitheringAnimator._renderers != null)
{
_isDitheringOut = true;
DitheringAnimator.SetVisible(false, 5f);
QSBCore.UnityEvents.RunWhen(() => DitheringAnimator._visibleFraction == 0, FinishDitherOut);
}
Player.AudioController.PlayUnequipTool();
}
public virtual void FinishDitherOut()
{
ToolGameObject?.SetActive(false);
_isDitheringOut = false;
}
}
}

View File

@ -25,7 +25,12 @@ namespace QSB.Tools.TranslatorTool
}
public override void OnDisable()
=> _translatorProp.OnFinishUnequipAnimation();
{
if (!_isDitheringOut)
{
_translatorProp.OnFinishUnequipAnimation();
}
}
public override void EquipTool()
{
@ -39,6 +44,12 @@ namespace QSB.Tools.TranslatorTool
_translatorProp.OnUnequipTool();
}
public override void FinishDitherOut()
{
base.FinishDitherOut();
_translatorProp.OnFinishUnequipAnimation();
}
public override void Update()
{
base.Update();

View File

@ -19,6 +19,7 @@ namespace QSB.Tools.TranslatorTool.TranslationSync.Patches
{
return;
}
if (__instance.IsTranslated(id))
{
return;

View File

@ -37,6 +37,7 @@ namespace QSB.TornadoSync.Patches
{
__instance.UpdateFormation();
}
if (__instance._isSectorOccupied)
{
__instance.UpdateAnimation();
@ -53,7 +54,6 @@ namespace QSB.TornadoSync.Patches
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TornadoController), nameof(TornadoController.OnEnterCollapseTrigger))]
public static bool OnEnterCollapseTrigger(TornadoController __instance,

View File

@ -32,6 +32,7 @@ namespace QSB.TornadoSync
{
SpawnOccasional(proxy.transform.root.GetAttachedOWRigidbody(), gdBody);
}
SpawnOccasional(cannon._probeBody, gdBody);
// islands

View File

@ -116,14 +116,17 @@ namespace QSB.TornadoSync.TransformSync
{
QueueMove(Locator._playerBody);
}
if (_sectors.Contains(ShipTransformSync.LocalInstance?.ReferenceSector?.AttachedObject))
{
QueueMove(Locator._shipBody);
}
if (_sectors.Contains(PlayerProbeSync.LocalInstance?.ReferenceSector?.AttachedObject))
{
QueueMove(Locator._probe._owRigidbody);
}
foreach (var child in _childBodies)
{
QueueMove(child);
@ -140,7 +143,6 @@ namespace QSB.TornadoSync.TransformSync
return true;
}
private readonly List<MoveData> _toMove = new();
private struct MoveData
@ -186,6 +188,7 @@ namespace QSB.TornadoSync.TransformSync
data.Child.SetVelocity(AttachedObject.FromRelVel(data.RelVel, pos));
data.Child.SetAngularVelocity(AttachedObject.FromRelAngVel(data.RelAngVel));
}
_toMove.Clear();
}
}

View File

@ -137,12 +137,6 @@ namespace QSB.Utility
WriteLine(2, $"Player data :");
foreach (var player in QSBPlayerManager.PlayerList)
{
if (player == null)
{
WriteLine(2, $"NULL PLAYER", Color.red);
continue;
}
WriteLine(2, $"{player.PlayerId}.{player.Name}");
WriteLine(2, $"State : {player.State}");
WriteLine(2, $"Eye State : {player.EyeState}");
@ -227,12 +221,6 @@ namespace QSB.Utility
foreach (var player in QSBPlayerManager.PlayerList)
{
if (player == null)
{
WriteLine(4, $"- NULL PLAYER", Color.red);
continue;
}
WriteLine(4, $"- {player.PlayerId}.{player.Name}");
var allQuantumObjects = QSBWorldSync.GetWorldObjects<IQSBQuantumObject>();
var ownedQuantumObjects = allQuantumObjects.Where(x => x.ControllingPlayer == player.PlayerId);

View File

@ -5,24 +5,24 @@ namespace QSB.Utility
public class DebugSettings
{
[JsonProperty("debugMode")]
public bool DebugMode { get; set; } = false;
public bool DebugMode { get; set; }
[JsonProperty("drawLines")]
public bool DrawLines { get; set; } = false;
public bool DrawLines { get; set; }
[JsonProperty("showQuantumVisibilityObjects")]
public bool ShowQuantumVisibilityObjects { get; set; } = false;
public bool ShowQuantumVisibilityObjects { get; set; }
[JsonProperty("showDebugLabels")]
public bool ShowDebugLabels { get; set; } = false;
public bool ShowDebugLabels { get; set; }
[JsonProperty("avoidTimeSync")]
public bool AvoidTimeSync { get; set; } = false;
public bool AvoidTimeSync { get; set; }
[JsonProperty("skipTitleScreen")]
public bool SkipTitleScreen { get; set; } = false;
public bool SkipTitleScreen { get; set; }
[JsonProperty("greySkybox")]
public bool GreySkybox { get; set; } = false;
public bool GreySkybox { get; set; }
}
}

View File

@ -1,6 +1,4 @@
using OWML.Common;
using QSB.Player;
using QSB.Player.TransformSync;
using QuantumUNET;
using System;
using System.Collections.Generic;
@ -41,28 +39,14 @@ namespace QSB.Utility
return uint.MaxValue;
}
var playerController = connection.PlayerControllers[0];
var playerController = connection.PlayerControllers.FirstOrDefault();
if (playerController == null)
{
DebugLog.ToConsole($"Error - Player Controller of {connection.address} is null.", MessageType.Error);
return uint.MaxValue;
}
var go = playerController.Gameobject;
if (go == null)
{
DebugLog.ToConsole($"Error - GameObject of {playerController.UnetView.NetId.Value} is null.", MessageType.Error);
return uint.MaxValue;
}
var controller = go.GetComponent<PlayerTransformSync>();
if (controller == null)
{
DebugLog.ToConsole($"Error - No PlayerTransformSync found on {go.name}", MessageType.Error);
return uint.MaxValue;
}
return controller.NetId.Value;
return playerController.UnetView.NetId.Value;
}
public static void SpawnWithServerAuthority(this GameObject go)

View File

@ -4,5 +4,6 @@
"showQuantumVisibilityObjects": false,
"showDebugLabels": true,
"avoidTimeSync": false,
"skipTitleScreen": true
"skipTitleScreen": true,
"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.\n- Make sure you have forwarded/opened the correct ports. (See the GitHub readme.)"
},
"uniqueName": "Raicuparta.QuantumSpaceBuddies",
"version": "0.14.0",
"version": "0.15.0",
"owmlVersion": "2.2.0",
"dependencies": [ "_nebula.MenuFramework" ]
}

114
QSBTests/MessageTests.cs Normal file
View File

@ -0,0 +1,114 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using QSB.Messaging;
using QSB.Utility;
using System;
using System.Linq;
using System.Reflection;
namespace QSBTests
{
[TestClass]
public class MessageTests
{
[TestMethod]
public void TestMessages()
{
var module = ModuleDefinition.ReadModule("QSB.dll");
var messageTypes = typeof(QSBMessage).GetDerivedTypes();
var fromField = module.ImportReference(typeof(QSBMessage).GetField("From", Util.Flags));
var toField = module.ImportReference(typeof(QSBMessage).GetField("To", Util.Flags));
var objectIdField = module.ImportReference(typeof(QSBWorldObjectMessage<>).GetField("ObjectId", Util.Flags));
foreach (var type in messageTypes)
{
var fields = type.GetFields(Util.Flags)
.Select(x => module.ImportReference(x));
var constructor = module.ImportReference(type.GetConstructors(Util.Flags).Single()).Resolve();
var serialize = module.ImportReference(type.GetMethod("Serialize", Util.Flags)).Resolve();
var deserialize = module.ImportReference(type.GetMethod("Deserialize", Util.Flags)).Resolve();
foreach (var field in fields)
{
if (!field.Eq(fromField) && !field.Eq(toField) && !field.Eq(objectIdField))
{
constructor.CheckUses(field, Util.UseType.Store);
}
serialize.CheckUses(field, Util.UseType.Load);
deserialize.CheckUses(field, Util.UseType.Store);
}
}
}
}
internal static class Util
{
public const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
public static bool Eq(this MemberReference a, MemberReference b) =>
a.DeclaringType.Namespace == b.DeclaringType.Namespace &&
a.DeclaringType.Name == b.DeclaringType.Name &&
a.Name == b.Name;
public static bool IsOp<T>(this Instruction instruction, OpCode opCode, out T operand)
{
if (instruction.OpCode == opCode)
{
operand = (T)instruction.Operand;
return true;
}
operand = default;
return false;
}
public enum UseType { Store, Load };
public static void CheckUses(this MethodDefinition method, FieldReference field, UseType useType)
{
var opCode = useType switch
{
UseType.Store => OpCodes.Stfld,
UseType.Load => OpCodes.Ldfld,
_ => throw new ArgumentOutOfRangeException(nameof(useType), useType, null)
};
while (true)
{
var il = method.Body.Instructions;
var uses = il.Any(x =>
x.IsOp(opCode, out FieldReference f) &&
f.Eq(field)
);
if (uses)
{
return;
}
var baseMethod = method.GetBaseMethod();
if (baseMethod.Eq(method))
{
break;
}
var callsBase = il.Any(x =>
x.IsOp(OpCodes.Call, out MethodReference m) &&
m.Eq(baseMethod)
);
if (!callsBase)
{
break;
}
method = baseMethod;
}
Assert.Fail($"{method} does not {useType} {field}");
}
}
}

View File

@ -21,8 +21,6 @@ namespace QuantumUNET.Components
public short PlayerControllerId { get; private set; } = -1;
public QNetworkConnection ConnectionToServer { get; private set; }
public QNetworkConnection ConnectionToClient { get; private set; }
public QNetworkIdentity RootIdentity { get; private set; }
public List<QNetworkIdentity> SubIdentities { get; private set; } = new List<QNetworkIdentity>();
public bool ServerOnly
{
@ -39,23 +37,6 @@ namespace QuantumUNET.Components
public QNetworkBehaviour[] GetNetworkBehaviours()
=> m_NetworkBehaviours;
public void SetRootIdentity(QNetworkIdentity newRoot)
{
if (RootIdentity != null)
{
RootIdentity.RemoveSubIdentity(this);
}
RootIdentity = newRoot;
RootIdentity.AddSubIndentity(this);
}
internal void AddSubIndentity(QNetworkIdentity identityToAdd)
=> SubIdentities.Add(identityToAdd);
internal void RemoveSubIdentity(QNetworkIdentity identityToRemove)
=> SubIdentities.Remove(identityToRemove);
internal void SetDynamicAssetId(int newAssetId)
{
if (m_AssetId == 0 || m_AssetId.Equals(newAssetId))

View File

@ -66,6 +66,7 @@ namespace QuantumUNET.Transport
{
result = 0;
}
return result;
}
@ -79,8 +80,10 @@ namespace QuantumUNET.Transport
{
str += "0";
}
text = str + text;
}
QNetworkHash128 result;
result.i0 = (byte)(HexToNumber(text[0]) * 16 + HexToNumber(text[1]));
result.i1 = (byte)(HexToNumber(text[2]) * 16 + HexToNumber(text[3]));