Merge pull request #435 from misternebula/message-conversion

Convert events to messages
This commit is contained in:
_nebula 2021-12-28 10:13:46 +00:00 committed by GitHub
commit bbb498ae0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
330 changed files with 4412 additions and 6923 deletions

View File

@ -1,6 +1,6 @@
using System.Collections.Generic;
using QSB.Anglerfish.WorldObjects;
using QSB.Anglerfish.WorldObjects;
using QSB.WorldSync;
using System.Collections.Generic;
namespace QSB.Anglerfish
{

View File

@ -1,67 +0,0 @@
using QSB.Anglerfish.WorldObjects;
using QSB.Events;
using QSB.Player;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.Anglerfish.Events
{
public class AnglerChangeStateEvent : QSBEvent<AnglerChangeStateMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener()
=> GlobalMessenger<QSBAngler>.AddListener(EventNames.QSBAnglerChangeState, Handler);
public override void CloseListener()
=> GlobalMessenger<QSBAngler>.RemoveListener(EventNames.QSBAnglerChangeState, Handler);
private void Handler(QSBAngler qsbAngler) => SendEvent(CreateMessage(qsbAngler));
private AnglerChangeStateMessage CreateMessage(QSBAngler qsbAngler) => new()
{
ObjectId = qsbAngler.ObjectId,
EnumValue = qsbAngler.AttachedObject._currentState,
TargetId = TargetToId(qsbAngler.TargetTransform),
LocalDisturbancePos = qsbAngler.AttachedObject._localDisturbancePos
};
public override void OnReceiveRemote(bool isHost, AnglerChangeStateMessage message)
{
var qsbAngler = QSBWorldSync.GetWorldFromId<QSBAngler>(message.ObjectId);
qsbAngler.TargetTransform = IdToTarget(message.TargetId);
qsbAngler.AttachedObject._localDisturbancePos = message.LocalDisturbancePos;
qsbAngler.AttachedObject.ChangeState(message.EnumValue);
}
private static uint TargetToId(Transform transform)
{
if (transform == null)
{
return uint.MaxValue;
}
if (transform == Locator.GetShipTransform())
{
return uint.MaxValue - 1;
}
return QSBPlayerManager.LocalPlayerId;
}
private static Transform IdToTarget(uint id)
{
if (id == uint.MaxValue)
{
return null;
}
if (id == uint.MaxValue - 1)
{
return Locator.GetShipTransform();
}
return QSBPlayerManager.GetPlayer(id).Body.transform;
}
}
}

View File

@ -1,26 +0,0 @@
using QSB.WorldSync.Events;
using QuantumUNET.Transport;
using UnityEngine;
namespace QSB.Anglerfish.Events
{
public class AnglerChangeStateMessage : EnumWorldObjectMessage<AnglerfishController.AnglerState>
{
public uint TargetId;
public Vector3 LocalDisturbancePos;
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
TargetId = reader.ReadUInt32();
LocalDisturbancePos = reader.ReadVector3();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(TargetId);
writer.Write(LocalDisturbancePos);
}
}
}

View File

@ -0,0 +1,72 @@
using QSB.Anglerfish.WorldObjects;
using QSB.Messaging;
using QSB.Player;
using QuantumUNET.Transport;
using UnityEngine;
namespace QSB.Anglerfish.Messages
{
public class AnglerChangeStateMessage : QSBEnumWorldObjectMessage<QSBAngler, AnglerfishController.AnglerState>
{
private uint TargetId;
private Vector3 LocalDisturbancePos;
public AnglerChangeStateMessage(QSBAngler qsbAngler)
{
Value = qsbAngler.AttachedObject._currentState;
TargetId = TargetToId(qsbAngler.TargetTransform);
LocalDisturbancePos = qsbAngler.AttachedObject._localDisturbancePos;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(TargetId);
writer.Write(LocalDisturbancePos);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
TargetId = reader.ReadUInt32();
LocalDisturbancePos = reader.ReadVector3();
}
public override void OnReceiveRemote()
{
WorldObject.TargetTransform = IdToTarget(TargetId);
WorldObject.AttachedObject._localDisturbancePos = LocalDisturbancePos;
WorldObject.AttachedObject.ChangeState(Value);
}
private static uint TargetToId(Transform transform)
{
if (transform == null)
{
return uint.MaxValue;
}
if (transform == Locator.GetShipTransform())
{
return uint.MaxValue - 1;
}
return QSBPlayerManager.LocalPlayerId;
}
private static Transform IdToTarget(uint id)
{
if (id == uint.MaxValue)
{
return null;
}
if (id == uint.MaxValue - 1)
{
return Locator.GetShipTransform();
}
return QSBPlayerManager.GetPlayer(id).Body.transform;
}
}
}

View File

@ -1,9 +1,8 @@
using HarmonyLib;
using QSB.Anglerfish.Messages;
using QSB.Anglerfish.WorldObjects;
using QSB.AuthoritySync;
using QSB.Events;
using QSB.Messaging;
using QSB.Patches;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
@ -17,7 +16,7 @@ namespace QSB.Anglerfish.Patches
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.GetTargetPosition))]
public static bool GetTargetPosition(AnglerfishController __instance, ref Vector3 __result)
{
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
if (qsbAngler.TargetTransform != null)
{
@ -35,12 +34,12 @@ namespace QSB.Anglerfish.Patches
public static bool OnSectorOccupantRemoved(AnglerfishController __instance,
SectorDetector sectorDetector)
{
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
if (qsbAngler.TargetTransform != null && sectorDetector.GetAttachedOWRigidbody().transform == qsbAngler.TargetTransform)
{
qsbAngler.TargetTransform = null;
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
return false;
@ -54,7 +53,7 @@ namespace QSB.Anglerfish.Patches
{
return true;
}
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
switch (__instance._currentState)
{
@ -62,7 +61,7 @@ namespace QSB.Anglerfish.Patches
if ((__instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos) - __instance._anglerBody.GetPosition()).sqrMagnitude < __instance._arrivalDistance * __instance._arrivalDistance)
{
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
break;
@ -70,14 +69,14 @@ namespace QSB.Anglerfish.Patches
if (qsbAngler.TargetTransform == null)
{
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
if ((qsbAngler.TargetTransform.position - __instance._anglerBody.GetPosition()).sqrMagnitude > __instance._escapeDistance * __instance._escapeDistance)
{
qsbAngler.TargetTransform = null;
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
break;
@ -87,7 +86,7 @@ namespace QSB.Anglerfish.Patches
if (qsbAngler.TargetTransform == null)
{
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
var num = Time.time - __instance._consumeStartTime;
@ -117,7 +116,7 @@ namespace QSB.Anglerfish.Patches
else
{
qsbAngler.TargetTransform = null;
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
break;
case AnglerfishController.AnglerState.Stunned:
@ -127,11 +126,11 @@ namespace QSB.Anglerfish.Patches
if (qsbAngler.TargetTransform != null)
{
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
break;
default:
@ -149,7 +148,7 @@ namespace QSB.Anglerfish.Patches
{
return true;
}
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
qsbAngler.UpdateTargetVelocity();
if (__instance._anglerBody.GetVelocity().sqrMagnitude > Mathf.Pow(__instance._chaseSpeed * 1.5f, 2f))
@ -228,7 +227,7 @@ namespace QSB.Anglerfish.Patches
public static bool OnImpact(AnglerfishController __instance,
ImpactData impact)
{
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
var attachedOWRigidbody = impact.otherCollider.GetAttachedOWRigidbody();
if ((attachedOWRigidbody.CompareTag("Player") || attachedOWRigidbody.CompareTag("Ship"))
@ -237,7 +236,7 @@ namespace QSB.Anglerfish.Patches
{
qsbAngler.TargetTransform = attachedOWRigidbody.transform;
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
@ -249,7 +248,7 @@ namespace QSB.Anglerfish.Patches
public static bool OnClosestAudibleNoise(AnglerfishController __instance,
NoiseMaker noiseMaker)
{
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
if (__instance._currentState is AnglerfishController.AnglerState.Consuming or AnglerfishController.AnglerState.Stunned)
{
@ -264,7 +263,7 @@ namespace QSB.Anglerfish.Patches
{
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
}
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
return false;
}
}
@ -275,7 +274,7 @@ namespace QSB.Anglerfish.Patches
{
__instance.ChangeState(AnglerfishController.AnglerState.Investigating);
}
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
return false;
@ -286,7 +285,7 @@ namespace QSB.Anglerfish.Patches
public static bool OnCaughtObject(AnglerfishController __instance,
OWRigidbody caughtBody)
{
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
var qsbAngler = __instance.GetWorldObject<QSBAngler>();
if (__instance._currentState == AnglerfishController.AnglerState.Consuming)
{
@ -301,7 +300,7 @@ namespace QSB.Anglerfish.Patches
qsbAngler.TargetTransform = caughtBody.transform;
__instance._consumeStartTime = Time.time;
__instance.ChangeState(AnglerfishController.AnglerState.Consuming);
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
qsbAngler.SendMessage(new AnglerChangeStateMessage(qsbAngler));
}
return false;

View File

@ -1,9 +1,9 @@
using QSB.Anglerfish.WorldObjects;
using QSB.AuthoritySync;
using QSB.Syncs.Unsectored.Rigidbodies;
using QSB.WorldSync;
using QuantumUNET.Transport;
using System.Collections.Generic;
using QSB.AuthoritySync;
using UnityEngine;
namespace QSB.Anglerfish.TransformSync
@ -43,7 +43,7 @@ namespace QSB.Anglerfish.TransformSync
protected override void Init()
{
_qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(AnglerManager.Anglers[_instances.IndexOf(this)]);
_qsbAngler = AnglerManager.Anglers[_instances.IndexOf(this)].GetWorldObject<QSBAngler>();
_qsbAngler.TransformSync = this;
base.Init();
@ -55,11 +55,11 @@ namespace QSB.Anglerfish.TransformSync
}
AttachedObject.OnUnsuspendOWRigidbody += OnUnsuspend;
AttachedObject.OnSuspendOWRigidbody += OnSuspend;
NetIdentity.FireAuthQueue(AttachedObject.IsSuspended() ? AuthQueueAction.Remove : AuthQueueAction.Add);
NetIdentity.SendAuthQueueMessage(AttachedObject.IsSuspended() ? AuthQueueAction.Remove : AuthQueueAction.Add);
}
private void OnUnsuspend(OWRigidbody suspendedBody) => NetIdentity.FireAuthQueue(AuthQueueAction.Add);
private void OnSuspend(OWRigidbody suspendedBody) => NetIdentity.FireAuthQueue(AuthQueueAction.Remove);
private void OnUnsuspend(OWRigidbody suspendedBody) => NetIdentity.SendAuthQueueMessage(AuthQueueAction.Add);
private void OnSuspend(OWRigidbody suspendedBody) => NetIdentity.SendAuthQueueMessage(AuthQueueAction.Remove);
private bool _shouldUpdate;

View File

@ -1,8 +0,0 @@
namespace QSB.Animation.NPC
{
internal enum AnimationEvent
{
StartConversation,
EndConversation
}
}

View File

@ -1,37 +0,0 @@
using QSB.Animation.NPC.WorldObjects;
using QSB.Events;
using QSB.WorldSync;
namespace QSB.Animation.NPC.Events
{
internal class NpcAnimationEvent : QSBEvent<NpcAnimationMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<AnimationEvent, int>.AddListener(EventNames.QSBNpcAnimEvent, Handler);
public override void CloseListener() => GlobalMessenger<AnimationEvent, int>.RemoveListener(EventNames.QSBNpcAnimEvent, Handler);
private void Handler(AnimationEvent animEvent, int index) => SendEvent(CreateMessage(animEvent, index));
private NpcAnimationMessage CreateMessage(AnimationEvent animEvent, int index) => new()
{
AboutId = LocalPlayerId,
AnimationEvent = animEvent,
AnimControllerIndex = index
};
public override void OnReceiveRemote(bool server, NpcAnimationMessage message)
{
var qsbObj = QSBWorldSync.GetWorldFromId<INpcAnimController>(message.AnimControllerIndex);
switch (message.AnimationEvent)
{
case AnimationEvent.StartConversation:
qsbObj.StartConversation();
break;
case AnimationEvent.EndConversation:
qsbObj.EndConversation();
break;
}
}
}
}

View File

@ -1,25 +0,0 @@
using QSB.Messaging;
using QuantumUNET.Transport;
namespace QSB.Animation.NPC.Events
{
internal class NpcAnimationMessage : PlayerMessage
{
public AnimationEvent AnimationEvent { get; set; }
public int AnimControllerIndex { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
AnimationEvent = (AnimationEvent)reader.ReadInt32();
AnimControllerIndex = reader.ReadInt32();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write((int)AnimationEvent);
writer.Write(AnimControllerIndex);
}
}
}

View File

@ -0,0 +1,22 @@
using QSB.Animation.NPC.WorldObjects;
using QSB.Messaging;
namespace QSB.Animation.NPC.Messages
{
internal class NpcAnimationMessage : QSBBoolWorldObjectMessage<INpcAnimController>
{
public NpcAnimationMessage(bool start) => Value = start;
public override void OnReceiveRemote()
{
if (Value)
{
WorldObject.StartConversation();
}
else
{
WorldObject.EndConversation();
}
}
}
}

View File

@ -1,10 +1,12 @@
using HarmonyLib;
using OWML.Common;
using QSB.Animation.NPC.Messages;
using QSB.Animation.NPC.WorldObjects;
using QSB.ConversationSync;
using QSB.Events;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using QSB.Player.Messages;
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
@ -20,27 +22,19 @@ namespace QSB.Animation.NPC.Patches
[HarmonyPrefix]
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnAnimatorIK))]
public static bool AnimatorIKReplacement(
CharacterAnimController __instance,
float ___headTrackingWeight,
bool ___lookOnlyWhenTalking,
bool ____inConversation,
ref float ____currentLookWeight,
ref Vector3 ____currentLookTarget,
DampedSpring3D ___lookSpring,
Animator ____animator,
CharacterDialogueTree ____dialogueTree)
CharacterAnimController __instance)
{
if (!WorldObjectManager.AllObjectsReady || ConversationManager.Instance == null)
{
return false;
}
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(__instance._dialogueTree);
var player = QSBPlayerManager.GetPlayer(playerId);
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController>(__instance); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
var qsbObj = __instance.GetWorldObject<QSBCharacterAnimController>(); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
PlayerInfo playerToUse = null;
if (____inConversation)
if (__instance._inConversation)
{
if (playerId == uint.MaxValue)
{
@ -54,7 +48,7 @@ namespace QSB.Animation.NPC.Patches
: player;
}
}
else if (!___lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0) // IDEA : maybe this would be more fun if characters looked between players at random times? :P
else if (!__instance.lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0) // IDEA : maybe this would be more fun if characters looked between players at random times? :P
{
playerToUse = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.GetPlayersInHeadZone(), __instance.transform.position);
}
@ -64,13 +58,13 @@ namespace QSB.Animation.NPC.Patches
}
var localPosition = playerToUse != null
? ____animator.transform.InverseTransformPoint(playerToUse.CameraBody.transform.position)
? __instance._animator.transform.InverseTransformPoint(playerToUse.CameraBody.transform.position)
: Vector3.zero;
var targetWeight = ___headTrackingWeight;
if (___lookOnlyWhenTalking)
var targetWeight = __instance.headTrackingWeight;
if (__instance.lookOnlyWhenTalking)
{
if (!____inConversation
if (!__instance._inConversation
|| qsbObj.GetPlayersInHeadZone().Count == 0
|| !qsbObj.GetPlayersInHeadZone().Contains(playerToUse))
{
@ -86,10 +80,10 @@ namespace QSB.Animation.NPC.Patches
}
}
____currentLookWeight = Mathf.Lerp(____currentLookWeight, targetWeight, Time.deltaTime * 2f);
____currentLookTarget = ___lookSpring.Update(____currentLookTarget, localPosition, Time.deltaTime);
____animator.SetLookAtPosition(____animator.transform.TransformPoint(____currentLookTarget));
____animator.SetLookAtWeight(____currentLookWeight);
__instance._currentLookWeight = Mathf.Lerp(__instance._currentLookWeight, targetWeight, Time.deltaTime * 2f);
__instance._currentLookTarget = __instance.lookSpring.Update(__instance._currentLookTarget, localPosition, Time.deltaTime);
__instance._animator.SetLookAtPosition(__instance._animator.transform.TransformPoint(__instance._currentLookTarget));
__instance._animator.SetLookAtWeight(__instance._currentLookWeight);
return false;
}
@ -100,8 +94,8 @@ namespace QSB.Animation.NPC.Patches
{
if (input.CompareTag("PlayerDetector"))
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController>(__instance);
QSBEventManager.FireEvent(EventNames.QSBExitNonNomaiHeadZone, qsbObj.ObjectId);
var qsbObj = __instance.GetWorldObject<QSBCharacterAnimController>();
new EnterLeaveMessage(EnterLeaveType.ExitNonNomaiHeadZone, qsbObj.ObjectId).Send();
}
return false;
@ -113,8 +107,8 @@ namespace QSB.Animation.NPC.Patches
{
if (input.CompareTag("PlayerDetector"))
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController>(__instance);
QSBEventManager.FireEvent(EventNames.QSBEnterNonNomaiHeadZone, qsbObj.ObjectId);
var qsbObj = __instance.GetWorldObject<QSBCharacterAnimController>();
new EnterLeaveMessage(EnterLeaveType.EnterNonNomaiHeadZone, qsbObj.ObjectId).Send();
}
return false;
}
@ -153,8 +147,7 @@ namespace QSB.Animation.NPC.Patches
return true;
}
var id = ownerOfThis.ObjectId;
QSBEventManager.FireEvent(EventNames.QSBNpcAnimEvent, AnimationEvent.StartConversation, id);
ownerOfThis.SendMessage(new NpcAnimationMessage(true));
return true;
}
@ -169,8 +162,7 @@ namespace QSB.Animation.NPC.Patches
return true;
}
var id = ownerOfThis.ObjectId;
QSBEventManager.FireEvent(EventNames.QSBNpcAnimEvent, AnimationEvent.EndConversation, id);
ownerOfThis.SendMessage(new NpcAnimationMessage(false));
return true;
}

View File

@ -1,8 +1,9 @@
using HarmonyLib;
using QSB.Animation.NPC.WorldObjects;
using QSB.Events;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using QSB.Player.Messages;
using QSB.WorldSync;
using System.Linq;
using UnityEngine;
@ -24,7 +25,7 @@ namespace QSB.Animation.NPC.Patches
__instance._animatorStateEvents.OnEnterState += __instance.OnEnterAnimatorState;
}
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance);
var qsbObj = __instance.GetWorldObject<QSBSolanumAnimController>();
var playersInHeadZone = qsbObj.GetPlayersInHeadZone();
var targetCamera = playersInHeadZone == null || playersInHeadZone.Count == 0
@ -46,8 +47,8 @@ namespace QSB.Animation.NPC.Patches
{
if (hitObj.CompareTag("PlayerDetector"))
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance._solanumAnimController);
QSBEventManager.FireEvent(EventNames.QSBEnterNomaiHeadZone, qsbObj.ObjectId);
var qsbObj = __instance._solanumAnimController.GetWorldObject<QSBSolanumAnimController>();
new EnterLeaveMessage(EnterLeaveType.EnterNomaiHeadZone, qsbObj.ObjectId).Send();
}
return false;
@ -59,8 +60,8 @@ namespace QSB.Animation.NPC.Patches
{
if (hitObj.CompareTag("PlayerDetector"))
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance._solanumAnimController);
QSBEventManager.FireEvent(EventNames.QSBExitNomaiHeadZone, qsbObj.ObjectId);
var qsbObj = __instance._solanumAnimController.GetWorldObject<QSBSolanumAnimController>();
new EnterLeaveMessage(EnterLeaveType.ExitNomaiHeadZone, qsbObj.ObjectId).Send();
}
return false;
}
@ -69,7 +70,7 @@ namespace QSB.Animation.NPC.Patches
[HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.Update))]
public static bool ReplacementUpdate(NomaiConversationManager __instance)
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance._solanumAnimController);
var qsbObj = __instance._solanumAnimController.GetWorldObject<QSBSolanumAnimController>();
__instance._playerInWatchVolume = qsbObj.GetPlayersInHeadZone().Any();
if (!__instance._initialized)

View File

@ -6,98 +6,112 @@ using UnityEngine;
namespace QSB.Animation.NPC.Patches
{
[HarmonyPatch(typeof(TravelerController))]
public class TravelerControllerPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
[HarmonyPrefix]
[HarmonyPatch(nameof(TravelerController.OnStartConversation))]
[HarmonyPatch(typeof(TravelerController), nameof(TravelerController.OnStartConversation))]
public static bool OnStartConversation(TravelerController __instance)
{
__instance._talking = true;
if (__instance is GabbroTravelerController gabbro)
{
if (gabbro._animator.enabled)
{
gabbro._animator.CrossFadeInFixedTime("Gabbro_Talking", 1.8f);
gabbro._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Talking", 1.8f);
}
Locator.GetTravelerAudioManager().StopTravelerAudio(gabbro.name);
}
else
{
if (__instance._animator != null && __instance._animator.enabled)
{
__instance._playingAnimID = __instance._animator.IsInTransition(0)
? __instance._animator.GetNextAnimatorStateInfo(0).fullPathHash
: __instance._animator.GetCurrentAnimatorStateInfo(0).fullPathHash;
__instance._animator.SetTrigger("Talking");
}
Locator.GetTravelerAudioManager().StopTravelerAudio(__instance.name);
if (__instance is ChertTravelerController chert)
{
chert._moodWeight = (float)chert._mood;
}
}
// call directly instead of firing event
__instance.StartConversation();
return false;
}
[HarmonyPrefix]
[HarmonyPatch(nameof(TravelerController.OnEndConversation))]
[HarmonyPatch(typeof(TravelerController), nameof(TravelerController.OnEndConversation))]
public static bool OnEndConversation(TravelerController __instance)
{
if (__instance is GabbroTravelerController gabbro)
{
if (gabbro._animator.enabled)
{
gabbro._animator.CrossFadeInFixedTime("Gabbro_Playing", gabbro._delayToRestartAudio, -1, -gabbro._delayToRestartAudio);
gabbro._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Playing", gabbro._delayToRestartAudio, -1, -gabbro._delayToRestartAudio);
}
Locator.GetTravelerAudioManager().PlayTravelerAudio(gabbro.name, gabbro._delayToRestartAudio);
if (DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_REMINDER") || DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION"))
{
var conditionState = DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION");
DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_REMINDER");
DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_ATTENTION");
GlobalMessenger<bool>.FireEvent("TriggerMapPromptReminder", conditionState);
}
}
else
{
if (__instance._animator != null && __instance._animator.enabled)
{
if (__instance._delayToRestartAudio > 0f)
{
__instance._animator.CrossFadeInFixedTime(__instance._playingAnimID, __instance._delayToRestartAudio, -1, -__instance._delayToRestartAudio);
}
else
{
__instance._animator.SetTrigger("Playing");
}
}
Locator.GetTravelerAudioManager().PlayTravelerAudio(__instance.name, __instance._delayToRestartAudio);
}
// call directly instead of firing event
__instance.EndConversation(__instance._delayToRestartAudio);
__instance._talking = false;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TravelerController), nameof(TravelerController.StartConversation))]
public static bool StartConversation(TravelerController __instance)
{
if (__instance._animator != null && __instance._animator.enabled)
{
__instance._playingAnimID = __instance._animator.IsInTransition(0)
? __instance._animator.GetNextAnimatorStateInfo(0).fullPathHash
: __instance._animator.GetCurrentAnimatorStateInfo(0).fullPathHash;
__instance._animator.SetTrigger("Talking");
}
Locator.GetTravelerAudioManager().StopTravelerAudio(__instance);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GabbroTravelerController), nameof(GabbroTravelerController.StartConversation))]
public static bool StartConversation(GabbroTravelerController __instance)
{
if (__instance._animator.enabled)
{
__instance._animator.CrossFadeInFixedTime("Gabbro_Talking", 1.8f);
__instance._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Talking", 1.8f);
}
Locator.GetTravelerAudioManager().StopTravelerAudio(__instance);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TravelerController), nameof(TravelerController.EndConversation))]
public static bool EndConversation(TravelerController __instance, float audioDelay)
{
if (__instance._animator != null && __instance._animator.enabled)
{
if (audioDelay > 0f)
{
__instance._animator.CrossFadeInFixedTime(__instance._playingAnimID, audioDelay, -1, -audioDelay);
}
else
{
__instance._animator.SetTrigger("Playing");
}
}
Locator.GetTravelerAudioManager().PlayTravelerAudio(__instance, audioDelay);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GabbroTravelerController), nameof(GabbroTravelerController.EndConversation))]
public static bool EndConversation(GabbroTravelerController __instance, float audioDelay)
{
if (__instance._animator.enabled)
{
__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"))
{
var conditionState = DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION");
DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_REMINDER");
DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_ATTENTION");
GlobalMessenger<bool>.FireEvent("TriggerMapPromptReminder", conditionState);
}
return false;
}
}
internal static class TravelerAudioManagerExtensions
{
/// bad, but works great
private static SignalName TravelerToSignal(string name)
private static SignalName TravelerToSignalName(TravelerController traveler)
{
var name = traveler.name;
if (name.Contains("Esker"))
{
return SignalName.Traveler_Esker;
@ -136,27 +150,27 @@ namespace QSB.Animation.NPC.Patches
throw new ArgumentOutOfRangeException(nameof(name), name, null);
}
internal static void StopTravelerAudio(this TravelerAudioManager manager, string name)
internal static void StopTravelerAudio(this TravelerAudioManager manager, TravelerController traveler)
{
var signalName = TravelerToSignal(name);
var audioSignal = manager._signals.First(x => x.GetName() == signalName);
var signalName = TravelerToSignalName(traveler);
var signal = manager._signals.First(x => x.GetName() == signalName);
audioSignal.GetOWAudioSource().FadeOut(0.5f);
signal.GetOWAudioSource().FadeOut(0.5f);
}
internal static void PlayTravelerAudio(this TravelerAudioManager manager, string name, float audioDelay)
internal static void PlayTravelerAudio(this TravelerAudioManager manager, TravelerController traveler, float audioDelay)
{
var signalName = TravelerToSignal(name);
var audioSignal = manager._signals.First(x => x.GetName() == signalName);
var signalName = TravelerToSignalName(traveler);
var signal = manager._signals.First(x => x.GetName() == signalName);
manager._playAfterDelay = false;
manager._playAudioTime = Time.time + audioDelay;
QSBCore.UnityEvents.RunWhen(() => Time.time >= manager._playAudioTime, () =>
{
if (!audioSignal.IsOnlyAudibleToScope() || audioSignal.GetOWAudioSource().isPlaying)
if (!signal.IsOnlyAudibleToScope() || signal.GetOWAudioSource().isPlaying)
{
audioSignal.GetOWAudioSource().FadeIn(0.5f);
audioSignal.GetOWAudioSource().timeSamples = 0;
signal.GetOWAudioSource().FadeIn(0.5f);
signal.GetOWAudioSource().timeSamples = 0;
}
});
}

View File

@ -10,10 +10,10 @@ namespace QSB.Animation.NPC.WorldObjects
public abstract CharacterDialogueTree GetDialogueTree();
public virtual void StartConversation()
=> GetDialogueTree().RaiseEvent("OnStartConversation");
=> GetDialogueTree().RaiseEvent(nameof(CharacterDialogueTree.OnStartConversation));
public virtual void EndConversation()
=> GetDialogueTree().RaiseEvent("OnEndConversation");
=> GetDialogueTree().RaiseEvent(nameof(CharacterDialogueTree.OnEndConversation));
public virtual bool InConversation()
=> false;

View File

@ -1,26 +0,0 @@
using OWML.Utils;
using UnityEngine;
namespace QSB.Animation.Player
{
public static class AnimControllerPatch
{
public static RuntimeAnimatorController SuitedAnimController { get; private set; }
public static void Init()
{
QSBCore.Helper.Events.Subscribe<PlayerAnimController>(OWML.Common.Events.BeforeStart);
QSBCore.Helper.Events.Event += OnEvent;
}
private static void OnEvent(MonoBehaviour behaviour, OWML.Common.Events ev)
{
if (behaviour is PlayerAnimController playerAnimController &&
ev == OWML.Common.Events.BeforeStart &&
SuitedAnimController == null)
{
SuitedAnimController = playerAnimController.GetValue<RuntimeAnimatorController>("_baseAnimController");
}
}
}
}

View File

@ -1,7 +1,7 @@
using OWML.Common;
using OWML.Utils;
using QSB.Animation.Player.Messages;
using QSB.Animation.Player.Thrusters;
using QSB.Events;
using QSB.Messaging;
using QSB.Player;
using QSB.Utility;
using QuantumUNET.Components;
@ -83,10 +83,10 @@ namespace QSB.Animation.Player
}
var playerAnimController = body.GetComponent<PlayerAnimController>();
_suitedAnimController = AnimControllerPatch.SuitedAnimController;
_unsuitedAnimController = playerAnimController.GetValue<AnimatorOverrideController>("_unsuitedAnimOverride");
_suitedGraphics = playerAnimController.GetValue<GameObject>("_suitedGroup");
_unsuitedGraphics = playerAnimController.GetValue<GameObject>("_unsuitedGroup");
_suitedAnimController = playerAnimController._baseAnimController;
_unsuitedAnimController = playerAnimController._unsuitedAnimOverride;
_suitedGraphics = playerAnimController._suitedGroup;
_unsuitedGraphics = playerAnimController._unsuitedGroup;
}
public void InitLocal(Transform body)
@ -106,13 +106,13 @@ namespace QSB.Animation.Player
var playerAnimController = body.GetComponent<PlayerAnimController>();
playerAnimController.enabled = false;
playerAnimController.SetValue("_suitedGroup", new GameObject());
playerAnimController.SetValue("_unsuitedGroup", new GameObject());
playerAnimController.SetValue("_baseAnimController", null);
playerAnimController.SetValue("_unsuitedAnimOverride", null);
playerAnimController.SetValue("_rightArmHidden", false);
playerAnimController._suitedGroup = new GameObject();
playerAnimController._unsuitedGroup = new GameObject();
playerAnimController._baseAnimController = null;
playerAnimController._unsuitedAnimOverride = null;
playerAnimController._rightArmHidden = false;
var rightArmObjects = playerAnimController.GetValue<GameObject[]>("_rightArmObjects").ToList();
var rightArmObjects = playerAnimController._rightArmObjects.ToList();
rightArmObjects.ForEach(rightArmObject => rightArmObject.layer = LayerMask.NameToLayer("Default"));
body.Find("player_mesh_noSuit:Traveller_HEA_Player/player_mesh_noSuit:Player_Head").gameObject.layer = 0;
@ -143,13 +143,13 @@ namespace QSB.Animation.Player
private void SuitUp()
{
QSBEventManager.FireEvent(EventNames.QSBChangeAnimType, PlayerId, AnimationType.PlayerSuited);
new ChangeAnimTypeMessage(PlayerId, AnimationType.PlayerSuited).Send();
SetAnimationType(AnimationType.PlayerSuited);
}
private void SuitDown()
{
QSBEventManager.FireEvent(EventNames.QSBChangeAnimType, PlayerId, AnimationType.PlayerUnsuited);
new ChangeAnimTypeMessage(PlayerId, AnimationType.PlayerUnsuited).Send();
SetAnimationType(AnimationType.PlayerUnsuited);
}
@ -206,12 +206,12 @@ namespace QSB.Animation.Player
{
_unsuitedGraphics?.SetActive(false);
}
if (_suitedGraphics != null)
{
_suitedGraphics?.SetActive(true);
}
break;
case AnimationType.PlayerUnsuited:
@ -273,7 +273,7 @@ namespace QSB.Animation.Player
{
VisibleAnimator.SetTrigger("Playing");
}
if (InvisibleAnimator != null)
{
InvisibleAnimator.SetTrigger("Playing");

View File

@ -1,38 +0,0 @@
using QSB.Events;
using QSB.Player;
namespace QSB.Animation.Player.Events
{
internal class AnimationTriggerEvent : QSBEvent<AnimationTriggerMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<uint, string>.AddListener(EventNames.QSBAnimTrigger, Handler);
public override void CloseListener() => GlobalMessenger<uint, string>.RemoveListener(EventNames.QSBAnimTrigger, Handler);
private void Handler(uint attachedNetId, string name) => SendEvent(CreateMessage(attachedNetId, name));
private AnimationTriggerMessage CreateMessage(uint attachedNetId, string name) => new()
{
AboutId = LocalPlayerId,
AttachedNetId = attachedNetId,
Name = name
};
public override void OnReceiveRemote(bool server, AnimationTriggerMessage message)
{
var animationSync = QSBPlayerManager.GetSyncObject<AnimationSync>(message.AttachedNetId);
if (animationSync == null)
{
return;
}
if (animationSync.VisibleAnimator == null)
{
return;
}
animationSync.VisibleAnimator.SetTrigger(message.Name);
}
}
}

View File

@ -1,25 +0,0 @@
using QSB.Messaging;
using QuantumUNET.Transport;
namespace QSB.Animation.Player.Events
{
public class AnimationTriggerMessage : PlayerMessage
{
public uint AttachedNetId { get; set; }
public string Name { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
AttachedNetId = reader.ReadUInt32();
Name = reader.ReadString();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(AttachedNetId);
writer.Write(Name);
}
}
}

View File

@ -1,34 +0,0 @@
using QSB.Events;
using QSB.Instruments;
using QSB.Messaging;
using QSB.Player;
namespace QSB.Animation.Player.Events
{
public class ChangeAnimTypeEvent : QSBEvent<EnumMessage<AnimationType>>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<uint, AnimationType>.AddListener(EventNames.QSBChangeAnimType, Handler);
public override void CloseListener() => GlobalMessenger<uint, AnimationType>.RemoveListener(EventNames.QSBChangeAnimType, Handler);
private void Handler(uint player, AnimationType type) => SendEvent(CreateMessage(player, type));
private EnumMessage<AnimationType> CreateMessage(uint player, AnimationType type) => new()
{
AboutId = player,
EnumValue = type
};
public override void OnReceiveRemote(bool server, EnumMessage<AnimationType> message)
{
if (!QSBPlayerManager.GetPlayer(message.AboutId).IsReady)
{
return;
}
QSBPlayerManager.GetPlayer(message.AboutId).AnimationSync.SetAnimationType(message.EnumValue);
QSBPlayerManager.GetSyncObject<InstrumentsManager>(message.AboutId).CheckInstrumentProps(message.EnumValue);
}
}
}

View File

@ -1,55 +0,0 @@
using QSB.Events;
using QSB.Messaging;
using QSB.Player;
namespace QSB.Animation.Player.Events
{
public class PlayerSuitEvent : QSBEvent<ToggleMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener()
{
GlobalMessenger.AddListener(EventNames.SuitUp, HandleSuitUp);
GlobalMessenger.AddListener(EventNames.RemoveSuit, HandleSuitDown);
}
public override void CloseListener()
{
GlobalMessenger.RemoveListener(EventNames.SuitUp, HandleSuitUp);
GlobalMessenger.RemoveListener(EventNames.RemoveSuit, HandleSuitDown);
}
private void HandleSuitUp() => SendEvent(CreateMessage(true));
private void HandleSuitDown() => SendEvent(CreateMessage(false));
private ToggleMessage CreateMessage(bool value) => new()
{
AboutId = LocalPlayerId,
ToggleValue = value
};
public override void OnReceiveRemote(bool server, ToggleMessage message)
{
var player = QSBPlayerManager.GetPlayer(message.AboutId);
player.SuitedUp = message.ToggleValue;
if (!player.IsReady)
{
return;
}
var animator = player.AnimationSync;
var type = message.ToggleValue ? AnimationType.PlayerSuited : AnimationType.PlayerUnsuited;
animator.SetAnimationType(type);
}
public override void OnReceiveLocal(bool server, ToggleMessage message)
{
QSBPlayerManager.LocalPlayer.SuitedUp = message.ToggleValue;
var animator = QSBPlayerManager.LocalPlayer.AnimationSync;
var type = message.ToggleValue ? AnimationType.PlayerSuited : AnimationType.PlayerUnsuited;
animator.CurrentType = type;
}
}
}

View File

@ -0,0 +1,51 @@
using QSB.Messaging;
using QSB.Player;
using QSB.WorldSync;
using QuantumUNET.Transport;
namespace QSB.Animation.Player.Messages
{
internal class AnimationTriggerMessage : QSBMessage
{
private uint AttachedNetId;
private string Name;
public AnimationTriggerMessage(uint attachedNetId, string name)
{
AttachedNetId = attachedNetId;
Name = name;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(AttachedNetId);
writer.Write(Name);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
AttachedNetId = reader.ReadUInt32();
Name = reader.ReadString();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
var animationSync = QSBPlayerManager.GetSyncObject<AnimationSync>(AttachedNetId);
if (animationSync == null)
{
return;
}
if (animationSync.VisibleAnimator == null)
{
return;
}
animationSync.VisibleAnimator.SetTrigger(Name);
}
}
}

View File

@ -0,0 +1,45 @@
using QSB.Instruments;
using QSB.Messaging;
using QSB.Player;
using QSB.WorldSync;
using QuantumUNET.Transport;
namespace QSB.Animation.Player.Messages
{
public class ChangeAnimTypeMessage : QSBEnumMessage<AnimationType>
{
private uint PlayerId;
public ChangeAnimTypeMessage(uint playerId, AnimationType type)
{
PlayerId = playerId;
Value = type;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(PlayerId);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
PlayerId = reader.ReadUInt32();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(PlayerId);
if (!player.IsReady)
{
return;
}
player.AnimationSync.SetAnimationType(Value);
QSBPlayerManager.GetSyncObject<InstrumentsManager>(PlayerId).CheckInstrumentProps(Value);
}
}
}

View File

@ -0,0 +1,48 @@
using QSB.Messaging;
using QSB.Player;
using QSB.Player.TransformSync;
namespace QSB.Animation.Player.Messages
{
public class PlayerSuitMessage : QSBBoolMessage
{
static PlayerSuitMessage()
{
GlobalMessenger.AddListener(OWEvents.SuitUp, () => Handle(true));
GlobalMessenger.AddListener(OWEvents.RemoveSuit, () => Handle(false));
}
private static void Handle(bool on)
{
if (PlayerTransformSync.LocalInstance)
{
new PlayerSuitMessage(on).Send();
}
}
private PlayerSuitMessage(bool on) => Value = on;
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);
player.SuitedUp = Value;
if (!player.IsReady)
{
return;
}
var animator = player.AnimationSync;
var type = Value ? AnimationType.PlayerSuited : AnimationType.PlayerUnsuited;
animator.SetAnimationType(type);
}
public override void OnReceiveLocal()
{
QSBPlayerManager.LocalPlayer.SuitedUp = Value;
var animator = QSBPlayerManager.LocalPlayer.AnimationSync;
var type = Value ? AnimationType.PlayerSuited : AnimationType.PlayerUnsuited;
animator.CurrentType = type;
}
}
}

View File

@ -1,11 +1,12 @@
using HarmonyLib;
using QSB.Events;
using QSB.Animation.Player.Messages;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using QSB.Utility;
using UnityEngine;
namespace QSB.Animation.Patches
namespace QSB.Animation.Player.Patches
{
[HarmonyPatch]
internal class PlayerAnimationPatches : QSBPatch
@ -15,28 +16,16 @@ namespace QSB.Animation.Patches
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerAnimController), nameof(PlayerAnimController.LateUpdate))]
public static bool LateUpdateReplacement(
PlayerAnimController __instance,
PlayerCharacterController ____playerController,
ThrusterModel ____playerJetpack,
ref float ____ungroundedTime,
Animator ____animator,
ref bool ____justBecameGrounded,
ref bool ____justTookFallDamage,
ref bool ____leftFootGrounded,
ref bool ____rightFootGrounded,
ref bool ____rightArmHidden,
GameObject[] ____rightArmObjects,
int ____defaultLayer,
int ____probeOnlyLayer)
PlayerAnimController __instance)
{
var isGrounded = ____playerController.IsGrounded();
var isGrounded = __instance._playerController.IsGrounded();
var isAttached = PlayerState.IsAttached();
var isInZeroG = PlayerState.InZeroG();
var isFlying = ____playerJetpack.GetLocalAcceleration().y > 0f;
var isFlying = __instance._playerJetpack.GetLocalAcceleration().y > 0f;
var movementVector = Vector3.zero;
if (!isAttached)
{
movementVector = ____playerController.GetRelativeGroundVelocity();
movementVector = __instance._playerController.GetRelativeGroundVelocity();
}
if (Mathf.Abs(movementVector.x) < 0.05f)
@ -51,77 +40,77 @@ namespace QSB.Animation.Patches
if (isFlying)
{
____ungroundedTime = Time.time;
__instance._ungroundedTime = Time.time;
}
var freefallMagnitude = 0f;
var timeInFreefall = 0f;
var lastGroundBody = ____playerController.GetLastGroundBody();
var lastGroundBody = __instance._playerController.GetLastGroundBody();
if (!isGrounded && !isAttached && !isInZeroG && lastGroundBody != null)
{
freefallMagnitude = (____playerController.GetAttachedOWRigidbody(false).GetVelocity() - lastGroundBody.GetPointVelocity(____playerController.transform.position)).magnitude;
timeInFreefall = Time.time - ____ungroundedTime;
freefallMagnitude = (__instance._playerController.GetAttachedOWRigidbody().GetVelocity() - lastGroundBody.GetPointVelocity(__instance._playerController.transform.position)).magnitude;
timeInFreefall = Time.time - __instance._ungroundedTime;
}
____animator.SetFloat("RunSpeedX", movementVector.x / 3f);
____animator.SetFloat("RunSpeedY", movementVector.z / 3f);
____animator.SetFloat("TurnSpeed", ____playerController.GetTurning());
____animator.SetBool("Grounded", isGrounded || isAttached || PlayerState.IsRecentlyDetached());
____animator.SetLayerWeight(1, ____playerController.GetJumpCrouchFraction());
____animator.SetFloat("FreefallSpeed", freefallMagnitude / 15f * (timeInFreefall / 3f));
____animator.SetBool("InZeroG", isInZeroG || isFlying);
____animator.SetBool("UsingJetpack", isInZeroG && PlayerState.IsWearingSuit());
if (____justBecameGrounded)
__instance._animator.SetFloat("RunSpeedX", movementVector.x / 3f);
__instance._animator.SetFloat("RunSpeedY", movementVector.z / 3f);
__instance._animator.SetFloat("TurnSpeed", __instance._playerController.GetTurning());
__instance._animator.SetBool("Grounded", isGrounded || isAttached || PlayerState.IsRecentlyDetached());
__instance._animator.SetLayerWeight(1, __instance._playerController.GetJumpCrouchFraction());
__instance._animator.SetFloat("FreefallSpeed", freefallMagnitude / 15f * (timeInFreefall / 3f));
__instance._animator.SetBool("InZeroG", isInZeroG || isFlying);
__instance._animator.SetBool("UsingJetpack", isInZeroG && PlayerState.IsWearingSuit());
if (__instance._justBecameGrounded)
{
var playerAnimationSync = QSBPlayerManager.LocalPlayer.AnimationSync;
if (____justTookFallDamage)
if (__instance._justTookFallDamage)
{
____animator.SetTrigger("LandHard");
QSBEventManager.FireEvent(EventNames.QSBAnimTrigger, playerAnimationSync.AttachedNetId, "LandHard");
__instance._animator.SetTrigger("LandHard");
new AnimationTriggerMessage(playerAnimationSync.AttachedNetId, "LandHard").Send();
}
else
{
____animator.SetTrigger("Land");
QSBEventManager.FireEvent(EventNames.QSBAnimTrigger, playerAnimationSync.AttachedNetId, "Land");
__instance._animator.SetTrigger("Land");
new AnimationTriggerMessage(playerAnimationSync.AttachedNetId, "Land").Send();
}
}
if (isGrounded)
{
var leftFootLift = ____animator.GetFloat("LeftFootLift");
if (!____leftFootGrounded && leftFootLift < 0.333f)
var leftFootLift = __instance._animator.GetFloat("LeftFootLift");
if (!__instance._leftFootGrounded && leftFootLift < 0.333f)
{
____leftFootGrounded = true;
__instance.RaiseEvent("OnLeftFootGrounded");
__instance._leftFootGrounded = true;
__instance.RaiseEvent(nameof(__instance.OnLeftFootGrounded));
}
else if (____leftFootGrounded && leftFootLift > 0.666f)
else if (__instance._leftFootGrounded && leftFootLift > 0.666f)
{
____leftFootGrounded = false;
__instance.RaiseEvent("OnLeftFootLift");
__instance._leftFootGrounded = false;
__instance.RaiseEvent(nameof(__instance.OnLeftFootLift));
}
var rightFootLift = ____animator.GetFloat("RightFootLift");
if (!____rightFootGrounded && rightFootLift < 0.333f)
var rightFootLift = __instance._animator.GetFloat("RightFootLift");
if (!__instance._rightFootGrounded && rightFootLift < 0.333f)
{
____rightFootGrounded = true;
__instance.RaiseEvent("OnRightFootGrounded");
__instance._rightFootGrounded = true;
__instance.RaiseEvent(nameof(__instance.OnRightFootGrounded));
}
else if (____rightFootGrounded && rightFootLift > 0.666f)
else if (__instance._rightFootGrounded && rightFootLift > 0.666f)
{
____rightFootGrounded = false;
__instance.RaiseEvent("OnRightFootLift");
__instance._rightFootGrounded = false;
__instance.RaiseEvent(nameof(__instance.OnRightFootLift));
}
}
____justBecameGrounded = false;
____justTookFallDamage = false;
__instance._justBecameGrounded = false;
__instance._justTookFallDamage = false;
var usingTool = Locator.GetToolModeSwapper().GetToolMode() != ToolMode.None;
if ((usingTool && !____rightArmHidden) || (!usingTool && ____rightArmHidden))
if ((usingTool && !__instance._rightArmHidden) || (!usingTool && __instance._rightArmHidden))
{
____rightArmHidden = usingTool;
for (var i = 0; i < ____rightArmObjects.Length; i++)
__instance._rightArmHidden = usingTool;
for (var i = 0; i < __instance._rightArmObjects.Length; i++)
{
____rightArmObjects[i].layer = (!____rightArmHidden) ? ____defaultLayer : ____probeOnlyLayer;
__instance._rightArmObjects[i].layer = (!__instance._rightArmHidden) ? __instance._defaultLayer : __instance._probeOnlyLayer;
}
}
@ -140,7 +129,7 @@ namespace QSB.Animation.Patches
__instance._animator.SetTrigger("Jump");
var playerAnimationSync = QSBPlayerManager.LocalPlayer.AnimationSync;
QSBEventManager.FireEvent(EventNames.QSBAnimTrigger, playerAnimationSync.AttachedNetId, "Jump");
new AnimationTriggerMessage(playerAnimationSync.AttachedNetId, "Jump").Send();
return false;
}
}

View File

@ -1,5 +1,4 @@
using OWML.Utils;
using QSB.Player;
using QSB.Player;
using QSB.Utility;
using UnityEngine;
@ -45,8 +44,8 @@ namespace QSB.Animation.Player.Thrusters
foreach (var controller in existingControllers)
{
var gameObject = controller.gameObject;
var oldThruster = controller.GetValue<Thruster>("_thruster");
var oldLight = controller.GetValue<Light>("_light");
var oldThruster = controller._thruster;
var oldLight = controller._light;
var localPos = oldThruster switch
{
Thruster.Up_RightThruster or Thruster.Up_LeftThruster => new Vector3(0, 0, 3),
@ -55,9 +54,9 @@ namespace QSB.Animation.Player.Thrusters
};
oldLight.transform.localPosition = localPos;
var oldAnimCurve = controller.GetValue<AnimationCurve>("_scaleByThrust");
var oldScaleSpring = controller.GetValue<DampedSpring>("_scaleSpring");
var oldScalar = controller.GetValue<float>("_belowMaxThrustScalar");
var oldAnimCurve = controller._scaleByThrust;
var oldScaleSpring = controller._scaleSpring;
var oldScalar = controller._belowMaxThrustScalar;
var oldBase = oldLight.range;
Object.Destroy(controller);
var newObj = gameObject.AddComponent<RemoteThrusterFlameController>();
@ -82,9 +81,9 @@ namespace QSB.Animation.Player.Thrusters
private static void CreateThrusterWashController(GameObject root, PlayerInfo player)
{
var old = root.GetComponent<ThrusterWashController>();
var oldDistanceScale = old.GetValue<AnimationCurve>("_emissionDistanceScale");
var oldThrusterScale = old.GetValue<AnimationCurve>("_emissionThrusterScale");
var defaultParticleSystem = old.GetValue<ParticleSystem>("_defaultParticleSystem");
var oldDistanceScale = old._emissionDistanceScale;
var oldThrusterScale = old._emissionThrusterScale;
var defaultParticleSystem = old._defaultParticleSystem;
Object.Destroy(old);

View File

@ -23,16 +23,16 @@ namespace QSB.Audio
}
public void PlayEquipTool()
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolTranslatorEquip, 1f);
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolTranslatorEquip);
public void PlayUnequipTool()
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolTranslatorUnequip, 1f);
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolTranslatorUnequip);
public void PlayTurnOnFlashlight()
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolFlashlightOn, 1f);
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolFlashlightOn);
public void PlayTurnOffFlashlight()
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolFlashlightOff, 1f);
=> _oneShotExternalSource.PlayOneShot(AudioType.ToolFlashlightOff);
private OWAudioSource CreateBaseAudio(
Transform parent,

View File

@ -1,34 +0,0 @@
using QSB.Events;
using QuantumUNET.Components;
namespace QSB.AuthoritySync
{
public class AuthQueueEvent : QSBEvent<AuthQueueMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() =>
GlobalMessenger<QNetworkIdentity, AuthQueueAction>.AddListener(EventNames.QSBAuthQueue, Handler);
public override void CloseListener() =>
GlobalMessenger<QNetworkIdentity, AuthQueueAction>.RemoveListener(EventNames.QSBAuthQueue, Handler);
private void Handler(QNetworkIdentity identity, AuthQueueAction action) => SendEvent(CreateMessage(identity, action));
private AuthQueueMessage CreateMessage(QNetworkIdentity identity, AuthQueueAction action) => new()
{
OnlySendToHost = true,
Identity = identity,
EnumValue = action
};
public override void OnReceiveLocal(bool isHost, AuthQueueMessage message) => OnReceive(message);
public override void OnReceiveRemote(bool isHost, AuthQueueMessage message) => OnReceive(message);
private static void OnReceive(AuthQueueMessage message)
{
message.Identity.UpdateAuthQueue(message.FromId, message.EnumValue);
}
}
}

View File

@ -1,38 +1,53 @@
using QSB.Messaging;
using QuantumUNET.Components;
using QSB.WorldSync;
using QuantumUNET;
using QuantumUNET.Transport;
namespace QSB.AuthoritySync
{
public class AuthQueueMessage : EnumMessage<AuthQueueAction>
/// <summary>
/// always sent to host
/// </summary>
public class AuthQueueMessage : QSBEnumMessage<AuthQueueAction>
{
public QNetworkIdentity Identity;
private QNetworkInstanceId NetId;
public override void Deserialize(QNetworkReader reader)
public AuthQueueMessage(QNetworkInstanceId netId, AuthQueueAction action)
{
base.Deserialize(reader);
Identity = reader.ReadNetworkIdentity();
To = 0;
NetId = netId;
Value = action;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(Identity);
writer.Write(NetId);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
NetId = reader.ReadNetworkId();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveLocal() => OnReceiveRemote();
public override void OnReceiveRemote() => QNetworkServer.objects[NetId].UpdateAuthQueue(From, Value);
}
public enum AuthQueueAction
{
/// <summary>
/// add identity to the queue
/// add player to the queue
/// </summary>
Add,
/// <summary>
/// remove identity from the queue
/// remove player from the queue
/// </summary>
Remove,
/// <summary>
/// add identity to the queue and force it to the front
/// add player to the queue and force them to the front
/// </summary>
Force
}

View File

@ -1,4 +1,4 @@
using QSB.Events;
using QSB.Messaging;
using QSB.Utility;
using QuantumUNET;
using QuantumUNET.Components;
@ -88,8 +88,8 @@ namespace QSB.AuthoritySync
#region any client
public static void FireAuthQueue(this QNetworkIdentity identity, AuthQueueAction action) =>
QSBEventManager.FireEvent(EventNames.QSBAuthQueue, identity, action);
public static void SendAuthQueueMessage(this QNetworkIdentity identity, AuthQueueAction action) =>
new AuthQueueMessage(identity.NetId, action).Send();
#endregion
}

View File

@ -1,30 +0,0 @@
using QSB.CampfireSync.WorldObjects;
using QSB.Events;
using QSB.WorldSync;
using QSB.WorldSync.Events;
namespace QSB.CampfireSync.Events
{
internal class CampfireStateEvent : QSBEvent<EnumWorldObjectMessage<Campfire.State>>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<int, Campfire.State>.AddListener(EventNames.QSBCampfireState, Handler);
public override void CloseListener() => GlobalMessenger<int, Campfire.State>.RemoveListener(EventNames.QSBCampfireState, Handler);
private void Handler(int objId, Campfire.State state) => SendEvent(CreateMessage(objId, state));
private EnumWorldObjectMessage<Campfire.State> CreateMessage(int objId, Campfire.State state) => new()
{
AboutId = LocalPlayerId,
ObjectId = objId,
EnumValue = state
};
public override void OnReceiveRemote(bool server, EnumWorldObjectMessage<Campfire.State> message)
{
var campfireObj = QSBWorldSync.GetWorldFromId<QSBCampfire>(message.ObjectId);
campfireObj.SetState(message.EnumValue);
}
}
}

View File

@ -0,0 +1,12 @@
using QSB.CampfireSync.WorldObjects;
using QSB.Messaging;
namespace QSB.CampfireSync.Messages
{
internal class CampfireStateMessage : QSBEnumWorldObjectMessage<QSBCampfire, Campfire.State>
{
public CampfireStateMessage(Campfire.State state) => Value = state;
public override void OnReceiveRemote() => WorldObject.SetState(Value);
}
}

View File

@ -1,6 +1,7 @@
using HarmonyLib;
using QSB.CampfireSync.Messages;
using QSB.CampfireSync.WorldObjects;
using QSB.Events;
using QSB.Messaging;
using QSB.Patches;
using QSB.WorldSync;
@ -15,7 +16,7 @@ namespace QSB.CampfireSync.Patches
[HarmonyPatch(typeof(Campfire), nameof(Campfire.OnPressInteract))]
public static bool LightCampfireEvent(Campfire __instance)
{
var qsbCampfire = QSBWorldSync.GetWorldFromUnity<QSBCampfire>(__instance);
var qsbCampfire = __instance.GetWorldObject<QSBCampfire>();
if (__instance._state == Campfire.State.LIT)
{
qsbCampfire.StartRoasting();
@ -23,7 +24,7 @@ namespace QSB.CampfireSync.Patches
else
{
qsbCampfire.SetState(Campfire.State.LIT);
QSBEventManager.FireEvent(EventNames.QSBCampfireState, qsbCampfire.ObjectId, Campfire.State.LIT);
qsbCampfire.SendMessage(new CampfireStateMessage(Campfire.State.LIT));
Locator.GetFlashlight().TurnOff(false);
}

View File

@ -1,15 +1,11 @@
using QSB.WorldSync;
using System.Reflection;
namespace QSB.CampfireSync.WorldObjects
{
public class QSBCampfire : WorldObject<Campfire>
{
public void StartRoasting()
=> AttachedObject
.GetType()
.GetMethod("StartRoasting", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(AttachedObject, null);
=> AttachedObject.StartRoasting();
public Campfire.State GetState()
=> AttachedObject.GetState();

View File

@ -1,4 +1,5 @@
using QSB.Events;
using QSB.ClientServerStateSync.Messages;
using QSB.Messaging;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.Utility;
@ -19,13 +20,17 @@ namespace QSB.ClientServerStateSync
private void Start()
{
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance != null, () => QSBEventManager.FireEvent(EventNames.QSBClientState, ForceGetCurrentState()));
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance != null,
() => new ClientStateMessage(ForceGetCurrentState()).Send());
}
public void FireChangeClientStateEvent(ClientState newState)
private void OnDestroy() =>
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
public void SendChangeClientStateMessage(ClientState newState)
{
ChangeClientState(newState);
QSBEventManager.FireEvent(EventNames.QSBClientState, newState);
new ClientStateMessage(newState).Send();
}
public void ChangeClientState(ClientState newState)
@ -137,7 +142,7 @@ namespace QSB.ClientServerStateSync
}
}
FireChangeClientStateEvent(newState);
SendChangeClientStateMessage(newState);
}
public void OnDeath()
@ -145,7 +150,7 @@ namespace QSB.ClientServerStateSync
var currentScene = QSBSceneManager.CurrentScene;
if (currentScene == OWScene.SolarSystem)
{
FireChangeClientStateEvent(ClientState.DeadInSolarSystem);
SendChangeClientStateMessage(ClientState.DeadInSolarSystem);
}
else if (currentScene == OWScene.EyeOfTheUniverse)
{
@ -164,7 +169,7 @@ namespace QSB.ClientServerStateSync
if (currentScene == OWScene.SolarSystem)
{
DebugLog.DebugWrite($"RESPAWN!");
FireChangeClientStateEvent(ClientState.AliveInSolarSystem);
SendChangeClientStateMessage(ClientState.AliveInSolarSystem);
}
else
{

View File

@ -1,41 +0,0 @@
using QSB.Events;
using QSB.Messaging;
using QSB.Player;
using QSB.Utility;
namespace QSB.ClientServerStateSync.Events
{
internal class ClientStateEvent : QSBEvent<EnumMessage<ClientState>>
{
public override bool RequireWorldObjectsReady => false;
public override void SetupListener()
=> GlobalMessenger<ClientState>.AddListener(EventNames.QSBClientState, Handler);
public override void CloseListener()
=> GlobalMessenger<ClientState>.RemoveListener(EventNames.QSBClientState, Handler);
private void Handler(ClientState state) => SendEvent(CreateMessage(state));
private EnumMessage<ClientState> CreateMessage(ClientState state) => new()
{
AboutId = LocalPlayerId,
EnumValue = state
};
public override void OnReceiveLocal(bool server, EnumMessage<ClientState> message)
=> ClientStateManager.Instance.ChangeClientState(message.EnumValue);
public override void OnReceiveRemote(bool server, EnumMessage<ClientState> message)
{
if (message.AboutId == uint.MaxValue)
{
DebugLog.ToConsole($"Error - ID is uint.MaxValue!", OWML.Common.MessageType.Error);
return;
}
var player = QSBPlayerManager.GetPlayer(message.AboutId);
player.State = message.EnumValue;
}
}
}

View File

@ -1,30 +0,0 @@
using QSB.Events;
using QSB.Messaging;
namespace QSB.ClientServerStateSync.Events
{
internal class ServerStateEvent : QSBEvent<EnumMessage<ServerState>>
{
public override bool RequireWorldObjectsReady => false;
public override void SetupListener()
=> GlobalMessenger<ServerState>.AddListener(EventNames.QSBServerState, Handler);
public override void CloseListener()
=> GlobalMessenger<ServerState>.RemoveListener(EventNames.QSBServerState, Handler);
private void Handler(ServerState state) => SendEvent(CreateMessage(state));
private EnumMessage<ServerState> CreateMessage(ServerState state) => new()
{
AboutId = LocalPlayerId,
EnumValue = state
};
public override void OnReceiveLocal(bool server, EnumMessage<ServerState> message)
=> OnReceiveRemote(server, message);
public override void OnReceiveRemote(bool server, EnumMessage<ServerState> message)
=> ServerStateManager.Instance.ChangeServerState(message.EnumValue);
}
}

View File

@ -0,0 +1,27 @@
using OWML.Common;
using QSB.Messaging;
using QSB.Player;
using QSB.Utility;
namespace QSB.ClientServerStateSync.Messages
{
internal class ClientStateMessage : QSBEnumMessage<ClientState>
{
public ClientStateMessage(ClientState state) => Value = state;
public override void OnReceiveLocal()
=> ClientStateManager.Instance.ChangeClientState(Value);
public override void OnReceiveRemote()
{
if (From == uint.MaxValue)
{
DebugLog.ToConsole($"Error - ID is uint.MaxValue!", MessageType.Error);
return;
}
var player = QSBPlayerManager.GetPlayer(From);
player.State = Value;
}
}
}

View File

@ -0,0 +1,13 @@
using QSB.Messaging;
namespace QSB.ClientServerStateSync.Messages
{
internal class ServerStateMessage : QSBEnumMessage<ServerState>
{
public ServerStateMessage(ServerState state) => Value = state;
public override void OnReceiveLocal() => OnReceiveRemote();
public override void OnReceiveRemote()
=> ServerStateManager.Instance.ChangeServerState(Value);
}
}

View File

@ -1,4 +1,6 @@
using QSB.Events;
using QSB.ClientServerStateSync.Messages;
using QSB.DeathSync.Messages;
using QSB.Messaging;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.Utility;
@ -30,13 +32,20 @@ namespace QSB.ClientServerStateSync
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
GlobalMessenger.AddListener("TriggerSupernova", OnTriggerSupernova);
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance != null, () => QSBEventManager.FireEvent(EventNames.QSBServerState, ForceGetCurrentState()));
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance != null,
() => new ServerStateMessage(ForceGetCurrentState()).Send());
}
public void FireChangeServerStateEvent(ServerState newState)
private void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
GlobalMessenger.RemoveListener("TriggerSupernova", OnTriggerSupernova);
}
public void SendChangeServerStateMessage(ServerState newState)
{
ChangeServerState(newState);
QSBEventManager.FireEvent(EventNames.QSBServerState, newState);
new ServerStateMessage(newState).Send();
}
public void ChangeServerState(ServerState newState)
@ -60,34 +69,34 @@ namespace QSB.ClientServerStateSync
case OWScene.Credits_Fast:
case OWScene.Credits_Final:
case OWScene.PostCreditsScene:
FireChangeServerStateEvent(ServerState.Credits);
SendChangeServerStateMessage(ServerState.Credits);
break;
case OWScene.TitleScreen:
FireChangeServerStateEvent(ServerState.NotLoaded);
SendChangeServerStateMessage(ServerState.NotLoaded);
break;
case OWScene.SolarSystem:
if (oldScene == OWScene.SolarSystem)
{
FireChangeServerStateEvent(ServerState.WaitingForAllPlayersToReady);
SendChangeServerStateMessage(ServerState.WaitingForAllPlayersToReady);
}
else
{
FireChangeServerStateEvent(ServerState.InSolarSystem);
SendChangeServerStateMessage(ServerState.InSolarSystem);
}
break;
case OWScene.EyeOfTheUniverse:
FireChangeServerStateEvent(ServerState.WaitingForAllPlayersToReady);
SendChangeServerStateMessage(ServerState.WaitingForAllPlayersToReady);
break;
case OWScene.None:
case OWScene.Undefined:
default:
DebugLog.ToConsole($"Warning - newScene is {newScene}!", OWML.Common.MessageType.Warning);
FireChangeServerStateEvent(ServerState.NotLoaded);
SendChangeServerStateMessage(ServerState.NotLoaded);
break;
}
}
@ -96,17 +105,24 @@ namespace QSB.ClientServerStateSync
{
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
{
FireChangeServerStateEvent(ServerState.WaitingForAllPlayersToDie);
SendChangeServerStateMessage(ServerState.WaitingForAllPlayersToDie);
}
}
private static ServerState ForceGetCurrentState()
=> QSBSceneManager.CurrentScene switch
private ServerState ForceGetCurrentState()
{
var currentScene = LoadManager.GetCurrentScene();
switch (currentScene)
{
OWScene.SolarSystem => ServerState.InSolarSystem,
OWScene.EyeOfTheUniverse => ServerState.InEye,
_ => ServerState.NotLoaded
};
case OWScene.SolarSystem:
return ServerState.InSolarSystem;
case OWScene.EyeOfTheUniverse:
return ServerState.InEye;
default:
return ServerState.NotLoaded;
}
}
private void Update()
{
@ -124,24 +140,24 @@ namespace QSB.ClientServerStateSync
if (_currentState == ServerState.WaitingForAllPlayersToReady)
{
if (QSBPlayerManager.PlayerList.All(x
=> x.State is ClientState.WaitingForOthersToBeReady
or ClientState.AliveInSolarSystem
or ClientState.AliveInEye))
=> x.State is ClientState.WaitingForOthersToBeReady
or ClientState.AliveInSolarSystem
or ClientState.AliveInEye))
{
DebugLog.DebugWrite($"All ready!!");
QSBEventManager.FireEvent(EventNames.QSBStartLoop);
new StartLoopMessage().Send();
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
{
FireChangeServerStateEvent(ServerState.InSolarSystem);
SendChangeServerStateMessage(ServerState.InSolarSystem);
}
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
{
FireChangeServerStateEvent(ServerState.InEye);
SendChangeServerStateMessage(ServerState.InEye);
}
else
{
DebugLog.ToConsole($"Error - All players were ready in non-universe scene!?", OWML.Common.MessageType.Error);
FireChangeServerStateEvent(ServerState.NotLoaded);
SendChangeServerStateMessage(ServerState.NotLoaded);
}
_blockNextCheck = true;

View File

@ -1,6 +1,7 @@
using OWML.Common;
using QSB.ConversationSync.Messages;
using QSB.ConversationSync.WorldObjects;
using QSB.Events;
using QSB.Messaging;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
@ -48,7 +49,7 @@ namespace QSB.ConversationSync
}
public void SendPlayerOption(string text) =>
QSBEventManager.FireEvent(EventNames.QSBConversation, QSBPlayerManager.LocalPlayerId, text, ConversationType.Player);
new ConversationMessage(ConversationType.Player, (int)QSBPlayerManager.LocalPlayerId, text).Send();
public void SendCharacterDialogue(int id, string text)
{
@ -58,14 +59,14 @@ namespace QSB.ConversationSync
return;
}
QSBEventManager.FireEvent(EventNames.QSBConversation, (uint)id, text, ConversationType.Character);
new ConversationMessage(ConversationType.Character, id, text).Send();
}
public void CloseBoxPlayer() =>
QSBEventManager.FireEvent(EventNames.QSBConversation, QSBPlayerManager.LocalPlayerId, "", ConversationType.ClosePlayer);
new ConversationMessage(ConversationType.ClosePlayer, (int)QSBPlayerManager.LocalPlayerId).Send();
public void CloseBoxCharacter(int id) =>
QSBEventManager.FireEvent(EventNames.QSBConversation, (uint)id, "", ConversationType.CloseCharacter);
new ConversationMessage(ConversationType.CloseCharacter, id).Send();
public void SendConvState(int charId, bool state)
{
@ -75,7 +76,7 @@ namespace QSB.ConversationSync
return;
}
QSBEventManager.FireEvent(EventNames.QSBConversationStartEnd, charId, QSBPlayerManager.LocalPlayerId, state);
new ConversationStartEndMessage(charId, QSBPlayerManager.LocalPlayerId, state).Send();
}
public void DisplayPlayerConversationBox(uint playerId, string text)

View File

@ -1,55 +0,0 @@
using QSB.Events;
using QSB.Player;
using QSB.WorldSync;
using System.Text.RegularExpressions;
namespace QSB.ConversationSync.Events
{
public class ConversationEvent : QSBEvent<ConversationMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<uint, string, ConversationType>.AddListener(EventNames.QSBConversation, Handler);
public override void CloseListener() => GlobalMessenger<uint, string, ConversationType>.RemoveListener(EventNames.QSBConversation, Handler);
private void Handler(uint id, string message, ConversationType type) => SendEvent(CreateMessage(id, message, type));
private ConversationMessage CreateMessage(uint id, string message, ConversationType type) => new()
{
AboutId = LocalPlayerId,
ObjectId = (int)id,
EnumValue = type,
Message = message
};
public override void OnReceiveRemote(bool server, ConversationMessage message)
{
switch (message.EnumValue)
{
case ConversationType.Character:
var translated = TextTranslation.Translate(message.Message).Trim();
translated = Regex.Replace(translated, @"<[Pp]ause=?\d*\.?\d*\s?\/?>", "");
ConversationManager.Instance.DisplayCharacterConversationBox(message.ObjectId, translated);
break;
case ConversationType.Player:
ConversationManager.Instance.DisplayPlayerConversationBox((uint)message.ObjectId, message.Message);
break;
case ConversationType.CloseCharacter:
if (message.ObjectId == -1)
{
break;
}
var tree = QSBWorldSync.OldDialogueTrees[message.ObjectId];
UnityEngine.Object.Destroy(ConversationManager.Instance.BoxMappings[tree]);
break;
case ConversationType.ClosePlayer:
UnityEngine.Object.Destroy(QSBPlayerManager.GetPlayer((uint)message.ObjectId).CurrentDialogueBox);
break;
}
}
}
}

View File

@ -1,22 +0,0 @@
using QSB.WorldSync.Events;
using QuantumUNET.Transport;
namespace QSB.ConversationSync.Events
{
public class ConversationMessage : EnumWorldObjectMessage<ConversationType>
{
public string Message { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
Message = reader.ReadString();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(Message);
}
}
}

View File

@ -1,63 +0,0 @@
using OWML.Common;
using QSB.Events;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
namespace QSB.ConversationSync.Events
{
public class ConversationStartEndEvent : QSBEvent<ConversationStartEndMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<int, uint, bool>.AddListener(EventNames.QSBConversationStartEnd, Handler);
public override void CloseListener() => GlobalMessenger<int, uint, bool>.RemoveListener(EventNames.QSBConversationStartEnd, Handler);
private void Handler(int objId, uint playerId, bool state) => SendEvent(CreateMessage(objId, playerId, state));
private ConversationStartEndMessage CreateMessage(int objId, uint playerId, bool state) => new()
{
AboutId = LocalPlayerId,
TreeId = objId,
PlayerId = playerId,
State = state
};
public override void OnReceiveRemote(bool server, ConversationStartEndMessage message)
{
if (message.TreeId == -1)
{
DebugLog.ToConsole("Warning - Received conv. start/end event with char id -1.", MessageType.Warning);
return;
}
var dialogueTree = QSBWorldSync.OldDialogueTrees[message.TreeId];
if (message.State)
{
StartConversation(message.PlayerId, message.TreeId, dialogueTree);
}
else
{
EndConversation(message.PlayerId, dialogueTree);
}
}
private void StartConversation(
uint playerId,
int dialogueTreeId,
CharacterDialogueTree tree)
{
QSBPlayerManager.GetPlayer(playerId).CurrentCharacterDialogueTreeId = dialogueTreeId;
tree.GetInteractVolume().DisableInteraction();
}
private void EndConversation(
uint playerId,
CharacterDialogueTree tree)
{
QSBPlayerManager.GetPlayer(playerId).CurrentCharacterDialogueTreeId = -1;
tree.GetInteractVolume().EnableInteraction();
}
}
}

View File

@ -1,28 +0,0 @@
using QSB.Messaging;
using QuantumUNET.Transport;
namespace QSB.ConversationSync.Events
{
public class ConversationStartEndMessage : PlayerMessage
{
public int TreeId { get; set; }
public uint PlayerId { get; set; }
public bool State { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
TreeId = reader.ReadInt32();
PlayerId = reader.ReadUInt32();
State = reader.ReadBoolean();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(TreeId);
writer.Write(PlayerId);
writer.Write(State);
}
}
}

View File

@ -1,40 +0,0 @@
using QSB.Events;
using QSB.WorldSync;
namespace QSB.ConversationSync.Events
{
public class DialogueConditionEvent : QSBEvent<DialogueConditionMessage>
{
public override bool RequireWorldObjectsReady => false;
public override void SetupListener() => GlobalMessenger<string, bool>.AddListener(EventNames.DialogueConditionChanged, Handler);
public override void CloseListener() => GlobalMessenger<string, bool>.RemoveListener(EventNames.DialogueConditionChanged, Handler);
private void Handler(string name, bool state) => SendEvent(CreateMessage(name, state));
private DialogueConditionMessage CreateMessage(string name, bool state) => new()
{
AboutId = LocalPlayerId,
ConditionName = name,
ConditionState = state
};
public override void OnReceiveLocal(bool server, DialogueConditionMessage message)
{
if (server)
{
QSBWorldSync.SetDialogueCondition(message.ConditionName, message.ConditionState);
}
}
public override void OnReceiveRemote(bool server, DialogueConditionMessage message)
{
if (server)
{
QSBWorldSync.SetDialogueCondition(message.ConditionName, message.ConditionState);
}
DialogueConditionManager.SharedInstance.SetConditionState(message.ConditionName, message.ConditionState);
}
}
}

View File

@ -1,25 +0,0 @@
using QSB.Messaging;
using QuantumUNET.Transport;
namespace QSB.ConversationSync.Events
{
public class DialogueConditionMessage : PlayerMessage
{
public string ConditionName { get; set; }
public bool ConditionState { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
ConditionName = reader.ReadString();
ConditionState = reader.ReadBoolean();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(ConditionName);
writer.Write(ConditionState);
}
}
}

View File

@ -1,35 +0,0 @@
using QSB.ConversationSync.WorldObjects;
using QSB.Events;
using QSB.WorldSync;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QSB.ConversationSync.Events
{
internal class EnterRemoteDialogueEvent : QSBEvent<EnterRemoteDialogueMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<QSBRemoteDialogueTrigger, int, int>.AddListener(EventNames.QSBEnterRemoteDialogue, Handler);
public override void CloseListener() => GlobalMessenger<QSBRemoteDialogueTrigger, int, int>.RemoveListener(EventNames.QSBEnterRemoteDialogue, Handler);
private void Handler(QSBRemoteDialogueTrigger remoteTrigger, int activatedIndex, int listIndex) => SendEvent(CreateMessage(remoteTrigger, activatedIndex, listIndex));
private EnterRemoteDialogueMessage CreateMessage(QSBRemoteDialogueTrigger remoteTrigger, int activatedIndex, int listIndex) => new()
{
AboutId = LocalPlayerId,
ObjectId = remoteTrigger.ObjectId,
ActivatedDialogueIndex = activatedIndex,
ListDialoguesIndex = listIndex
};
public override void OnReceiveRemote(bool isHost, EnterRemoteDialogueMessage message)
{
var qsbObj = QSBWorldSync.GetWorldFromId<QSBRemoteDialogueTrigger>(message.ObjectId);
qsbObj.RemoteEnterDialogue(message.ActivatedDialogueIndex, message.ListDialoguesIndex);
}
}
}

View File

@ -1,25 +0,0 @@
using QSB.WorldSync.Events;
using QuantumUNET.Transport;
namespace QSB.ConversationSync.Events
{
public class EnterRemoteDialogueMessage : WorldObjectMessage
{
public int ActivatedDialogueIndex { get; set; }
public int ListDialoguesIndex { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
ActivatedDialogueIndex = reader.ReadInt32();
ListDialoguesIndex = reader.ReadInt32();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(ActivatedDialogueIndex);
writer.Write(ListDialoguesIndex);
}
}
}

View File

@ -0,0 +1,68 @@
using QSB.Messaging;
using QSB.Player;
using QSB.WorldSync;
using QuantumUNET.Transport;
using System.Text.RegularExpressions;
using UnityEngine;
namespace QSB.ConversationSync.Messages
{
public class ConversationMessage : QSBEnumMessage<ConversationType>
{
private int Id;
private string Message;
public ConversationMessage(ConversationType type, int id, string message = "")
{
Value = type;
Id = id;
Message = message;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(Id);
writer.Write(Message);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
Id = reader.ReadInt32();
Message = reader.ReadString();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
switch (Value)
{
case ConversationType.Character:
var translated = TextTranslation.Translate(Message).Trim();
translated = Regex.Replace(translated, @"<[Pp]ause=?\d*\.?\d*\s?\/?>", "");
ConversationManager.Instance.DisplayCharacterConversationBox(Id, translated);
break;
case ConversationType.Player:
ConversationManager.Instance.DisplayPlayerConversationBox((uint)Id, Message);
break;
case ConversationType.CloseCharacter:
if (Id == -1)
{
break;
}
var tree = QSBWorldSync.OldDialogueTrees[Id];
Object.Destroy(ConversationManager.Instance.BoxMappings[tree]);
break;
case ConversationType.ClosePlayer:
Object.Destroy(QSBPlayerManager.GetPlayer((uint)Id).CurrentDialogueBox);
break;
}
}
}
}

View File

@ -0,0 +1,77 @@
using OWML.Common;
using QSB.Messaging;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using QuantumUNET.Transport;
namespace QSB.ConversationSync.Messages
{
public class ConversationStartEndMessage : QSBBoolMessage
{
private int TreeId;
private uint PlayerId;
public ConversationStartEndMessage(int treeId, uint playerId, bool start)
{
TreeId = treeId;
PlayerId = playerId;
Value = start;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(TreeId);
writer.Write(PlayerId);
writer.Write(Value);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
TreeId = reader.ReadInt32();
PlayerId = reader.ReadUInt32();
Value = reader.ReadBoolean();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
if (TreeId == -1)
{
DebugLog.ToConsole("Warning - Received conv. start/end event with char id -1.", MessageType.Warning);
return;
}
var dialogueTree = QSBWorldSync.OldDialogueTrees[TreeId];
if (Value)
{
StartConversation(PlayerId, TreeId, dialogueTree);
}
else
{
EndConversation(PlayerId, dialogueTree);
}
}
private static void StartConversation(
uint playerId,
int treeId,
CharacterDialogueTree tree)
{
QSBPlayerManager.GetPlayer(playerId).CurrentCharacterDialogueTreeId = treeId;
tree.GetInteractVolume().DisableInteraction();
}
private static void EndConversation(
uint playerId,
CharacterDialogueTree tree)
{
QSBPlayerManager.GetPlayer(playerId).CurrentCharacterDialogueTreeId = -1;
tree.GetInteractVolume().EnableInteraction();
}
}
}

View File

@ -0,0 +1,61 @@
using QSB.Messaging;
using QSB.Player.TransformSync;
using QSB.WorldSync;
using QuantumUNET.Transport;
namespace QSB.ConversationSync.Messages
{
public class DialogueConditionMessage : QSBMessage
{
static DialogueConditionMessage() => GlobalMessenger<string, bool>.AddListener(OWEvents.DialogueConditionChanged, Handler);
private static void Handler(string name, bool state)
{
if (PlayerTransformSync.LocalInstance)
{
new DialogueConditionMessage(name, state).Send();
}
}
private string ConditionName;
private bool ConditionState;
public DialogueConditionMessage(string name, bool state)
{
ConditionName = name;
ConditionState = state;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(ConditionName);
writer.Write(ConditionState);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
ConditionName = reader.ReadString();
ConditionState = reader.ReadBoolean();
}
public override void OnReceiveRemote()
{
if (QSBCore.IsHost)
{
QSBWorldSync.SetDialogueCondition(ConditionName, ConditionState);
}
DialogueConditionManager.SharedInstance.SetConditionState(ConditionName, ConditionState);
}
public override void OnReceiveLocal()
{
if (QSBCore.IsHost)
{
QSBWorldSync.SetDialogueCondition(ConditionName, ConditionState);
}
}
}
}

View File

@ -0,0 +1,35 @@
using QSB.ConversationSync.WorldObjects;
using QSB.Messaging;
using QuantumUNET.Transport;
namespace QSB.ConversationSync.Messages
{
internal class EnterRemoteDialogueMessage : QSBWorldObjectMessage<QSBRemoteDialogueTrigger>
{
private int ActivatedDialogueIndex;
private int ListDialoguesIndex;
public EnterRemoteDialogueMessage(int activatedIndex, int listIndex)
{
ActivatedDialogueIndex = activatedIndex;
ListDialoguesIndex = listIndex;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(ActivatedDialogueIndex);
writer.Write(ListDialoguesIndex);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
ActivatedDialogueIndex = reader.ReadInt32();
ListDialoguesIndex = reader.ReadInt32();
}
public override void OnReceiveRemote()
=> WorldObject.RemoteEnterDialogue(ActivatedDialogueIndex, ListDialoguesIndex);
}
}

View File

@ -1,13 +1,12 @@
using HarmonyLib;
using OWML.Common;
using QSB.ConversationSync.Messages;
using QSB.ConversationSync.WorldObjects;
using QSB.Events;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using System.Collections.Generic;
using UnityEngine;
namespace QSB.ConversationSync.Patches
{
@ -54,7 +53,7 @@ namespace QSB.ConversationSync.Patches
[HarmonyPrefix]
[HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.InputDialogueOption))]
public static bool CharacterDialogueTree_InputDialogueOption(int optionIndex, DialogueBoxVer2 ____currentDialogueBox)
public static bool CharacterDialogueTree_InputDialogueOption(CharacterDialogueTree __instance, int optionIndex)
{
if (optionIndex < 0)
{
@ -63,16 +62,16 @@ namespace QSB.ConversationSync.Patches
return true;
}
var selectedOption = ____currentDialogueBox.OptionFromUIIndex(optionIndex);
var selectedOption = __instance._currentDialogueBox.OptionFromUIIndex(optionIndex);
ConversationManager.Instance.SendPlayerOption(selectedOption.Text);
return true;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(DialogueNode), nameof(DialogueNode.GetNextPage))]
public static void DialogueNode_GetNextPage(string ____name, List<string> ____listPagesToDisplay, int ____currentPage)
public static void DialogueNode_GetNextPage(DialogueNode __instance)
{
var key = ____name + ____listPagesToDisplay[____currentPage];
var key = __instance._name + __instance._listPagesToDisplay[__instance._currentPage];
// Sending key so translation can be done on client side - should make different language-d clients compatible
QSBCore.UnityEvents.RunWhen(() => QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId != -1,
() => ConversationManager.Instance.SendCharacterDialogue(QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId, key));
@ -139,10 +138,8 @@ namespace QSB.ConversationSync.Patches
__instance._activatedDialogues[num] = true;
QSBEventManager.FireEvent(EventNames.QSBEnterRemoteDialogue,
QSBWorldSync.GetWorldFromUnity<QSBRemoteDialogueTrigger>(__instance),
num,
__instance._listDialogues.IndexOf(dialogue));
__instance.GetWorldObject<QSBRemoteDialogueTrigger>()
.SendMessage(new EnterRemoteDialogueMessage(num, __instance._listDialogues.IndexOf(dialogue)));
__result = true;
return false;

View File

@ -1,5 +1,4 @@
using QSB.Utility;
using QSB.WorldSync;
using QSB.WorldSync;
namespace QSB.ConversationSync.WorldObjects
{

View File

@ -1,7 +0,0 @@
namespace QSB.DeathSync
{
public enum EndLoopReason
{
AllPlayersDead = 0
}
}

View File

@ -1,50 +0,0 @@
using QSB.ClientServerStateSync;
using QSB.Events;
using QSB.Messaging;
using QSB.Patches;
using QSB.Utility;
namespace QSB.DeathSync.Events
{
internal class EndLoopEvent : QSBEvent<EnumMessage<EndLoopReason>>
{
public override bool RequireWorldObjectsReady => false;
public override void SetupListener() => GlobalMessenger<EndLoopReason>.AddListener(EventNames.QSBEndLoop, Handler);
public override void CloseListener() => GlobalMessenger<EndLoopReason>.RemoveListener(EventNames.QSBEndLoop, Handler);
private void Handler(EndLoopReason type) => SendEvent(CreateMessage(type));
private EnumMessage<EndLoopReason> CreateMessage(EndLoopReason type) => new()
{
AboutId = LocalPlayerId,
EnumValue = type
};
public override void OnReceiveLocal(bool server, EnumMessage<EndLoopReason> message)
=> OnReceiveRemote(server, message);
public override void OnReceiveRemote(bool server, EnumMessage<EndLoopReason> message)
{
DebugLog.DebugWrite($" ~~~~ END LOOP - Reason:{message.EnumValue} ~~~~ ");
switch (message.EnumValue)
{
case EndLoopReason.AllPlayersDead:
if (ServerStateManager.Instance.GetServerState() == ServerState.WaitingForAllPlayersToDie)
{
break;
}
QSBPatchManager.DoUnpatchType(QSBPatchTypes.RespawnTime);
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
if (QSBCore.IsHost)
{
ServerStateManager.Instance.FireChangeServerStateEvent(ServerState.WaitingForAllPlayersToDie);
}
break;
}
}
}
}

View File

@ -1,45 +0,0 @@
using QSB.ClientServerStateSync;
using QSB.Events;
using QSB.Player;
using QSB.RespawnSync;
using QSB.Utility;
namespace QSB.DeathSync.Events
{
public class PlayerDeathEvent : QSBEvent<PlayerDeathMessage>
{
public override bool RequireWorldObjectsReady => false;
public override void SetupListener() => GlobalMessenger<DeathType>.AddListener(EventNames.QSBPlayerDeath, Handler);
public override void CloseListener() => GlobalMessenger<DeathType>.RemoveListener(EventNames.QSBPlayerDeath, Handler);
private void Handler(DeathType type) => SendEvent(CreateMessage(type));
private PlayerDeathMessage CreateMessage(DeathType type) => new()
{
AboutId = LocalPlayerId,
EnumValue = type,
NecronomiconIndex = Necronomicon.GetRandomIndex(type)
};
public override void OnReceiveLocal(bool server, PlayerDeathMessage message)
{
var player = QSBPlayerManager.GetPlayer(message.AboutId);
RespawnManager.Instance.OnPlayerDeath(player);
ClientStateManager.Instance.OnDeath();
}
public override void OnReceiveRemote(bool server, PlayerDeathMessage message)
{
var player = QSBPlayerManager.GetPlayer(message.AboutId);
var playerName = player.Name;
var deathMessage = Necronomicon.GetPhrase(message.EnumValue, message.NecronomiconIndex);
if (deathMessage != string.Empty)
{
DebugLog.ToAll(string.Format(deathMessage, playerName));
}
RespawnManager.Instance.OnPlayerDeath(player);
}
}
}

View File

@ -1,24 +0,0 @@
using QSB.Messaging;
using QuantumUNET.Transport;
namespace QSB.DeathSync.Events
{
public class PlayerDeathMessage : EnumMessage<DeathType>
{
public int NecronomiconIndex { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
EnumValue = (DeathType)reader.ReadInt32();
NecronomiconIndex = reader.ReadInt32();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write((int)EnumValue);
writer.Write(NecronomiconIndex);
}
}
}

View File

@ -1,43 +0,0 @@
using QSB.ClientServerStateSync;
using QSB.Events;
using QSB.Messaging;
using QSB.Utility;
namespace QSB.DeathSync.Events
{
internal class StartLoopEvent : QSBEvent<PlayerMessage>
{
public override bool RequireWorldObjectsReady => false;
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBStartLoop, Handler);
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBStartLoop, Handler);
private void Handler() => SendEvent(CreateMessage());
private PlayerMessage CreateMessage() => new()
{
AboutId = LocalPlayerId
};
public override void OnReceiveLocal(bool server, PlayerMessage message)
=> OnReceiveRemote(server, message);
public override void OnReceiveRemote(bool server, PlayerMessage message)
{
DebugLog.DebugWrite($" ~~~ LOOP START ~~~");
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
{
ClientStateManager.Instance.FireChangeClientStateEvent(ClientState.AliveInSolarSystem);
}
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
{
ClientStateManager.Instance.FireChangeClientStateEvent(ClientState.AliveInEye);
}
else
{
DebugLog.ToConsole($"Error - Got StartLoop event when not in universe!", OWML.Common.MessageType.Error);
ClientStateManager.Instance.FireChangeClientStateEvent(ClientState.NotLoaded);
}
}
}
}

View File

@ -0,0 +1,30 @@
using QSB.ClientServerStateSync;
using QSB.Messaging;
using QSB.Patches;
using QSB.Utility;
namespace QSB.DeathSync.Messages
{
// when all players die
internal class EndLoopMessage : QSBMessage
{
public override void OnReceiveLocal() => OnReceiveRemote();
public override void OnReceiveRemote()
{
DebugLog.DebugWrite($" ~~~~ END LOOP - all players are dead ~~~~ ");
if (ServerStateManager.Instance.GetServerState() == ServerState.WaitingForAllPlayersToDie)
{
return;
}
QSBPatchManager.DoUnpatchType(QSBPatchTypes.RespawnTime);
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
if (QSBCore.IsHost)
{
ServerStateManager.Instance.SendChangeServerStateMessage(ServerState.WaitingForAllPlayersToDie);
}
}
}
}

View File

@ -0,0 +1,48 @@
using QSB.ClientServerStateSync;
using QSB.Messaging;
using QSB.Player;
using QSB.RespawnSync;
using QSB.Utility;
using QuantumUNET.Transport;
namespace QSB.DeathSync.Messages
{
public class PlayerDeathMessage : QSBEnumMessage<DeathType>
{
private int NecronomiconIndex;
public PlayerDeathMessage(DeathType type) => NecronomiconIndex = Necronomicon.GetRandomIndex(type);
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(NecronomiconIndex);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
NecronomiconIndex = reader.ReadInt32();
}
public override void OnReceiveLocal()
{
var player = QSBPlayerManager.GetPlayer(From);
RespawnManager.Instance.OnPlayerDeath(player);
ClientStateManager.Instance.OnDeath();
}
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);
var playerName = player.Name;
var deathMessage = Necronomicon.GetPhrase(Value, NecronomiconIndex);
if (deathMessage != string.Empty)
{
DebugLog.ToAll(string.Format(deathMessage, playerName));
}
RespawnManager.Instance.OnPlayerDeath(player);
}
}
}

View File

@ -0,0 +1,30 @@
using OWML.Common;
using QSB.ClientServerStateSync;
using QSB.Messaging;
using QSB.Utility;
namespace QSB.DeathSync.Messages
{
internal class StartLoopMessage : QSBMessage
{
public override void OnReceiveLocal() => OnReceiveRemote();
public override void OnReceiveRemote()
{
DebugLog.DebugWrite($" ~~~ LOOP START ~~~");
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
{
ClientStateManager.Instance.SendChangeClientStateMessage(ClientState.AliveInSolarSystem);
}
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
{
ClientStateManager.Instance.SendChangeClientStateMessage(ClientState.AliveInEye);
}
else
{
DebugLog.ToConsole($"Error - Got StartLoop event when not in universe!", MessageType.Error);
ClientStateManager.Instance.SendChangeClientStateMessage(ClientState.NotLoaded);
}
}
}
}

View File

@ -1,5 +1,6 @@
using HarmonyLib;
using QSB.Events;
using QSB.DeathSync.Messages;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using QSB.ShipSync;
@ -40,7 +41,7 @@ namespace QSB.DeathSync.Patches
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerResources), nameof(PlayerResources.OnImpact))]
public static bool PlayerResources_OnImpact(ImpactData impact, PlayerResources __instance, float ____currentHealth)
public static bool PlayerResources_OnImpact(PlayerResources __instance, ImpactData impact)
{
if (PlayerState.IsInsideShip())
{
@ -49,7 +50,7 @@ namespace QSB.DeathSync.Patches
var speed = Mathf.Clamp01((impact.speed - __instance.GetMinImpactSpeed()) / (__instance.GetMaxImpactSpeed() - __instance.GetMinImpactSpeed()));
var tookDamage = __instance.ApplyInstantDamage(100f * speed, InstantDamageType.Impact);
if (tookDamage && ____currentHealth <= 0f && !PlayerState.IsDead())
if (tookDamage && __instance._currentHealth <= 0f && !PlayerState.IsDead())
{
Locator.GetDeathManager().SetImpactDeathSpeed(impact.speed);
Locator.GetDeathManager().KillPlayer(DeathType.Impact);
@ -61,73 +62,63 @@ namespace QSB.DeathSync.Patches
[HarmonyPrefix]
[HarmonyPatch(typeof(HighSpeedImpactSensor), nameof(HighSpeedImpactSensor.FixedUpdate))]
public static bool HighSpeedImpactSensor_FixedUpdate(
HighSpeedImpactSensor __instance,
bool ____isPlayer,
ref bool ____dead,
ref bool ____dieNextUpdate,
OWRigidbody ____body,
ref float ____impactSpeed,
float ____sqrCheckSpeedThreshold,
RaycastHit[] ____raycastHits,
SectorDetector ____sectorDetector,
float ____radius,
Vector3 ____localOffset
HighSpeedImpactSensor __instance
)
{
if (____isPlayer && (PlayerState.IsAttached() || PlayerState.IsInsideShuttle() || PlayerState.UsingNomaiRemoteCamera()))
if (__instance._isPlayer && (PlayerState.IsAttached() || PlayerState.IsInsideShuttle() || PlayerState.UsingNomaiRemoteCamera()))
{
return false;
}
if (____dieNextUpdate && !____dead)
if (__instance._dieNextUpdate && !__instance._dead)
{
____dead = true;
____dieNextUpdate = false;
__instance._dead = true;
__instance._dieNextUpdate = false;
if (__instance.gameObject.CompareTag("Player"))
{
Locator.GetDeathManager().SetImpactDeathSpeed(____impactSpeed);
Locator.GetDeathManager().SetImpactDeathSpeed(__instance._impactSpeed);
Locator.GetDeathManager().KillPlayer(DeathType.Impact);
}
else if (__instance.gameObject.CompareTag("Ship"))
{
__instance.GetComponent<ShipDamageController>().Explode(false);
__instance.GetComponent<ShipDamageController>().Explode();
}
}
if (____isPlayer && PlayerState.IsInsideShip())
if (__instance._isPlayer && PlayerState.IsInsideShip())
{
var shipCenter = Locator.GetShipTransform().position + (Locator.GetShipTransform().up * 2f);
var distanceFromShip = Vector3.Distance(____body.GetPosition(), shipCenter);
var distanceFromShip = Vector3.Distance(__instance._body.GetPosition(), shipCenter);
if (distanceFromShip > 8f)
{
____body.SetPosition(shipCenter);
__instance._body.SetPosition(shipCenter);
}
if (!____dead)
if (!__instance._dead)
{
var a = ____body.GetVelocity() - Locator.GetShipBody().GetPointVelocity(____body.GetPosition());
if (a.sqrMagnitude > ____sqrCheckSpeedThreshold)
var a = __instance._body.GetVelocity() - Locator.GetShipBody().GetPointVelocity(__instance._body.GetPosition());
if (a.sqrMagnitude > __instance._sqrCheckSpeedThreshold)
{
____impactSpeed = a.magnitude;
____body.AddVelocityChange(-a);
__instance._impactSpeed = a.magnitude;
__instance._body.AddVelocityChange(-a);
}
}
return false;
}
var passiveReferenceFrame = ____sectorDetector.GetPassiveReferenceFrame();
if (!____dead && passiveReferenceFrame != null)
var passiveReferenceFrame = __instance._sectorDetector.GetPassiveReferenceFrame();
if (!__instance._dead && passiveReferenceFrame != null)
{
var relativeVelocity = ____body.GetVelocity() - passiveReferenceFrame.GetOWRigidBody().GetPointVelocity(____body.GetPosition());
if (relativeVelocity.sqrMagnitude > ____sqrCheckSpeedThreshold)
var relativeVelocity = __instance._body.GetVelocity() - passiveReferenceFrame.GetOWRigidBody().GetPointVelocity(__instance._body.GetPosition());
if (relativeVelocity.sqrMagnitude > __instance._sqrCheckSpeedThreshold)
{
var hitCount = Physics.RaycastNonAlloc(__instance.transform.TransformPoint(____localOffset), relativeVelocity, ____raycastHits, (relativeVelocity.magnitude * Time.deltaTime) + ____radius, OWLayerMask.physicalMask, QueryTriggerInteraction.Ignore);
var hitCount = Physics.RaycastNonAlloc(__instance.transform.TransformPoint(__instance._localOffset), relativeVelocity, __instance._raycastHits, (relativeVelocity.magnitude * Time.deltaTime) + __instance._radius, OWLayerMask.physicalMask, QueryTriggerInteraction.Ignore);
for (var i = 0; i < hitCount; i++)
{
if (____raycastHits[i].rigidbody.mass > 10f && !____raycastHits[i].rigidbody.Equals(____body.GetRigidbody()))
if (__instance._raycastHits[i].rigidbody.mass > 10f && !__instance._raycastHits[i].rigidbody.Equals(__instance._body.GetRigidbody()))
{
var owRigidbody = ____raycastHits[i].rigidbody.GetComponent<OWRigidbody>();
var owRigidbody = __instance._raycastHits[i].rigidbody.GetComponent<OWRigidbody>();
if (owRigidbody == null)
{
DebugLog.ToConsole("Rigidbody does not have attached OWRigidbody!!!", OWML.Common.MessageType.Error);
@ -135,15 +126,15 @@ namespace QSB.DeathSync.Patches
}
else
{
relativeVelocity = ____body.GetVelocity() - owRigidbody.GetPointVelocity(____body.GetPosition());
var a2 = Vector3.Project(relativeVelocity, ____raycastHits[i].normal);
if (a2.sqrMagnitude > ____sqrCheckSpeedThreshold)
relativeVelocity = __instance._body.GetVelocity() - owRigidbody.GetPointVelocity(__instance._body.GetPosition());
var a2 = Vector3.Project(relativeVelocity, __instance._raycastHits[i].normal);
if (a2.sqrMagnitude > __instance._sqrCheckSpeedThreshold)
{
____body.AddVelocityChange(-a2);
____impactSpeed = a2.magnitude;
__instance._body.AddVelocityChange(-a2);
__instance._impactSpeed = a2.magnitude;
if (!PlayerState.IsInsideTheEye())
{
____dieNextUpdate = true;
__instance._dieNextUpdate = true;
}
break;
@ -180,7 +171,7 @@ namespace QSB.DeathSync.Patches
if (deadPlayersCount == QSBPlayerManager.PlayerList.Count - 1)
{
QSBEventManager.FireEvent(EventNames.QSBEndLoop, EndLoopReason.AllPlayersDead);
new EndLoopMessage().Send();
return true;
}
@ -195,18 +186,18 @@ namespace QSB.DeathSync.Patches
if (!QSBPlayerManager.LocalPlayer.IsDead)
{
QSBPlayerManager.LocalPlayer.IsDead = true;
QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
new PlayerDeathMessage(deathType).Send();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ShipDamageController), nameof(ShipDamageController.Awake))]
public static void ShipDamageController_Awake(ref bool ____exploded)
=> ____exploded = true;
public static void ShipDamageController_Awake(ShipDamageController __instance)
=> __instance._exploded = true;
[HarmonyPrefix]
[HarmonyPatch(typeof(DestructionVolume), nameof(DestructionVolume.VanishShip))]
public static bool DestructionVolume_VanishShip(DeathType ____deathType)
public static bool DestructionVolume_VanishShip(DestructionVolume __instance)
{
if (RespawnOnDeath.Instance == null)
{
@ -220,7 +211,7 @@ namespace QSB.DeathSync.Patches
if (PlayerState.IsInsideShip() || PlayerState.UsingShipComputer() || PlayerState.AtFlightConsole())
{
Locator.GetDeathManager().KillPlayer(____deathType);
Locator.GetDeathManager().KillPlayer(__instance._deathType);
}
return true;

View File

@ -12,151 +12,86 @@ namespace QSB.DeathSync.Patches
[HarmonyPrefix]
[HarmonyPatch(typeof(MapController), nameof(MapController.EnterMapView))]
public static bool MapController_EnterMapView(
MapController __instance,
ref bool ____isMapMode,
OWAudioSource ____audioSource,
MapMarkerManager ____mapMarkerManager,
OWCamera ____mapCamera,
OWCamera ____activeCam,
MeshRenderer ____gridRenderer,
ref Transform ____targetTransform,
ref bool ____lockedToTargetTransform,
ref Vector3 ____position,
ref float ____yaw,
ref float ____pitch,
ref float ____zoom,
ref float ____targetZoom,
ref bool ____interpPosition,
ref bool ____interpPitch,
ref bool ____interpZoom,
ref bool ____framingPlayer,
ref float ____lockTimer,
float ____defaultYawAngle,
float ____initialPitchAngle,
float ____initialZoomDist,
float ____defaultZoomDist,
float ____lockOnMoveLength,
ref float ____gridOverrideSize,
ref bool ____gridOverride,
ref float ____gridTimer,
ref float ____revealLength,
ReferenceFrame ____currentRFrame,
float ____gridLockOnLength,
ref float ____revealTimer
MapController __instance
)
{
if (____isMapMode)
if (__instance._isMapMode)
{
return false;
}
____mapMarkerManager.SetVisible(true);
__instance._mapMarkerManager.SetVisible(true);
GlobalMessenger.FireEvent("EnterMapView");
GlobalMessenger<OWCamera>.FireEvent("SwitchActiveCamera", ____mapCamera);
if (____audioSource.isPlaying)
GlobalMessenger<OWCamera>.FireEvent("SwitchActiveCamera", __instance._mapCamera);
if (__instance._audioSource.isPlaying)
{
____audioSource.Stop();
____audioSource.SetLocalVolume(1f);
____audioSource.Play();
__instance._audioSource.Stop();
__instance._audioSource.SetLocalVolume(1f);
__instance._audioSource.Play();
}
else
{
____audioSource.SetLocalVolume(1f);
____audioSource.Play();
__instance._audioSource.SetLocalVolume(1f);
__instance._audioSource.Play();
}
Locator.GetAudioMixer().MixMap();
____activeCam.enabled = false;
____mapCamera.enabled = true;
____gridRenderer.enabled = false;
____targetTransform = null;
____lockedToTargetTransform = false;
____position = RespawnOnDeath.Instance.DeathPositionWorld - Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition();
____position.y = 0f;
____yaw = ____defaultYawAngle;
____pitch = ____initialPitchAngle;
____zoom = ____initialZoomDist;
____targetZoom = ____defaultZoomDist;
__instance._activeCam.enabled = false;
__instance._mapCamera.enabled = true;
__instance._gridRenderer.enabled = false;
__instance._targetTransform = null;
__instance._lockedToTargetTransform = false;
__instance._position = RespawnOnDeath.Instance.DeathPositionWorld - Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition();
__instance._position.y = 0f;
__instance._yaw = __instance._defaultYawAngle;
__instance._pitch = __instance._initialPitchAngle;
__instance._zoom = __instance._initialZoomDist;
__instance._targetZoom = __instance._defaultZoomDist;
__instance.transform.rotation = Quaternion.LookRotation(-RespawnOnDeath.Instance.DeathPlayerUpVector, RespawnOnDeath.Instance.DeathPlayerForwardVector);
__instance.transform.position = RespawnOnDeath.Instance.DeathPositionWorld;
____interpPosition = true;
____interpPitch = true;
____interpZoom = true;
____framingPlayer = ____lockedToTargetTransform;
____lockTimer = ____lockOnMoveLength;
____gridOverrideSize = (____currentRFrame == null) ? 0f : ____currentRFrame.GetAutopilotArrivalDistance();
____gridOverride = ____gridOverrideSize > 0f;
____gridTimer = (!____gridOverride) ? 0f : ____gridLockOnLength;
____revealLength = 20f;
____revealTimer = 0f;
____isMapMode = true;
__instance._interpPosition = true;
__instance._interpPitch = true;
__instance._interpZoom = true;
__instance._framingPlayer = __instance._lockedToTargetTransform;
__instance._lockTimer = __instance._lockOnMoveLength;
__instance._gridOverrideSize = (__instance._currentRFrame == null) ? 0f : __instance._currentRFrame.GetAutopilotArrivalDistance();
__instance._gridOverride = __instance._gridOverrideSize > 0f;
__instance._gridTimer = (!__instance._gridOverride) ? 0f : __instance._gridLockOnLength;
__instance._revealLength = 20f;
__instance._revealTimer = 0f;
__instance._isMapMode = true;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MapController), nameof(MapController.LateUpdate))]
public static bool MapController_LateUpdate(
MapController __instance,
ref float ____observatoryRevealTwist,
ref float ____defaultPitchAngle,
ref float ____initialPitchAngle,
OWCamera ____mapCamera,
ref float ____lockTimer,
ref float ____revealTimer,
float ____lockOnMoveLength,
float ____revealLength,
ref bool ____screenPromptsVisible,
bool ____isPaused,
ScreenPrompt ____closePrompt,
ScreenPrompt ____panPrompt,
ScreenPrompt ____rotatePrompt,
ScreenPrompt ____zoomPrompt,
ref bool ____lockedToTargetTransform,
ref bool ____interpPosition,
ref bool ____interpPitch,
ref bool ____interpZoom,
OWCamera ____activeCam,
ref Vector3 ____position,
float ____panSpeed,
ref float ____zoom,
float ____maxPanDistance,
float ____yawSpeed,
ref float ____yaw,
float ____pitchSpeed,
ref float ____pitch,
float ____minPitchAngle,
float ____maxPitchAngle,
ref float ____targetZoom,
float ____minZoomDistance,
float ____maxZoomDistance,
float ____initialZoomDist,
float ____zoomSpeed,
float ____observatoryRevealDist
MapController __instance
)
{
____lockTimer = Mathf.Min(____lockTimer + Time.deltaTime, ____lockOnMoveLength);
____revealTimer = Mathf.Min(____revealTimer + Time.deltaTime, ____revealLength);
__instance._lockTimer = Mathf.Min(__instance._lockTimer + Time.deltaTime, __instance._lockOnMoveLength);
__instance._revealTimer = Mathf.Min(__instance._revealTimer + Time.deltaTime, __instance._revealLength);
var revealFraction = Mathf.Clamp01(____revealTimer / ____revealLength);
var revealFraction = Mathf.Clamp01(__instance._revealTimer / __instance._revealLength);
var smoothedRevealFraction = Mathf.SmoothStep(0f, 1f, revealFraction);
var canInteractWith = ____revealTimer > 18f;
var canInteractWith = __instance._revealTimer > 18f;
if (____screenPromptsVisible && ____isPaused)
if (__instance._screenPromptsVisible && __instance._isPaused)
{
____closePrompt.SetVisibility(false);
____panPrompt.SetVisibility(false);
____rotatePrompt.SetVisibility(false);
____zoomPrompt.SetVisibility(false);
____screenPromptsVisible = false;
__instance._closePrompt.SetVisibility(false);
__instance._panPrompt.SetVisibility(false);
__instance._rotatePrompt.SetVisibility(false);
__instance._zoomPrompt.SetVisibility(false);
__instance._screenPromptsVisible = false;
}
else if (!____screenPromptsVisible && canInteractWith && !____isPaused)
else if (!__instance._screenPromptsVisible && canInteractWith && !__instance._isPaused)
{
____closePrompt.SetVisibility(false);
____panPrompt.SetVisibility(true);
____rotatePrompt.SetVisibility(true);
____zoomPrompt.SetVisibility(true);
____screenPromptsVisible = true;
__instance._closePrompt.SetVisibility(false);
__instance._panPrompt.SetVisibility(true);
__instance._rotatePrompt.SetVisibility(true);
__instance._zoomPrompt.SetVisibility(true);
__instance._screenPromptsVisible = true;
}
var XZinput = Vector2.zero;
@ -164,61 +99,61 @@ namespace QSB.DeathSync.Patches
var zoomInput = 0f;
if (canInteractWith)
{
XZinput = OWInput.GetAxisValue(InputLibrary.moveXZ, InputMode.All);
XZinput = OWInput.GetAxisValue(InputLibrary.moveXZ);
lookInput = InputLibrary.look.GetAxisValue(false);
zoomInput = OWInput.GetValue(InputLibrary.mapZoomIn, InputMode.All) - OWInput.GetValue(InputLibrary.mapZoomOut, InputMode.All);
zoomInput = OWInput.GetValue(InputLibrary.mapZoomIn) - OWInput.GetValue(InputLibrary.mapZoomOut);
lookInput.y *= -1f;
zoomInput *= -1f;
}
____lockedToTargetTransform &= XZinput.sqrMagnitude < 0.01f;
____interpPosition &= XZinput.sqrMagnitude < 0.01f;
____interpPitch &= Mathf.Abs(lookInput.y) < 0.1f;
____interpZoom &= Mathf.Abs(zoomInput) < 0.1f;
__instance._lockedToTargetTransform &= XZinput.sqrMagnitude < 0.01f;
__instance._interpPosition &= XZinput.sqrMagnitude < 0.01f;
__instance._interpPitch &= Mathf.Abs(lookInput.y) < 0.1f;
__instance._interpZoom &= Mathf.Abs(zoomInput) < 0.1f;
if (____interpPosition)
if (__instance._interpPosition)
{
var a = ____activeCam.transform.position - Locator.GetCenterOfTheUniverse().GetOffsetPosition();
var a = __instance._activeCam.transform.position - Locator.GetCenterOfTheUniverse().GetOffsetPosition();
var b = Vector3.zero;
____position = Vector3.Lerp(a, b, smoothedRevealFraction);
__instance._position = Vector3.Lerp(a, b, smoothedRevealFraction);
}
else
{
var normalized = Vector3.Scale(__instance.transform.forward + __instance.transform.up, new Vector3(1f, 0f, 1f)).normalized;
var a2 = (__instance.transform.right * XZinput.x) + (normalized * XZinput.y);
____position += a2 * ____panSpeed * ____zoom * Time.deltaTime;
____position.y = 0f;
if (____position.sqrMagnitude > ____maxPanDistance * ____maxPanDistance)
__instance._position += a2 * __instance._panSpeed * __instance._zoom * Time.deltaTime;
__instance._position.y = 0f;
if (__instance._position.sqrMagnitude > __instance._maxPanDistance * __instance._maxPanDistance)
{
____position = ____position.normalized * ____maxPanDistance;
__instance._position = __instance._position.normalized * __instance._maxPanDistance;
}
}
____yaw += lookInput.x * ____yawSpeed * Time.deltaTime;
____yaw = OWMath.WrapAngle(____yaw);
if (____interpPitch)
__instance._yaw += lookInput.x * __instance._yawSpeed * Time.deltaTime;
__instance._yaw = OWMath.WrapAngle(__instance._yaw);
if (__instance._interpPitch)
{
____pitch = Mathf.Lerp(____initialPitchAngle, ____defaultPitchAngle, smoothedRevealFraction);
__instance._pitch = Mathf.Lerp(__instance._initialPitchAngle, __instance._defaultPitchAngle, smoothedRevealFraction);
}
else
{
____pitch += lookInput.y * ____pitchSpeed * Time.deltaTime;
____pitch = Mathf.Clamp(____pitch, ____minPitchAngle, ____maxPitchAngle);
__instance._pitch += lookInput.y * __instance._pitchSpeed * Time.deltaTime;
__instance._pitch = Mathf.Clamp(__instance._pitch, __instance._minPitchAngle, __instance._maxPitchAngle);
}
if (____interpZoom)
if (__instance._interpZoom)
{
____zoom = Mathf.Lerp(____initialZoomDist, ____targetZoom, smoothedRevealFraction);
__instance._zoom = Mathf.Lerp(__instance._initialZoomDist, __instance._targetZoom, smoothedRevealFraction);
}
else
{
____zoom += zoomInput * ____zoomSpeed * Time.deltaTime;
____zoom = Mathf.Clamp(____zoom, ____minZoomDistance, ____maxZoomDistance);
__instance._zoom += zoomInput * __instance._zoomSpeed * Time.deltaTime;
__instance._zoom = Mathf.Clamp(__instance._zoom, __instance._minZoomDistance, __instance._maxZoomDistance);
}
____mapCamera.nearClipPlane = Mathf.Lerp(0.1f, 1f, smoothedRevealFraction);
__instance._mapCamera.nearClipPlane = Mathf.Lerp(0.1f, 1f, smoothedRevealFraction);
var finalRotation = Quaternion.Euler(____pitch, ____yaw, 0f);
var finalRotation = Quaternion.Euler(__instance._pitch, __instance._yaw, 0f);
var num4 = revealFraction * (2f - revealFraction);
@ -229,15 +164,15 @@ namespace QSB.DeathSync.Patches
// Get starting position - distance above player
var startingPosition = RespawnOnDeath.Instance.DeathPositionWorld;
startingPosition += RespawnOnDeath.Instance.DeathPlayerUpVector * num5 * ____observatoryRevealDist;
startingPosition += RespawnOnDeath.Instance.DeathPlayerUpVector * num5 * __instance._observatoryRevealDist;
// Lerp to final rotation
__instance.transform.rotation = Quaternion.Lerp(lookingDownAtPlayer, finalRotation, num5);
// Lerp reveal twist
__instance.transform.rotation *= Quaternion.AngleAxis(Mathf.Lerp(____observatoryRevealTwist, 0f, num4), Vector3.forward);
__instance.transform.rotation *= Quaternion.AngleAxis(Mathf.Lerp(__instance._observatoryRevealTwist, 0f, num4), Vector3.forward);
var endPosition = ____position + (-__instance.transform.forward * ____zoom) + Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition();
var endPosition = __instance._position + (-__instance.transform.forward * __instance._zoom) + Locator.GetCenterOfTheUniverse().GetStaticReferenceFrame().GetPosition();
// Lerp to final position
__instance.transform.position = Vector3.Lerp(startingPosition, endPosition, num5);

View File

@ -1,6 +1,4 @@
using OWML.Common;
using QSB.Events;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.RespawnSync;
using QSB.Utility;

View File

@ -65,7 +65,7 @@ namespace QSB.EchoesOfTheEye.LightSensorSync.Patches
var position = Locator.GetPlayerCamera().transform.position;
var to = __instance.transform.position - position;
if (Vector3.Angle(Locator.GetPlayerCamera().transform.forward, to) <= __instance._maxSpotHalfAngle
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir, true))
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir))
{
__instance._illuminated = true;
}
@ -77,7 +77,7 @@ namespace QSB.EchoesOfTheEye.LightSensorSync.Patches
var position = player.Camera.transform.position;
var to = __instance.transform.position - position;
if (Vector3.Angle(player.Camera.transform.forward, to) <= __instance._maxSpotHalfAngle
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir, true))
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir))
{
__instance._illuminated = true;
}
@ -92,7 +92,7 @@ namespace QSB.EchoesOfTheEye.LightSensorSync.Patches
&& probe.IsLaunched()
&& !probe.IsRetrieving()
&& probe.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
&& !__instance.CheckOcclusion(probe.GetLightSourcePosition(), vector, sensorWorldDir, true))
&& !__instance.CheckOcclusion(probe.GetLightSourcePosition(), vector, sensorWorldDir))
{
__instance._illuminated = true;
}
@ -110,7 +110,7 @@ namespace QSB.EchoesOfTheEye.LightSensorSync.Patches
if (dreamLanternController.IsLit()
&& dreamLanternController.IsFocused(__instance._lanternFocusThreshold)
&& dreamLanternController.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
&& !__instance.CheckOcclusion(dreamLanternController.GetLightPosition(), vector, sensorWorldDir, true))
&& !__instance.CheckOcclusion(dreamLanternController.GetLightPosition(), vector, sensorWorldDir))
{
__instance._illuminatingDreamLanternList.Add(dreamLanternController);
__instance._illuminated = true;

View File

@ -1,29 +0,0 @@
using QSB.ElevatorSync.WorldObjects;
using QSB.Events;
using QSB.WorldSync;
using QSB.WorldSync.Events;
namespace QSB.ElevatorSync.Events
{
public class ElevatorEvent : QSBEvent<BoolWorldObjectMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<int, bool>.AddListener(EventNames.QSBStartLift, Handler);
public override void CloseListener() => GlobalMessenger<int, bool>.RemoveListener(EventNames.QSBStartLift, Handler);
private void Handler(int id, bool isGoingUp) => SendEvent(CreateMessage(id, isGoingUp));
private BoolWorldObjectMessage CreateMessage(int id, bool isGoingUp) => new()
{
State = isGoingUp,
ObjectId = id
};
public override void OnReceiveRemote(bool server, BoolWorldObjectMessage message)
{
var elevator = QSBWorldSync.GetWorldFromId<QSBElevator>(message.ObjectId);
elevator?.RemoteCall(message.State);
}
}
}

View File

@ -0,0 +1,12 @@
using QSB.ElevatorSync.WorldObjects;
using QSB.Messaging;
namespace QSB.ElevatorSync.Messages
{
public class ElevatorMessage : QSBBoolWorldObjectMessage<QSBElevator>
{
public ElevatorMessage(bool isGoingUp) => Value = isGoingUp;
public override void OnReceiveRemote() => WorldObject.RemoteCall(Value);
}
}

View File

@ -1,7 +1,7 @@
using HarmonyLib;
using OWML.Utils;
using QSB.ElevatorSync.Messages;
using QSB.ElevatorSync.WorldObjects;
using QSB.Events;
using QSB.Messaging;
using QSB.Patches;
using QSB.WorldSync;
@ -16,9 +16,9 @@ namespace QSB.ElevatorSync.Patches
[HarmonyPatch(typeof(Elevator), nameof(Elevator.StartLift))]
public static void Elevator_StartLift(Elevator __instance)
{
var isGoingUp = __instance.GetValue<bool>("_goingToTheEnd");
var id = QSBWorldSync.GetIdFromUnity<QSBElevator>(__instance);
QSBEventManager.FireEvent(EventNames.QSBStartLift, id, isGoingUp);
var isGoingUp = __instance._goingToTheEnd;
var qsbElevator = __instance.GetWorldObject<QSBElevator>();
qsbElevator.SendMessage(new ElevatorMessage(isGoingUp));
}
}
}

View File

@ -43,9 +43,9 @@ namespace QSB.ElevatorSync.WorldObjects
AttachedObject._attachPoint.AttachPlayer();
if (Locator.GetPlayerSuit().IsWearingSuit(true) && Locator.GetPlayerSuit().IsTrainingSuit())
if (Locator.GetPlayerSuit().IsWearingSuit() && Locator.GetPlayerSuit().IsTrainingSuit())
{
Locator.GetPlayerSuit().RemoveSuit(false);
Locator.GetPlayerSuit().RemoveSuit();
}
RemoteStartLift();

View File

@ -1,113 +0,0 @@
namespace QSB.Events
{
public static class EventNames
{
// Built into Outer Wilds -- don't change unless they change in-game!
public const string TurnOnFlashlight = nameof(TurnOnFlashlight);
public const string TurnOffFlashlight = nameof(TurnOffFlashlight);
public const string ProbeLauncherEquipped = nameof(ProbeLauncherEquipped);
public const string ProbeLauncherUnequipped = nameof(ProbeLauncherUnequipped);
public const string EquipSignalscope = nameof(EquipSignalscope);
public const string UnequipSignalscope = nameof(UnequipSignalscope);
public const string SuitUp = nameof(SuitUp);
public const string RemoveSuit = nameof(RemoveSuit);
public const string EquipTranslator = nameof(EquipTranslator);
public const string UnequipTranslator = nameof(UnequipTranslator);
public const string WakeUp = nameof(WakeUp);
public const string DialogueConditionChanged = nameof(DialogueConditionChanged);
public const string PlayerEnterQuantumMoon = nameof(PlayerEnterQuantumMoon);
public const string PlayerExitQuantumMoon = nameof(PlayerExitQuantumMoon);
public const string EnterRoastingMode = nameof(EnterRoastingMode);
public const string ExitRoastingMode = nameof(ExitRoastingMode);
public const string EnterFlightConsole = nameof(EnterFlightConsole);
public const string ExitFlightConsole = nameof(ExitFlightConsole);
public const string EnterShip = nameof(EnterShip);
public const string ExitShip = nameof(ExitShip);
public const string EyeStateChanged = nameof(EyeStateChanged);
// Custom event names -- change if you want! These can be anything, as long as both
// sides of the GlobalMessenger (fireevent and addlistener) reference the same thing.
public const string QSBPlayerDeath = nameof(QSBPlayerDeath);
public const string QSBPlayerJoin = nameof(QSBPlayerJoin);
public const string QSBPlayerReady = nameof(QSBPlayerReady);
public const string QSBRequestStateResync = nameof(QSBRequestStateResync);
public const string QSBServerTime = nameof(QSBServerTime);
public const string QSBStartLift = nameof(QSBStartLift);
public const string QSBGeyserState = nameof(QSBGeyserState);
public const string QSBOrbSlot = nameof(QSBOrbSlot);
public const string QSBOrbDrag = nameof(QSBOrbDrag);
public const string QSBConversation = nameof(QSBConversation);
public const string QSBConversationStartEnd = nameof(QSBConversationStartEnd);
public const string QSBChangeAnimType = nameof(QSBChangeAnimType);
public const string QSBPlayerInformation = nameof(QSBPlayerInformation);
public const string QSBRevealFact = nameof(QSBRevealFact);
public const string QSBSocketStateChange = nameof(QSBSocketStateChange);
public const string QSBMultiStateChange = nameof(QSBMultiStateChange);
public const string QSBQuantumShuffle = nameof(QSBQuantumShuffle);
public const string QSBQuantumAuthority = nameof(QSBQuantumAuthority);
public const string QSBMoonStateChange = nameof(QSBMoonStateChange);
public const string QSBIdentifyFrequency = nameof(QSBIdentifyFrequency);
public const string QSBIdentifySignal = nameof(QSBIdentifySignal);
public const string QSBTextTranslated = nameof(QSBTextTranslated);
public const string QSBEnterShrine = nameof(QSBEnterShrine);
public const string QSBExitShrine = nameof(QSBExitShrine);
public const string QSBPlayerEntangle = nameof(QSBPlayerEntangle);
public const string QSBDropItem = nameof(QSBDropItem);
public const string QSBSocketItem = nameof(QSBSocketItem);
public const string QSBMoveToCarry = nameof(QSBMoveToCarry);
public const string QSBStartStatue = nameof(QSBStartStatue);
public const string QSBPlayerKick = nameof(QSBPlayerKick);
public const string QSBEnterPlatform = nameof(QSBEnterPlatform);
public const string QSBExitPlatform = nameof(QSBExitPlatform);
public const string QSBCampfireState = nameof(QSBCampfireState);
public const string QSBMarshmallowEvent = nameof(QSBMarshmallowEvent);
public const string QSBAnimTrigger = nameof(QSBAnimTrigger);
public const string QSBEnterNonNomaiHeadZone = nameof(QSBEnterNonNomaiHeadZone);
public const string QSBExitNonNomaiHeadZone = nameof(QSBExitNonNomaiHeadZone);
public const string QSBNpcAnimEvent = nameof(QSBNpcAnimEvent);
public const string QSBHatchState = nameof(QSBHatchState);
public const string QSBEnableFunnel = nameof(QSBEnableFunnel);
public const string QSBHullImpact = nameof(QSBHullImpact);
public const string QSBHullDamaged = nameof(QSBHullDamaged);
public const string QSBHullChangeIntegrity = nameof(QSBHullChangeIntegrity);
public const string QSBHullRepaired = nameof(QSBHullRepaired);
public const string QSBHullRepairTick = nameof(QSBHullRepairTick);
public const string QSBComponentDamaged = nameof(QSBComponentDamaged);
public const string QSBComponentRepaired = nameof(QSBComponentRepaired);
public const string QSBComponentRepairTick = nameof(QSBComponentRepairTick);
public const string QSBPlayerRespawn = nameof(QSBPlayerRespawn);
public const string QSBProbeEvent = nameof(QSBProbeEvent);
public const string QSBProbeStartRetrieve = nameof(QSBProbeStartRetrieve);
public const string QSBRetrieveProbe = nameof(QSBRetrieveProbe);
public const string QSBPlayerRetrieveProbe = nameof(QSBPlayerRetrieveProbe);
public const string QSBLaunchProbe = nameof(QSBLaunchProbe);
public const string QSBPlayerLaunchProbe = nameof(QSBPlayerLaunchProbe);
public const string QSBEndLoop = nameof(QSBEndLoop);
public const string QSBStartLoop = nameof(QSBStartLoop);
public const string QSBServerState = nameof(QSBServerState);
public const string QSBClientState = nameof(QSBClientState);
public const string QSBDebugEvent = nameof(QSBDebugEvent);
public const string QSBEnterNomaiHeadZone = nameof(QSBEnterNomaiHeadZone);
public const string QSBExitNomaiHeadZone = nameof(QSBExitNomaiHeadZone);
public const string QSBEnterSatelliteCamera = nameof(QSBEnterSatelliteCamera);
public const string QSBExitSatelliteCamera = nameof(QSBExitSatelliteCamera);
public const string QSBSatelliteSnapshot = nameof(QSBSatelliteSnapshot);
public const string QSBAnglerChangeState = nameof(QSBAnglerChangeState);
public const string QSBMeteorPreLaunch = nameof(QSBMeteorPreLaunch);
public const string QSBMeteorLaunch = nameof(QSBMeteorLaunch);
public const string QSBMeteorSpecialImpact = nameof(QSBMeteorSpecialImpact);
public const string QSBFragmentDamage = nameof(QSBFragmentDamage);
public const string QSBFragmentResync = nameof(QSBFragmentResync);
public const string QSBLearnLaunchCodes = nameof(QSBLearnLaunchCodes);
public const string QSBSatelliteRepairTick = nameof(QSBSatelliteRepairTick);
public const string QSBSatelliteRepaired = nameof(QSBSatelliteRepairTick);
public const string QSBAuthQueue = nameof(QSBAuthQueue);
public const string QSBJellyfishRising = nameof(QSBJellyfishRising);
public const string QSBTornadoFormState = nameof(QSBTornadoFormState);
public const string QSBRequestGameDetails = nameof(QSBRequestGameDetails);
public const string QSBGameDetails = nameof(QSBGameDetails);
public const string QSBEnterRemoteDialogue = nameof(QSBEnterRemoteDialogue);
public const string QSBGatherInstrument = nameof(QSBGatherInstrument);
public const string QSBZoomOut = nameof(QSBZoomOut);
}
}

View File

@ -1,8 +0,0 @@
namespace QSB.Events
{
public interface IQSBEvent
{
void SetupListener();
void CloseListener();
}
}

View File

@ -1,99 +0,0 @@
using JetBrains.Annotations;
using OWML.Utils;
using QSB.Messaging;
using QSB.Player;
using QSB.WorldSync;
using QuantumUNET.Transport;
using System;
using QSB.Utility;
namespace QSB.Events
{
public abstract class QSBEvent<T> : IQSBEvent where T : PlayerMessage, new()
{
public uint LocalPlayerId => QSBPlayerManager.LocalPlayerId;
[UsedImplicitly]
private Type _messageType => typeof(T);
[UsedImplicitly]
private readonly int _msgType;
protected QSBEvent()
{
_msgType = QSBEventManager._eventList.Count;
}
public abstract void SetupListener();
public abstract void CloseListener();
[UsedImplicitly]
public virtual void OnReceiveRemote(bool isHost, T message) { }
[UsedImplicitly]
public virtual void OnReceiveLocal(bool isHost, T message) { }
public abstract bool RequireWorldObjectsReady { get; }
public void SendEvent(T message)
{
message.FromId = LocalPlayerId;
if (QSBEventManager.ForIdOverride != uint.MaxValue)
{
message.ForId = QSBEventManager.ForIdOverride;
}
if (message.OnlySendToHost)
{
if (QSBEventManager.ForIdOverride != uint.MaxValue)
{
DebugLog.ToConsole($"Warning - {typeof(T).Name} is OnlySendToHost, but we are trying to ForIdOverride!");
}
message.ForId = 0;
}
new QSBEventRelay
{
To = message.ForId,
Event = this,
Message = message
}.Send();
}
/// <summary>
/// Checks whether the message should be processed by the executing client.
/// </summary>
/// <returns>True if the message should be processed.</returns>
[UsedImplicitly]
public virtual bool CheckMessage(T message)
=> !RequireWorldObjectsReady || WorldObjectManager.AllObjectsReady;
}
internal class QSBEventRelay : QSBMessage
{
public IQSBEvent Event;
public PlayerMessage Message;
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
var msgType = Event.GetValue<int>("_msgType");
writer.Write(msgType);
Message.Serialize(writer);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
var msgType = reader.ReadInt32();
Event = QSBEventManager._eventList[msgType];
var messageType = Event.GetValue<Type>("_messageType");
Message = (PlayerMessage)Activator.CreateInstance(messageType);
Message.Deserialize(reader);
}
public override bool ShouldReceive => Event.Invoke<bool>("CheckMessage", Message);
public override void OnReceiveRemote() => Event.Invoke("OnReceiveRemote", QSBCore.IsHost, Message);
public override void OnReceiveLocal() => Event.Invoke("OnReceiveLocal", QSBCore.IsHost, Message);
public override string ToString() => Event.GetType().Name;
}
}

View File

@ -1,122 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OWML.Common;
using QSB.Utility;
namespace QSB.Events
{
public static class QSBEventManager
{
public static bool Ready { get; private set; }
private static readonly Type[] _types = typeof(IQSBEvent).GetDerivedTypes().ToArray();
internal static readonly List<IQSBEvent> _eventList = new();
public static void Init()
{
foreach (var type in _types)
{
_eventList.Add((IQSBEvent)Activator.CreateInstance(type));
}
if (UnitTestDetector.IsInUnitTest)
{
return;
}
_eventList.ForEach(ev => ev.SetupListener());
Ready = true;
DebugLog.DebugWrite("Event Manager ready.", MessageType.Success);
}
public static void Reset()
{
Ready = false;
_eventList.ForEach(ev => ev.CloseListener());
_eventList.Clear();
}
public static void FireEvent(string eventName)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger.FireEvent(eventName);
}
public static void FireEvent<T>(string eventName, T arg)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T>.FireEvent(eventName, arg);
}
public static void FireEvent<T, U>(string eventName, T arg1, U arg2)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U>.FireEvent(eventName, arg1, arg2);
}
public static void FireEvent<T, U, V>(string eventName, T arg1, U arg2, V arg3)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U, V>.FireEvent(eventName, arg1, arg2, arg3);
}
public static void FireEvent<T, U, V, W>(string eventName, T arg1, U arg2, V arg3, W arg4)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U, V, W>.FireEvent(eventName, arg1, arg2, arg3, arg4);
}
public static void FireEvent<T, U, V, W, X>(string eventName, T arg1, U arg2, V arg3, W arg4, X arg5)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U, V, W, X>.FireEvent(eventName, arg1, arg2, arg3, arg4, arg5);
}
public static void FireEvent<T, U, V, W, X, Y>(string eventName, T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U, V, W, X, Y>.FireEvent(eventName, arg1, arg2, arg3, arg4, arg5, arg6);
}
/// used to force set ForId for every sent event
public static uint ForIdOverride = uint.MaxValue;
}
}

View File

@ -1,33 +0,0 @@
using QSB.Events;
using QSB.Messaging;
using QSB.Player;
namespace QSB.EyeOfTheUniverse.EyeStateSync.Events
{
internal class EyeStateEvent : QSBEvent<EnumMessage<EyeState>>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<EyeState>.AddListener(EventNames.EyeStateChanged, Handler);
public override void CloseListener() => GlobalMessenger<EyeState>.RemoveListener(EventNames.EyeStateChanged, Handler);
private void Handler(EyeState state) => SendEvent(CreateMessage(state));
private EnumMessage<EyeState> CreateMessage(EyeState state) => new()
{
AboutId = LocalPlayerId,
EnumValue = state
};
public override void OnReceiveLocal(bool isHost, EnumMessage<EyeState> message)
{
QSBPlayerManager.LocalPlayer.EyeState = message.EnumValue;
}
public override void OnReceiveRemote(bool isHost, EnumMessage<EyeState> message)
{
var player = QSBPlayerManager.GetPlayer(message.AboutId);
player.EyeState = message.EnumValue;
}
}
}

View File

@ -0,0 +1,36 @@
using QSB.Messaging;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.WorldSync;
namespace QSB.EyeOfTheUniverse.EyeStateSync.Messages
{
internal class EyeStateMessage : QSBEnumMessage<EyeState>
{
static EyeStateMessage() => GlobalMessenger<EyeState>.AddListener(OWEvents.EyeStateChanged, Handler);
private static void Handler(EyeState state)
{
if (PlayerTransformSync.LocalInstance)
{
new EyeStateMessage(state).Send();
}
}
private EyeStateMessage(EyeState state) => Value = state;
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveLocal()
{
QSBPlayerManager.LocalPlayer.EyeState = Value;
}
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);
player.EyeState = Value;
}
}
}

View File

@ -1,25 +1,14 @@
using QSB.Events;
using QSB.Messaging;
using QSB.Messaging;
using QSB.WorldSync;
using System.Linq;
namespace QSB.EyeOfTheUniverse.GalaxyMap.Events
namespace QSB.EyeOfTheUniverse.GalaxyMap.Messages
{
internal class ZoomOutEvent : QSBEvent<PlayerMessage>
internal class ZoomOutMessage : QSBMessage
{
public override bool RequireWorldObjectsReady => true;
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBZoomOut, Handler);
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBZoomOut, Handler);
private void Handler() => SendEvent(CreateMessage());
private PlayerMessage CreateMessage() => new()
{
AboutId = LocalPlayerId
};
public override void OnReceiveRemote(bool isHost, PlayerMessage message)
public override void OnReceiveRemote()
{
var controller = QSBWorldSync.GetUnityObjects<GalaxyMapController>().First();
controller.enabled = true;

View File

@ -1,5 +1,6 @@
using HarmonyLib;
using QSB.Events;
using QSB.EyeOfTheUniverse.GalaxyMap.Messages;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using System.Linq;
@ -30,7 +31,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap.Patches
{
if (QSBPlayerManager.PlayerList.All(x => x.EyeState == EyeState.Observatory))
{
QSBEventManager.FireEvent(EventNames.QSBZoomOut);
new ZoomOutMessage().Send();
}
}
}

View File

@ -82,7 +82,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
{
if (_currentDialogueBox != null && OWInput.GetInputMode() == InputMode.Dialogue)
{
if (OWInput.IsNewlyPressed(InputLibrary.interact, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.cancel, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.enter, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.enter2, InputMode.All))
if (OWInput.IsNewlyPressed(InputLibrary.interact) || OWInput.IsNewlyPressed(InputLibrary.cancel) || OWInput.IsNewlyPressed(InputLibrary.enter) || OWInput.IsNewlyPressed(InputLibrary.enter2))
{
if (!_currentDialogueBox.AreTextEffectsComplete())
{
@ -104,13 +104,13 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
}
else
{
if (OWInput.IsNewlyPressed(InputLibrary.down, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.down2, InputMode.All))
if (OWInput.IsNewlyPressed(InputLibrary.down) || OWInput.IsNewlyPressed(InputLibrary.down2))
{
_currentDialogueBox.OnDownPressed();
return;
}
if (OWInput.IsNewlyPressed(InputLibrary.up, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.up2, InputMode.All))
if (OWInput.IsNewlyPressed(InputLibrary.up) || OWInput.IsNewlyPressed(InputLibrary.up2))
{
_currentDialogueBox.OnUpPressed();
}
@ -180,7 +180,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
dialogueNode.ListEntryCondition.Add(xelement5.Value);
if (!sharedInstance.ConditionExists(xelement5.Value))
{
sharedInstance.AddCondition(xelement5.Value, false);
sharedInstance.AddCondition(xelement5.Value);
}
}
}
@ -256,7 +256,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
dialogueOption.ConditionRequirement = xelement13.Element("RequiredCondition").Value;
if (!sharedInstance.ConditionExists(dialogueOption.ConditionRequirement))
{
sharedInstance.AddCondition(dialogueOption.ConditionRequirement, false);
sharedInstance.AddCondition(dialogueOption.ConditionRequirement);
}
}
@ -270,7 +270,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
dialogueOption.CancelledRequirement = xelement13.Element("CancelledCondition").Value;
if (!sharedInstance.ConditionExists(dialogueOption.CancelledRequirement))
{
sharedInstance.AddCondition(dialogueOption.CancelledRequirement, false);
sharedInstance.AddCondition(dialogueOption.CancelledRequirement);
}
}
@ -289,7 +289,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
dialogueOption.ConditionToSet = xelement13.Element("ConditionToSet").Value;
if (!sharedInstance.ConditionExists(dialogueOption.ConditionToSet))
{
sharedInstance.AddCondition(dialogueOption.ConditionToSet, false);
sharedInstance.AddCondition(dialogueOption.ConditionToSet);
}
}
@ -298,7 +298,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
dialogueOption.ConditionToCancel = xelement13.Element("ConditionToCancel").Value;
if (!sharedInstance.ConditionExists(dialogueOption.ConditionToCancel))
{
sharedInstance.AddCondition(dialogueOption.ConditionToCancel, false);
sharedInstance.AddCondition(dialogueOption.ConditionToCancel);
}
}
@ -368,12 +368,12 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
_currentDialogueBox = DisplayDialogueBox2();
if (_attentionPoint != null && !PlayerState.InZeroG())
{
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().LockOn(_attentionPoint, _attentionPointOffset, 2f, false, 1f);
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().LockOn(_attentionPoint, _attentionPointOffset, 2f);
}
if (PlayerState.InZeroG() && !_timeFrozen)
{
Locator.GetPlayerBody().GetComponent<Autopilot>().StartMatchVelocity(this.GetAttachedOWRigidbody(false).GetReferenceFrame(), false);
Locator.GetPlayerBody().GetComponent<Autopilot>().StartMatchVelocity(this.GetAttachedOWRigidbody().GetReferenceFrame());
}
}
@ -497,7 +497,7 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
if (selectedOption.ConditionToCancel != string.Empty)
{
DialogueConditionManager.SharedInstance.SetConditionState(selectedOption.ConditionToCancel, false);
DialogueConditionManager.SharedInstance.SetConditionState(selectedOption.ConditionToCancel);
}
if (selectedOption.TargetName == string.Empty)

View File

@ -149,12 +149,12 @@ namespace QSB.EyeOfTheUniverse.GalaxyMap
if (PersistentConditionToDisable != string.Empty)
{
PlayerData.SetPersistentCondition(PersistentConditionToDisable, false);
sharedInstance.SetConditionState(PersistentConditionToDisable, false);
sharedInstance.SetConditionState(PersistentConditionToDisable);
}
for (var j = 0; j < DBEntriesToSet.Length; j++)
{
Locator.GetShipLogManager().RevealFact(DBEntriesToSet[j], true, true);
Locator.GetShipLogManager().RevealFact(DBEntriesToSet[j]);
}
}
}

View File

@ -1,29 +0,0 @@
using QSB.Events;
using QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects;
using QSB.WorldSync;
using QSB.WorldSync.Events;
namespace QSB.EyeOfTheUniverse.InstrumentSync.Event
{
internal class GatherInstrumentEvent : QSBEvent<WorldObjectMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<QSBQuantumInstrument>.AddListener(EventNames.QSBGatherInstrument, Handler);
public override void CloseListener() => GlobalMessenger<QSBQuantumInstrument>.RemoveListener(EventNames.QSBGatherInstrument, Handler);
private void Handler(QSBQuantumInstrument instrument) => SendEvent(CreateMessage(instrument));
private BoolWorldObjectMessage CreateMessage(QSBQuantumInstrument instrument) => new()
{
AboutId = LocalPlayerId,
ObjectId = instrument.ObjectId
};
public override void OnReceiveRemote(bool isHost, WorldObjectMessage message)
{
var qsbObj = QSBWorldSync.GetWorldFromId<QSBQuantumInstrument>(message.ObjectId);
qsbObj.AttachedObject.Gather();
}
}
}

View File

@ -0,0 +1,10 @@
using QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects;
using QSB.Messaging;
namespace QSB.EyeOfTheUniverse.InstrumentSync.Messages
{
internal class GatherInstrumentMessage : QSBWorldObjectMessage<QSBQuantumInstrument>
{
public override void OnReceiveRemote() => WorldObject.AttachedObject.Gather();
}
}

View File

@ -1,6 +1,7 @@
using HarmonyLib;
using QSB.Events;
using QSB.EyeOfTheUniverse.InstrumentSync.Messages;
using QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects;
using QSB.Messaging;
using QSB.Patches;
using QSB.WorldSync;
using UnityEngine;
@ -14,7 +15,7 @@ namespace QSB.EyeOfTheUniverse.InstrumentSync.Patches
[HarmonyPostfix]
[HarmonyPatch(typeof(QuantumInstrument), nameof(QuantumInstrument.OnPressInteract))]
public static void OnPressInteract(QuantumInstrument __instance)
=> QSBEventManager.FireEvent(EventNames.QSBGatherInstrument, QSBWorldSync.GetWorldFromUnity<QSBQuantumInstrument>(__instance));
=> __instance.GetWorldObject<QSBQuantumInstrument>().SendMessage(new GatherInstrumentMessage());
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumInstrument), nameof(QuantumInstrument.Update))]
@ -27,10 +28,10 @@ namespace QSB.EyeOfTheUniverse.InstrumentSync.Patches
&& Vector3.Angle(__instance.transform.position - Locator.GetPlayerCamera().transform.position, Locator.GetPlayerCamera().transform.forward) < 1f)
{
__instance._scopeGatherPrompt.SetVisibility(true);
if (OWInput.IsNewlyPressed(InputLibrary.interact, InputMode.All))
if (OWInput.IsNewlyPressed(InputLibrary.interact))
{
__instance.Gather();
QSBEventManager.FireEvent(EventNames.QSBGatherInstrument, QSBWorldSync.GetWorldFromUnity<QSBQuantumInstrument>(__instance));
__instance.GetWorldObject<QSBQuantumInstrument>().SendMessage(new GatherInstrumentMessage());
Locator.GetPromptManager().RemoveScreenPrompt(__instance._scopeGatherPrompt);
}
}

View File

@ -1,30 +0,0 @@
using QSB.Events;
using QSB.GeyserSync.WorldObjects;
using QSB.WorldSync;
using QSB.WorldSync.Events;
namespace QSB.GeyserSync.Events
{
public class GeyserEvent : QSBEvent<BoolWorldObjectMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener() => GlobalMessenger<int, bool>.AddListener(EventNames.QSBGeyserState, Handler);
public override void CloseListener() => GlobalMessenger<int, bool>.RemoveListener(EventNames.QSBGeyserState, Handler);
private void Handler(int id, bool state) => SendEvent(CreateMessage(id, state));
private BoolWorldObjectMessage CreateMessage(int id, bool state) => new()
{
AboutId = LocalPlayerId,
ObjectId = id,
State = state
};
public override void OnReceiveRemote(bool isHost, BoolWorldObjectMessage message)
{
var geyser = QSBWorldSync.GetWorldFromId<QSBGeyser>(message.ObjectId);
geyser?.SetState(message.State);
}
}
}

View File

@ -0,0 +1,12 @@
using QSB.GeyserSync.WorldObjects;
using QSB.Messaging;
namespace QSB.GeyserSync.Messages
{
public class GeyserMessage : QSBBoolWorldObjectMessage<QSBGeyser>
{
public GeyserMessage(bool state) => Value = state;
public override void OnReceiveRemote() => WorldObject.SetState(Value);
}
}

View File

@ -1,4 +1,5 @@
using QSB.Events;
using QSB.GeyserSync.Messages;
using QSB.Messaging;
using QSB.WorldSync;
using QuantumUNET;
@ -16,7 +17,7 @@ namespace QSB.GeyserSync.WorldObjects
{
if (QNetworkServer.active)
{
QSBEventManager.FireEvent(EventNames.QSBGeyserState, ObjectId, state);
this.SendMessage(new GeyserMessage(state));
}
}

View File

@ -1,5 +1,4 @@
using QSB.Utility;
using UnityEngine;
using UnityEngine;
namespace QSB.Inputs
{

View File

@ -1,7 +1,8 @@
using OWML.Common;
using QSB.Animation.Player;
using QSB.Events;
using QSB.Animation.Player.Messages;
using QSB.Instruments.QSBCamera;
using QSB.Messaging;
using QSB.Player;
using QSB.Utility;
using UnityEngine;
@ -119,7 +120,7 @@ namespace QSB.Instruments
public void SwitchToType(AnimationType type)
{
QSBEventManager.FireEvent(EventNames.QSBChangeAnimType, QSBPlayerManager.LocalPlayerId, type);
new ChangeAnimTypeMessage(QSBPlayerManager.LocalPlayerId, type).Send();
QSBPlayerManager.LocalPlayer.AnimationSync.SetAnimationType(type);
CheckInstrumentProps(type);
}

View File

@ -1,5 +1,4 @@
using OWML.Common;
using QSB.Events;
using QSB.Utility;
using UnityEngine;
using UnityEngine.PostProcessing;
@ -84,7 +83,7 @@ namespace QSB.Instruments.QSBCamera
}
OWInput.ChangeInputMode(InputMode.None);
QSBEventManager.FireEvent("SwitchActiveCamera", _owCamera);
GlobalMessenger<OWCamera>.FireEvent("SwitchActiveCamera", _owCamera);
Locator.GetPlayerCamera().mainCamera.enabled = false;
if (_cameraObj.GetComponent<PostProcessingBehaviour>() == null)
{
@ -113,7 +112,7 @@ namespace QSB.Instruments.QSBCamera
}
OWInput.ChangeInputMode(InputMode.Character);
QSBEventManager.FireEvent("SwitchActiveCamera", Locator.GetPlayerCamera());
GlobalMessenger<OWCamera>.FireEvent("SwitchActiveCamera", Locator.GetPlayerCamera());
Locator.GetActiveCamera().mainCamera.enabled = true;
_camera.enabled = false;
Mode = CameraMode.FirstPerson;

View File

@ -1,40 +0,0 @@
using QSB.Events;
using QSB.ItemSync.WorldObjects.Items;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.ItemSync.Events
{
internal class DropItemEvent : QSBEvent<DropItemMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener()
=> GlobalMessenger<int, Vector3, Vector3, Sector>.AddListener(EventNames.QSBDropItem, Handler);
public override void CloseListener()
=> GlobalMessenger<int, Vector3, Vector3, Sector>.RemoveListener(EventNames.QSBDropItem, Handler);
private void Handler(int objectId, Vector3 position, Vector3 normal, Sector sector)
=> SendEvent(CreateMessage(objectId, position, normal, sector));
private DropItemMessage CreateMessage(int objectId, Vector3 position, Vector3 normal, Sector sector) => new()
{
ObjectId = objectId,
Position = position,
Normal = normal,
Sector = sector
};
public override void OnReceiveRemote(bool server, DropItemMessage message)
{
var worldObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ObjectId);
worldObject.DropItem(message.Position, message.Normal, message.Sector);
var player = QSBPlayerManager.GetPlayer(message.FromId);
player.HeldItem = worldObject;
}
}
}

View File

@ -1,36 +0,0 @@
using QSB.Messaging;
using QSB.SectorSync.WorldObjects;
using QSB.WorldSync;
using QuantumUNET.Transport;
using UnityEngine;
namespace QSB.ItemSync.Events
{
public class DropItemMessage : PlayerMessage
{
public int ObjectId { get; set; }
public Vector3 Position { get; set; }
public Vector3 Normal { get; set; }
public Sector Sector { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
ObjectId = reader.ReadInt32();
Position = reader.ReadVector3();
Normal = reader.ReadVector3();
var sectorId = reader.ReadInt32();
Sector = QSBWorldSync.GetWorldFromId<QSBSector>(sectorId).AttachedObject;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(ObjectId);
writer.Write(Position);
writer.Write(Normal);
var qsbSector = QSBWorldSync.GetWorldFromUnity<QSBSector>(Sector);
writer.Write(qsbSector.ObjectId);
}
}
}

View File

@ -1,51 +0,0 @@
using QSB.Events;
using QSB.ItemSync.WorldObjects.Items;
using QSB.Player;
using QSB.WorldSync;
using QSB.WorldSync.Events;
namespace QSB.ItemSync.Events
{
internal class MoveToCarryEvent : QSBEvent<WorldObjectMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener()
=> GlobalMessenger<int>.AddListener(EventNames.QSBMoveToCarry, Handler);
public override void CloseListener()
=> GlobalMessenger<int>.RemoveListener(EventNames.QSBMoveToCarry, Handler);
private void Handler(int itemId)
=> SendEvent(CreateMessage(itemId));
private WorldObjectMessage CreateMessage(int itemid) => new()
{
AboutId = QSBPlayerManager.LocalPlayerId,
ObjectId = itemid
};
public override void OnReceiveRemote(bool server, WorldObjectMessage message)
{
var player = QSBPlayerManager.GetPlayer(message.AboutId);
var itemObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ObjectId);
var itemType = itemObject.GetItemType();
player.HeldItem = itemObject;
var itemSocket = itemType switch
{
ItemType.Scroll => player.ScrollSocket,
ItemType.SharedStone => player.SharedStoneSocket,
ItemType.WarpCore => ((QSBWarpCoreItem)itemObject).IsVesselCoreType()
? player.VesselCoreSocket
: player.WarpCoreSocket,
ItemType.Lantern => player.SimpleLanternSocket,
ItemType.DreamLantern => player.DreamLanternSocket,
ItemType.SlideReel => player.SlideReelSocket,
ItemType.VisionTorch => player.VisionTorchSocket,
_ => player.ItemSocket,
};
itemObject.PickUpItem(itemSocket, message.AboutId);
}
}
}

View File

@ -1,64 +0,0 @@
using QSB.Events;
using QSB.ItemSync.WorldObjects.Items;
using QSB.ItemSync.WorldObjects.Sockets;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
namespace QSB.ItemSync.Events
{
internal class SocketItemEvent : QSBEvent<SocketItemMessage>
{
public override bool RequireWorldObjectsReady => true;
public override void SetupListener()
=> GlobalMessenger<int, int, SocketEventType>.AddListener(EventNames.QSBSocketItem, Handler);
public override void CloseListener()
=> GlobalMessenger<int, int, SocketEventType>.RemoveListener(EventNames.QSBSocketItem, Handler);
private void Handler(int socketId, int itemId, SocketEventType type)
=> SendEvent(CreateMessage(socketId, itemId, type));
private SocketItemMessage CreateMessage(int socketId, int itemId, SocketEventType type) => new()
{
AboutId = QSBPlayerManager.LocalPlayerId,
SocketId = socketId,
ItemId = itemId,
SocketType = type
};
public override void OnReceiveRemote(bool server, SocketItemMessage message)
{
IQSBOWItemSocket socketWorldObject;
IQSBOWItem itemWorldObject;
var player = QSBPlayerManager.GetPlayer(message.FromId);
player.HeldItem = null;
switch (message.SocketType)
{
case SocketEventType.Socket:
socketWorldObject = QSBWorldSync.GetWorldFromId<IQSBOWItemSocket>(message.SocketId);
itemWorldObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ItemId);
socketWorldObject.PlaceIntoSocket(itemWorldObject);
return;
case SocketEventType.StartUnsocket:
socketWorldObject = QSBWorldSync.GetWorldFromId<IQSBOWItemSocket>(message.SocketId);
if (!socketWorldObject.IsSocketOccupied())
{
DebugLog.ToConsole($"Warning - Trying to start unsocket on socket that is unoccupied! Socket:{socketWorldObject.Name}");
return;
}
socketWorldObject.RemoveFromSocket();
return;
case SocketEventType.CompleteUnsocket:
itemWorldObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ItemId);
itemWorldObject.OnCompleteUnsocket();
return;
}
}
}
}

View File

@ -1,28 +0,0 @@
using QSB.Messaging;
using QuantumUNET.Transport;
namespace QSB.ItemSync.Events
{
public class SocketItemMessage : PlayerMessage
{
public int SocketId { get; set; }
public int ItemId { get; set; }
public SocketEventType SocketType { get; set; }
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
SocketId = reader.ReadInt32();
ItemId = reader.ReadInt32();
SocketType = (SocketEventType)reader.ReadInt32();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(SocketId);
writer.Write(ItemId);
writer.Write((int)SocketType);
}
}
}

View File

@ -0,0 +1,49 @@
using QSB.ItemSync.WorldObjects.Items;
using QSB.Messaging;
using QSB.Player;
using QSB.SectorSync.WorldObjects;
using QSB.WorldSync;
using QuantumUNET.Transport;
using UnityEngine;
namespace QSB.ItemSync.Messages
{
internal class DropItemMessage : QSBWorldObjectMessage<IQSBOWItem>
{
private Vector3 Position;
private Vector3 Normal;
private int SectorId;
public DropItemMessage(Vector3 position, Vector3 normal, Sector sector)
{
Position = position;
Normal = normal;
SectorId = sector.GetWorldObject<QSBSector>().ObjectId;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(Position);
writer.Write(Normal);
writer.Write(SectorId);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
Position = reader.ReadVector3();
Normal = reader.ReadVector3();
SectorId = reader.ReadInt32();
}
public override void OnReceiveRemote()
{
var sector = SectorId.GetWorldObject<QSBSector>().AttachedObject;
WorldObject.DropItem(Position, Normal, sector);
var player = QSBPlayerManager.GetPlayer(From);
player.HeldItem = WorldObject;
}
}
}

View File

@ -0,0 +1,31 @@
using QSB.ItemSync.WorldObjects.Items;
using QSB.Messaging;
using QSB.Player;
namespace QSB.ItemSync.Messages
{
internal class MoveToCarryMessage : QSBWorldObjectMessage<IQSBOWItem>
{
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);
var itemType = WorldObject.GetItemType();
player.HeldItem = WorldObject;
var itemSocket = itemType switch
{
ItemType.Scroll => player.ScrollSocket,
ItemType.SharedStone => player.SharedStoneSocket,
ItemType.WarpCore => ((QSBWarpCoreItem)WorldObject).IsVesselCoreType()
? player.VesselCoreSocket
: player.WarpCoreSocket,
ItemType.Lantern => player.SimpleLanternSocket,
ItemType.DreamLantern => player.DreamLanternSocket,
ItemType.SlideReel => player.SlideReelSocket,
ItemType.VisionTorch => player.VisionTorchSocket,
_ => player.ItemSocket,
};
WorldObject.PickUpItem(itemSocket, From);
}
}
}

View File

@ -0,0 +1,72 @@
using QSB.ItemSync.WorldObjects.Items;
using QSB.ItemSync.WorldObjects.Sockets;
using QSB.Messaging;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using QuantumUNET.Transport;
namespace QSB.ItemSync.Messages
{
internal class SocketItemMessage : QSBEnumMessage<SocketMessageType>
{
private int SocketId;
private int ItemId;
public SocketItemMessage(SocketMessageType type, int socketId = -1, int itemId = -1)
{
Value = type;
SocketId = socketId;
ItemId = itemId;
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(SocketId);
writer.Write(ItemId);
}
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
SocketId = reader.ReadInt32();
ItemId = reader.ReadInt32();
}
public override bool ShouldReceive => WorldObjectManager.AllObjectsReady;
public override void OnReceiveRemote()
{
IQSBOWItemSocket socketWorldObject;
IQSBOWItem itemWorldObject;
var player = QSBPlayerManager.GetPlayer(From);
player.HeldItem = null;
switch (Value)
{
case SocketMessageType.Socket:
socketWorldObject = SocketId.GetWorldObject<IQSBOWItemSocket>();
itemWorldObject = ItemId.GetWorldObject<IQSBOWItem>();
socketWorldObject.PlaceIntoSocket(itemWorldObject);
return;
case SocketMessageType.StartUnsocket:
socketWorldObject = SocketId.GetWorldObject<IQSBOWItemSocket>();
if (!socketWorldObject.IsSocketOccupied())
{
DebugLog.ToConsole($"Warning - Trying to start unsocket on socket that is unoccupied! Socket:{socketWorldObject.Name}");
return;
}
socketWorldObject.RemoveFromSocket();
return;
case SocketMessageType.CompleteUnsocket:
itemWorldObject = ItemId.GetWorldObject<IQSBOWItem>();
itemWorldObject.OnCompleteUnsocket();
return;
}
}
}
}

View File

@ -1,8 +1,9 @@
using HarmonyLib;
using OWML.Common;
using QSB.Events;
using QSB.ItemSync.Messages;
using QSB.ItemSync.WorldObjects.Items;
using QSB.ItemSync.WorldObjects.Sockets;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using QSB.Utility;
@ -20,22 +21,21 @@ namespace QSB.ItemSync.Patches
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.MoveItemToCarrySocket))]
public static bool ItemTool_MoveItemToCarrySocket(OWItem item)
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<IQSBOWItem>(item);
var itemId = qsbObj.ObjectId;
var qsbObj = item.GetWorldObject<IQSBOWItem>();
QSBPlayerManager.LocalPlayer.HeldItem = qsbObj;
QSBEventManager.FireEvent(EventNames.QSBMoveToCarry, itemId);
qsbObj.SendMessage(new MoveToCarryMessage());
return true;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.SocketItem))]
public static bool ItemTool_SocketItem(OWItem ____heldItem, OWItemSocket socket)
public static bool ItemTool_SocketItem(ItemTool __instance, OWItemSocket socket)
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<IQSBOWItem>(____heldItem);
var socketId = QSBWorldSync.GetWorldFromUnity<IQSBOWItemSocket>(socket).ObjectId;
var qsbObj = __instance._heldItem.GetWorldObject<IQSBOWItem>();
var socketId = socket.GetWorldObject<IQSBOWItemSocket>().ObjectId;
var itemId = qsbObj.ObjectId;
QSBPlayerManager.LocalPlayer.HeldItem = null;
QSBEventManager.FireEvent(EventNames.QSBSocketItem, socketId, itemId, SocketEventType.Socket);
new SocketItemMessage(SocketMessageType.Socket, socketId, itemId).Send();
return true;
}
@ -43,27 +43,27 @@ namespace QSB.ItemSync.Patches
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.StartUnsocketItem))]
public static bool ItemTool_StartUnsocketItem(OWItemSocket socket)
{
var item = QSBWorldSync.GetWorldFromUnity<IQSBOWItem>(socket.GetSocketedItem());
var item = socket.GetSocketedItem().GetWorldObject<IQSBOWItem>();
QSBPlayerManager.LocalPlayer.HeldItem = item;
var socketId = QSBWorldSync.GetWorldFromUnity<IQSBOWItemSocket>(socket).ObjectId;
QSBEventManager.FireEvent(EventNames.QSBSocketItem, socketId, 0, SocketEventType.StartUnsocket);
var socketId = socket.GetWorldObject<IQSBOWItemSocket>().ObjectId;
new SocketItemMessage(SocketMessageType.StartUnsocket, socketId).Send();
return true;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.CompleteUnsocketItem))]
public static bool ItemTool_CompleteUnsocketItem(OWItem ____heldItem)
public static bool ItemTool_CompleteUnsocketItem(ItemTool __instance)
{
var itemId = QSBWorldSync.GetWorldFromUnity<IQSBOWItem>(____heldItem).ObjectId;
QSBEventManager.FireEvent(EventNames.QSBSocketItem, 0, itemId, SocketEventType.CompleteUnsocket);
var itemId = __instance._heldItem.GetWorldObject<IQSBOWItem>().ObjectId;
new SocketItemMessage(SocketMessageType.CompleteUnsocket, itemId: itemId).Send();
return true;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.DropItem))]
public static bool ItemTool_DropItem(RaycastHit hit, OWRigidbody targetRigidbody, IItemDropTarget customDropTarget, ref OWItem ____heldItem)
public static bool ItemTool_DropItem(ItemTool __instance, RaycastHit hit, OWRigidbody targetRigidbody, IItemDropTarget customDropTarget)
{
Locator.GetPlayerAudioController().PlayDropItem(____heldItem.GetItemType());
Locator.GetPlayerAudioController().PlayDropItem(__instance._heldItem.GetItemType());
var hitGameObject = hit.collider.gameObject;
var gameObject2 = hitGameObject;
var sectorGroup = gameObject2.GetComponent<ISectorGroup>();
@ -77,9 +77,9 @@ namespace QSB.ItemSync.Patches
if (sectorGroup != null)
{
sector = sectorGroup.GetSector();
if (sector == null && sectorGroup is SectorCullGroup)
if (sector == null && sectorGroup is SectorCullGroup sectorCullGroup)
{
var controllingProxy = (sectorGroup as SectorCullGroup).GetControllingProxy();
var controllingProxy = sectorCullGroup.GetControllingProxy();
if (controllingProxy != null)
{
sector = controllingProxy.GetSector();
@ -90,16 +90,16 @@ namespace QSB.ItemSync.Patches
var parent = (customDropTarget == null)
? targetRigidbody.transform
: customDropTarget.GetItemDropTargetTransform(hit.collider.gameObject);
var objectId = QSBWorldSync.GetWorldFromUnity<IQSBOWItem>(____heldItem).ObjectId;
____heldItem.DropItem(hit.point, hit.normal, parent, sector, customDropTarget);
____heldItem = null;
var qsbItem = __instance._heldItem.GetWorldObject<IQSBOWItem>();
__instance._heldItem.DropItem(hit.point, hit.normal, parent, sector, customDropTarget);
__instance._heldItem = null;
QSBPlayerManager.LocalPlayer.HeldItem = null;
Locator.GetToolModeSwapper().UnequipTool();
var parentSector = parent.GetComponentInChildren<Sector>();
if (parentSector != null)
{
var localPos = parentSector.transform.InverseTransformPoint(hit.point);
QSBEventManager.FireEvent(EventNames.QSBDropItem, objectId, localPos, hit.normal, parentSector);
qsbItem.SendMessage(new DropItemMessage(localPos, hit.normal, parentSector));
return false;
}

View File

@ -1,6 +1,6 @@
namespace QSB.ItemSync
{
public enum SocketEventType
public enum SocketMessageType
{
StartUnsocket,
CompleteUnsocket,

View File

@ -36,7 +36,7 @@ namespace QSB.ItemSync.WorldObjects.Items
var initialSector = AttachedObject.GetSector();
if (initialSector != null)
{
InitialSector = QSBWorldSync.GetWorldFromUnity<QSBSector>(initialSector);
InitialSector = initialSector.GetWorldObject<QSBSector>();
}
if (InitialParent == null)
@ -46,7 +46,7 @@ namespace QSB.ItemSync.WorldObjects.Items
if (InitialParent?.GetComponent<OWItemSocket>() != null)
{
var qsbObj = QSBWorldSync.GetWorldFromUnity<IQSBOWItemSocket>(InitialParent.GetComponent<OWItemSocket>());
var qsbObj = InitialParent.GetComponent<OWItemSocket>().GetWorldObject<IQSBOWItemSocket>();
InitialSocket = qsbObj;
}
});

Some files were not shown because too many files have changed in this diff Show More