mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-26 09:35:26 +00:00
Merge pull request #289 from misternebula/animations
rework animations, fix many worldobject things
This commit is contained in:
commit
affcc9bef4
@ -1,11 +0,0 @@
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.Animation.Character
|
||||
{
|
||||
internal class CharacterAnimManager : WorldObjectManager
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
=> QSBWorldSync.Init<QSBCharacterAnimController, CharacterAnimController>();
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
public class CharacterAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnAnimatorIK", typeof(CharacterAnimationPatches), nameof(AnimController_OnAnimatorIK));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneEntry", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneEntry));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneExit", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneExit));
|
||||
}
|
||||
|
||||
public override void DoUnpatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnAnimatorIK");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnZoneExit");
|
||||
}
|
||||
|
||||
public static bool AnimController_OnAnimatorIK(
|
||||
CharacterAnimController __instance,
|
||||
float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
bool ____playerInHeadZone,
|
||||
bool ____inConversation,
|
||||
ref float ____currentLookWeight,
|
||||
ref Vector3 ____currentLookTarget,
|
||||
DampedSpring3D ___lookSpring,
|
||||
Animator ____animator,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance); // TODO : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
Vector3 position;
|
||||
if (____inConversation)
|
||||
{
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - {__instance.name} is in conversation with a null player! Defaulting to active camera.", MessageType.Error);
|
||||
position = Locator.GetActiveCamera().transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
position = player.CameraBody == null
|
||||
? Locator.GetActiveCamera().transform.position
|
||||
: player.CameraBody.transform.position;
|
||||
}
|
||||
}
|
||||
else if (!___lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0)
|
||||
{
|
||||
position = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.GetPlayersInHeadZone(), __instance.transform.position).CameraBody.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
position = QSBPlayerManager.GetClosestPlayerToWorldPoint(__instance.transform.position, true).CameraBody.transform.position;
|
||||
}
|
||||
|
||||
var localPosition = ____animator.transform.InverseTransformPoint(position);
|
||||
|
||||
var targetWeight = ___headTrackingWeight;
|
||||
if (___lookOnlyWhenTalking)
|
||||
{
|
||||
if (!____inConversation || qsbObj.GetPlayersInHeadZone().Count == 0)
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (qsbObj.GetPlayersInHeadZone().Count == 0)
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
|
||||
____currentLookWeight = Mathf.Lerp(____currentLookWeight, targetWeight, Time.deltaTime * 2f);
|
||||
____currentLookTarget = ___lookSpring.Update(____currentLookTarget, localPosition, Time.deltaTime);
|
||||
____animator.SetLookAtPosition(____animator.transform.TransformPoint(____currentLookTarget));
|
||||
____animator.SetLookAtWeight(____currentLookWeight);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneExit(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneEntry(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.Animation.Character.WorldObjects
|
||||
{
|
||||
internal class QSBCharacterAnimController : WorldObject<CharacterAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new List<PlayerInfo>();
|
||||
|
||||
public override void Init(CharacterAnimController controller, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = controller;
|
||||
}
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
|
||||
public void AddPlayerToHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Add(player);
|
||||
}
|
||||
|
||||
public void RemovePlayerFromHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (!_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Remove(player);
|
||||
}
|
||||
|
||||
public void StartConversation()
|
||||
{
|
||||
AttachedObject.SetValue("_inConversation", true);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnStartConversation");
|
||||
}
|
||||
|
||||
public void EndConversation()
|
||||
{
|
||||
AttachedObject.SetValue("_inConversation", false);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnEndConversation");
|
||||
}
|
||||
}
|
||||
}
|
8
QSB/Animation/NPC/AnimationEvent.cs
Normal file
8
QSB/Animation/NPC/AnimationEvent.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace QSB.Animation.NPC
|
||||
{
|
||||
internal enum AnimationEvent
|
||||
{
|
||||
StartConversation,
|
||||
EndConversation
|
||||
}
|
||||
}
|
20
QSB/Animation/NPC/CharacterAnimManager.cs
Normal file
20
QSB/Animation/NPC/CharacterAnimManager.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC
|
||||
{
|
||||
internal class CharacterAnimManager : WorldObjectManager
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
QSBWorldSync.Init<QSBCharacterAnimController, CharacterAnimController>();
|
||||
QSBWorldSync.Init<QSBTravelerController, TravelerController>();
|
||||
|
||||
//TODO : this is the wrong place to put this... move it to Conversations?
|
||||
QSBWorldSync.OldDialogueTrees.Clear();
|
||||
QSBWorldSync.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
|
||||
}
|
||||
}
|
||||
}
|
37
QSB/Animation/NPC/Events/NpcAnimationEvent.cs
Normal file
37
QSB/Animation/NPC/Events/NpcAnimationEvent.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.Animation.NPC.Events
|
||||
{
|
||||
internal class NpcAnimationEvent : QSBEvent<NpcAnimationMessage>
|
||||
{
|
||||
public override EventType Type => EventType.NpcAnimEvent;
|
||||
|
||||
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 NpcAnimationMessage
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
QSB/Animation/NPC/Events/NpcAnimationMessage.cs
Normal file
25
QSB/Animation/NPC/Events/NpcAnimationMessage.cs
Normal file
@ -0,0 +1,25 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
196
QSB/Animation/NPC/Patches/CharacterAnimationPatches.cs
Normal file
196
QSB/Animation/NPC/Patches/CharacterAnimationPatches.cs
Normal file
@ -0,0 +1,196 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.ConversationSync;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC.Patches
|
||||
{
|
||||
public class CharacterAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnAnimatorIK", typeof(CharacterAnimationPatches), nameof(AnimController_OnAnimatorIK));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneEntry", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneEntry));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneExit", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneExit));
|
||||
QSBCore.HarmonyHelper.AddPrefix<FacePlayerWhenTalking>("OnStartConversation", typeof(CharacterAnimationPatches), nameof(FacePlayerWhenTalking_OnStartConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("StartConversation", typeof(CharacterAnimationPatches), nameof(CharacterDialogueTree_StartConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("EndConversation", typeof(CharacterAnimationPatches), nameof(CharacterDialogueTree_EndConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<KidRockController>("Update", typeof(CharacterAnimationPatches), nameof(KidRockController_Update));
|
||||
}
|
||||
|
||||
public override void DoUnpatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnAnimatorIK");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnZoneEntry");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnZoneExit");
|
||||
QSBCore.HarmonyHelper.Unpatch<FacePlayerWhenTalking>("OnStartConversation");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("StartConversation");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("EndConversation");
|
||||
QSBCore.HarmonyHelper.Unpatch<KidRockController>("Update");
|
||||
}
|
||||
|
||||
public static bool AnimController_OnAnimatorIK(
|
||||
CharacterAnimController __instance,
|
||||
float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
bool ____playerInHeadZone,
|
||||
bool ____inConversation,
|
||||
ref float ____currentLookWeight,
|
||||
ref Vector3 ____currentLookTarget,
|
||||
DampedSpring3D ___lookSpring,
|
||||
Animator ____animator,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance); // TODO : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
PlayerInfo playerToUse;
|
||||
if (____inConversation)
|
||||
{
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - {__instance.name} is in conversation with a null player! Defaulting to active camera.", MessageType.Error);
|
||||
playerToUse = QSBPlayerManager.LocalPlayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerToUse = player.CameraBody == null
|
||||
? QSBPlayerManager.LocalPlayer
|
||||
: player;
|
||||
}
|
||||
}
|
||||
else if (!___lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0) // TODO : maybe this would be more fun if characters looked between players at random times? :P
|
||||
{
|
||||
playerToUse = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.GetPlayersInHeadZone(), __instance.transform.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
playerToUse = QSBPlayerManager.GetClosestPlayerToWorldPoint(__instance.transform.position, true);
|
||||
}
|
||||
|
||||
var localPosition = ____animator.transform.InverseTransformPoint(playerToUse.CameraBody.transform.position);
|
||||
|
||||
var targetWeight = ___headTrackingWeight;
|
||||
if (___lookOnlyWhenTalking)
|
||||
{
|
||||
if (!____inConversation
|
||||
|| qsbObj.GetPlayersInHeadZone().Count == 0
|
||||
|| !qsbObj.GetPlayersInHeadZone().Contains(playerToUse))
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (qsbObj.GetPlayersInHeadZone().Count == 0
|
||||
|| !qsbObj.GetPlayersInHeadZone().Contains(playerToUse))
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
|
||||
____currentLookWeight = Mathf.Lerp(____currentLookWeight, targetWeight, Time.deltaTime * 2f);
|
||||
____currentLookTarget = ___lookSpring.Update(____currentLookTarget, localPosition, Time.deltaTime);
|
||||
____animator.SetLookAtPosition(____animator.transform.TransformPoint(____currentLookTarget));
|
||||
____animator.SetLookAtWeight(____currentLookWeight);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneExit(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneEntry(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool FacePlayerWhenTalking_OnStartConversation(
|
||||
FacePlayerWhenTalking __instance,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No player talking to {____dialogueTree.name}!", MessageType.Error);
|
||||
return false;
|
||||
}
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
|
||||
var distance = player.Body.transform.position - __instance.transform.position;
|
||||
var vector2 = distance - Vector3.Project(distance, __instance.transform.up);
|
||||
var angle = Vector3.Angle(__instance.transform.forward, vector2) * Mathf.Sign(Vector3.Dot(vector2, __instance.transform.right));
|
||||
var axis = __instance.transform.parent.InverseTransformDirection(__instance.transform.up);
|
||||
var lhs = Quaternion.AngleAxis(angle, axis);
|
||||
__instance.GetType().GetMethod("FaceLocalRotation", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { lhs * __instance.transform.localRotation });
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CharacterDialogueTree_StartConversation(CharacterDialogueTree __instance)
|
||||
{
|
||||
var allNpcAnimControllers = QSBWorldSync.GetWorldObjects<INpcAnimController>();
|
||||
var ownerOfThis = allNpcAnimControllers.FirstOrDefault(x => x.GetDialogueTree() == __instance);
|
||||
if (ownerOfThis == default)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var id = QSBWorldSync.GetIdFromTypeSubset(ownerOfThis);
|
||||
QSBEventManager.FireEvent(EventNames.QSBNpcAnimEvent, AnimationEvent.StartConversation, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CharacterDialogueTree_EndConversation(CharacterDialogueTree __instance)
|
||||
{
|
||||
var allNpcAnimControllers = QSBWorldSync.GetWorldObjects<INpcAnimController>();
|
||||
var ownerOfThis = allNpcAnimControllers.FirstOrDefault(x => x.GetDialogueTree() == __instance);
|
||||
if (ownerOfThis == default)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var id = QSBWorldSync.GetIdFromTypeSubset(ownerOfThis);
|
||||
QSBEventManager.FireEvent(EventNames.QSBNpcAnimEvent, AnimationEvent.EndConversation, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool KidRockController_Update(
|
||||
KidRockController __instance,
|
||||
bool ____throwingRock,
|
||||
CharacterDialogueTree ____dialogueTree,
|
||||
float ____nextThrowTime)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var qsbObj = QSBWorldSync.GetWorldObjects<QSBCharacterAnimController>().First(x => x.GetDialogueTree() == ____dialogueTree);
|
||||
|
||||
if (!____throwingRock && !qsbObj.InConversation() && Time.time > ____nextThrowTime)
|
||||
{
|
||||
__instance.GetType().GetMethod("StartRockThrow", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
10
QSB/Animation/NPC/WorldObjects/INpcAnimController.cs
Normal file
10
QSB/Animation/NPC/WorldObjects/INpcAnimController.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
public interface INpcAnimController
|
||||
{
|
||||
CharacterDialogueTree GetDialogueTree();
|
||||
void StartConversation();
|
||||
void EndConversation();
|
||||
bool InConversation();
|
||||
}
|
||||
}
|
25
QSB/Animation/NPC/WorldObjects/NpcAnimController.cs
Normal file
25
QSB/Animation/NPC/WorldObjects/NpcAnimController.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal abstract class NpcAnimController<T> : WorldObject<T>, INpcAnimController
|
||||
where T : MonoBehaviour
|
||||
{
|
||||
public override void Init(T controller, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = controller;
|
||||
}
|
||||
|
||||
public abstract CharacterDialogueTree GetDialogueTree();
|
||||
|
||||
public virtual void StartConversation()
|
||||
=> QSBWorldSync.RaiseEvent(GetDialogueTree(), "OnStartConversation");
|
||||
|
||||
public virtual void EndConversation()
|
||||
=> QSBWorldSync.RaiseEvent(GetDialogueTree(), "OnEndConversation");
|
||||
|
||||
public abstract bool InConversation();
|
||||
}
|
||||
}
|
38
QSB/Animation/NPC/WorldObjects/QSBCharacterAnimController.cs
Normal file
38
QSB/Animation/NPC/WorldObjects/QSBCharacterAnimController.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Player;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBCharacterAnimController : NpcAnimController<CharacterAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new List<PlayerInfo>();
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
|
||||
public void AddPlayerToHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Add(player);
|
||||
}
|
||||
|
||||
public void RemovePlayerFromHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (!_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Remove(player);
|
||||
}
|
||||
|
||||
public override CharacterDialogueTree GetDialogueTree()
|
||||
=> AttachedObject.GetValue<CharacterDialogueTree>("_dialogueTree");
|
||||
|
||||
public override bool InConversation()
|
||||
=> AttachedObject.GetValue<bool>("_inConversation");
|
||||
}
|
||||
}
|
13
QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs
Normal file
13
QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using OWML.Utils;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBTravelerController : NpcAnimController<TravelerController>
|
||||
{
|
||||
public override CharacterDialogueTree GetDialogueTree()
|
||||
=> AttachedObject.GetValue<CharacterDialogueTree>("_dialogueSystem");
|
||||
|
||||
public override bool InConversation()
|
||||
=> AttachedObject.GetValue<bool>("_talking");
|
||||
}
|
||||
}
|
@ -37,9 +37,9 @@ namespace QSB.ConversationSync
|
||||
public uint GetPlayerTalkingToTree(CharacterDialogueTree tree)
|
||||
{
|
||||
var treeIndex = QSBWorldSync.OldDialogueTrees.IndexOf(tree);
|
||||
return QSBPlayerManager.PlayerList.All(x => x.CurrentDialogueID != treeIndex)
|
||||
return QSBPlayerManager.PlayerList.All(x => x.CurrentCharacterDialogueTreeId != treeIndex)
|
||||
? uint.MaxValue
|
||||
: QSBPlayerManager.PlayerList.First(x => x.CurrentDialogueID == treeIndex).PlayerId;
|
||||
: QSBPlayerManager.PlayerList.First(x => x.CurrentCharacterDialogueTreeId == treeIndex).PlayerId;
|
||||
}
|
||||
|
||||
public void SendPlayerOption(string text) =>
|
||||
@ -122,6 +122,7 @@ namespace QSB.ConversationSync
|
||||
lookAt.SetValue("_localFacingVector", Vector3.back);
|
||||
lookAt.SetValue("_localRotationAxis", Vector3.up);
|
||||
newBox.GetComponent<Text>().text = text;
|
||||
newBox.AddComponent<ZOverride>();
|
||||
newBox.SetActive(true);
|
||||
return newBox;
|
||||
}
|
||||
|
@ -1,12 +1,8 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ConversationSync.Events
|
||||
{
|
||||
@ -17,19 +13,19 @@ namespace QSB.ConversationSync.Events
|
||||
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 charId, uint playerId, bool state) => SendEvent(CreateMessage(charId, playerId, state));
|
||||
private void Handler(int objId, uint playerId, bool state) => SendEvent(CreateMessage(objId, playerId, state));
|
||||
|
||||
private ConversationStartEndMessage CreateMessage(int charId, uint playerId, bool state) => new ConversationStartEndMessage
|
||||
private ConversationStartEndMessage CreateMessage(int objId, uint playerId, bool state) => new ConversationStartEndMessage
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
CharacterId = charId,
|
||||
TreeId = objId,
|
||||
PlayerId = playerId,
|
||||
State = state
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, ConversationStartEndMessage message)
|
||||
{
|
||||
if (message.CharacterId == -1)
|
||||
if (message.TreeId == -1)
|
||||
{
|
||||
DebugLog.ToConsole("Warning - Received conv. start/end event with char id -1.", MessageType.Warning);
|
||||
return;
|
||||
@ -40,44 +36,32 @@ namespace QSB.ConversationSync.Events
|
||||
return;
|
||||
}
|
||||
|
||||
var dialogueTree = QSBWorldSync.OldDialogueTrees[message.CharacterId];
|
||||
var animController = Resources.FindObjectsOfTypeAll<CharacterAnimController>().FirstOrDefault(x => x.GetValue<CharacterDialogueTree>("_dialogueTree") == dialogueTree);
|
||||
|
||||
if (animController == default(CharacterAnimController))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var dialogueTree = QSBWorldSync.OldDialogueTrees[message.TreeId];
|
||||
|
||||
if (message.State)
|
||||
{
|
||||
StartConversation(message.PlayerId, message.CharacterId, animController, dialogueTree);
|
||||
StartConversation(message.PlayerId, message.TreeId, dialogueTree);
|
||||
}
|
||||
else
|
||||
{
|
||||
EndConversation(message.PlayerId, animController, dialogueTree);
|
||||
EndConversation(message.PlayerId, dialogueTree);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartConversation(
|
||||
uint playerId,
|
||||
int characterId,
|
||||
CharacterAnimController controller,
|
||||
int dialogueTreeId,
|
||||
CharacterDialogueTree tree)
|
||||
{
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueID = characterId;
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(controller);
|
||||
qsbObj.StartConversation();
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentCharacterDialogueTreeId = dialogueTreeId;
|
||||
tree.GetInteractVolume().DisableInteraction();
|
||||
}
|
||||
|
||||
private void EndConversation(
|
||||
uint playerId,
|
||||
CharacterAnimController controller,
|
||||
CharacterDialogueTree tree)
|
||||
{
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueID = -1;
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(controller);
|
||||
qsbObj.EndConversation();
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentCharacterDialogueTreeId = -1;
|
||||
tree.GetInteractVolume().EnableInteraction();
|
||||
}
|
||||
}
|
||||
|
@ -5,14 +5,14 @@ namespace QSB.ConversationSync.Events
|
||||
{
|
||||
public class ConversationStartEndMessage : PlayerMessage
|
||||
{
|
||||
public int CharacterId { get; set; }
|
||||
public int TreeId { get; set; }
|
||||
public uint PlayerId { get; set; }
|
||||
public bool State { get; set; }
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
CharacterId = reader.ReadInt32();
|
||||
TreeId = reader.ReadInt32();
|
||||
PlayerId = reader.ReadUInt32();
|
||||
State = reader.ReadBoolean();
|
||||
}
|
||||
@ -20,7 +20,7 @@ namespace QSB.ConversationSync.Events
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(CharacterId);
|
||||
writer.Write(TreeId);
|
||||
writer.Write(PlayerId);
|
||||
writer.Write(State);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
QSBCore.HarmonyHelper.AddPostfix<DialogueNode>("GetNextPage", typeof(ConversationPatches), nameof(Node_GetNextPage));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("InputDialogueOption", typeof(ConversationPatches), nameof(Tree_InputDialogueOption));
|
||||
QSBCore.HarmonyHelper.AddPostfix<CharacterDialogueTree>("StartConversation", typeof(ConversationPatches), nameof(Tree_StartConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("StartConversation", typeof(ConversationPatches), nameof(Tree_StartConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("EndConversation", typeof(ConversationPatches), nameof(Tree_EndConversation));
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Index for tree {__instance.name} was -1.", MessageType.Warning);
|
||||
}
|
||||
QSBPlayerManager.LocalPlayer.CurrentDialogueID = index;
|
||||
QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId = index;
|
||||
ConversationManager.Instance.SendConvState(index, true);
|
||||
}
|
||||
|
||||
@ -44,14 +44,14 @@ namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (QSBPlayerManager.LocalPlayer.CurrentDialogueID == -1)
|
||||
if (QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId == -1)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Ending conversation with CurrentDialogueId of -1! Called from {__instance.name}", MessageType.Warning);
|
||||
return true;
|
||||
}
|
||||
ConversationManager.Instance.SendConvState(QSBPlayerManager.LocalPlayer.CurrentDialogueID, false);
|
||||
ConversationManager.Instance.CloseBoxCharacter(QSBPlayerManager.LocalPlayer.CurrentDialogueID);
|
||||
QSBPlayerManager.LocalPlayer.CurrentDialogueID = -1;
|
||||
ConversationManager.Instance.SendConvState(QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId, false);
|
||||
ConversationManager.Instance.CloseBoxCharacter(QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId);
|
||||
QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId = -1;
|
||||
ConversationManager.Instance.CloseBoxPlayer();
|
||||
return true;
|
||||
}
|
||||
@ -74,8 +74,8 @@ namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
var key = ____name + ____listPagesToDisplay[____currentPage];
|
||||
// Sending key so translation can be done on client side - should make different language-d clients compatible
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBPlayerManager.LocalPlayer.CurrentDialogueID != -1,
|
||||
() => ConversationManager.Instance.SendCharacterDialogue(QSBPlayerManager.LocalPlayer.CurrentDialogueID, key));
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId != -1,
|
||||
() => ConversationManager.Instance.SendCharacterDialogue(QSBPlayerManager.LocalPlayer.CurrentCharacterDialogueTreeId, key));
|
||||
}
|
||||
}
|
||||
}
|
@ -63,5 +63,6 @@
|
||||
public static string QSBAnimTrigger = "QSBAnimTrigger";
|
||||
public static string QSBEnterHeadZone = "QSBEnterHeadZone";
|
||||
public static string QSBExitHeadZone = "QSBExitHeadZone";
|
||||
public static string QSBNpcAnimEvent = "QSBNpcAnimEvent";
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@
|
||||
CampfireState,
|
||||
Roasting,
|
||||
MarshmallowEvent,
|
||||
AnimTrigger
|
||||
AnimTrigger,
|
||||
NpcAnimEvent
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.NPC.Events;
|
||||
using QSB.Animation.Player.Events;
|
||||
using QSB.CampfireSync.Events;
|
||||
using QSB.ConversationSync.Events;
|
||||
@ -75,7 +76,8 @@ namespace QSB.Events
|
||||
new DialogueConditionEvent(),
|
||||
new RevealFactEvent(),
|
||||
new IdentifyFrequencyEvent(),
|
||||
new IdentifySignalEvent()
|
||||
new IdentifySignalEvent(),
|
||||
new NpcAnimationEvent()
|
||||
};
|
||||
|
||||
if (UnitTestDetector.IsInUnitTest)
|
||||
|
@ -79,7 +79,6 @@ namespace QSB.OrbSync.Events
|
||||
DebugLog.ToConsole($"Error - Orb identity is null. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
DebugLog.DebugWrite($"Orb {message.ObjectId} to owner {message.FromId}");
|
||||
if (orbIdentity.ClientAuthorityOwner != null && orbIdentity.ClientAuthorityOwner != fromPlayer)
|
||||
{
|
||||
orbIdentity.RemoveClientAuthority(orbIdentity.ClientAuthorityOwner);
|
||||
@ -105,7 +104,6 @@ namespace QSB.OrbSync.Events
|
||||
DebugLog.ToConsole($"Error - No NomaiOrbTransformSync has AttachedOrb with objectId {message.ObjectId}!");
|
||||
return;
|
||||
}
|
||||
DebugLog.DebugWrite($"Orb {message.ObjectId} to owner {message.FromId}");
|
||||
var orb = NomaiOrbTransformSync.OrbTransformSyncs
|
||||
.First(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].gameObject);
|
||||
orb.enabled = true;
|
||||
|
@ -22,7 +22,7 @@ namespace QSB.OrbSync.TransformSync
|
||||
|
||||
private void OnReady()
|
||||
{
|
||||
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count < _index)
|
||||
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count <= _index)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - OldOrbList is null or does not contain index {_index}.", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
@ -33,7 +33,7 @@ namespace QSB.OrbSync.TransformSync
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
OrbTransformSyncs.Remove(this);
|
||||
base.OnDestroy();
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.NPC.Patches;
|
||||
using QSB.Animation.Patches;
|
||||
using QSB.CampfireSync.Patches;
|
||||
using QSB.ConversationSync.Patches;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.PoolSync;
|
||||
using QSB.Utility;
|
||||
|
@ -40,7 +40,7 @@ namespace QSB.Player
|
||||
public QSBCampfire Campfire { get; set; }
|
||||
|
||||
// Conversation
|
||||
public int CurrentDialogueID { get; set; }
|
||||
public int CurrentCharacterDialogueTreeId { get; set; }
|
||||
public GameObject CurrentDialogueBox { get; set; }
|
||||
|
||||
// Animation
|
||||
@ -56,7 +56,7 @@ namespace QSB.Player
|
||||
public PlayerInfo(uint id)
|
||||
{
|
||||
PlayerId = id;
|
||||
CurrentDialogueID = -1;
|
||||
CurrentCharacterDialogueTreeId = -1;
|
||||
}
|
||||
|
||||
public void UpdateStateObjects()
|
||||
|
@ -102,9 +102,15 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Animation\Character\CharacterAnimManager.cs" />
|
||||
<Compile Include="Animation\Character\Patches\CharacterAnimationPatches.cs" />
|
||||
<Compile Include="Animation\Character\WorldObjects\QSBCharacterAnimController.cs" />
|
||||
<Compile Include="Animation\NPC\AnimationEvent.cs" />
|
||||
<Compile Include="Animation\NPC\CharacterAnimManager.cs" />
|
||||
<Compile Include="Animation\NPC\Events\NpcAnimationEvent.cs" />
|
||||
<Compile Include="Animation\NPC\Events\NpcAnimationMessage.cs" />
|
||||
<Compile Include="Animation\NPC\Patches\CharacterAnimationPatches.cs" />
|
||||
<Compile Include="Animation\NPC\WorldObjects\INpcAnimController.cs" />
|
||||
<Compile Include="Animation\NPC\WorldObjects\NpcAnimController.cs" />
|
||||
<Compile Include="Animation\NPC\WorldObjects\QSBCharacterAnimController.cs" />
|
||||
<Compile Include="Animation\NPC\WorldObjects\QSBTravelerController.cs" />
|
||||
<Compile Include="Animation\Player\AnimationSync.cs" />
|
||||
<Compile Include="Animation\Player\AnimationType.cs" />
|
||||
<Compile Include="Animation\Player\Events\AnimationTriggerEvent.cs" />
|
||||
@ -273,7 +279,7 @@
|
||||
<Compile Include="SectorSync\SectorSync.cs" />
|
||||
<Compile Include="Utility\CustomCallbacks.cs" />
|
||||
<Compile Include="Utility\DebugBoxManager.cs" />
|
||||
<Compile Include="Utility\DebugZOverride.cs" />
|
||||
<Compile Include="Utility\ZOverride.cs" />
|
||||
<Compile Include="Utility\Extensions.cs" />
|
||||
<Compile Include="Utility\GlobalMessenger4Args.cs" />
|
||||
<Compile Include="Utility\GlobalMessenger5Args.cs" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Character;
|
||||
using QSB.Animation.NPC;
|
||||
using QSB.CampfireSync;
|
||||
using QSB.ConversationSync;
|
||||
using QSB.ElevatorSync;
|
||||
@ -179,7 +179,9 @@ namespace QSB
|
||||
foreach (var player in QSBPlayerManager.PlayerList.Where(x => x.PlayerStates.IsReady))
|
||||
{
|
||||
var networkTransform = player.TransformSync;
|
||||
GUI.Label(new Rect(220, offset, 400f, 20f), $"- {player.PlayerId} : {networkTransform.transform.localPosition} from {networkTransform.ReferenceSector.Name}");
|
||||
var sector = networkTransform.ReferenceSector;
|
||||
|
||||
GUI.Label(new Rect(220, offset, 400f, 20f), $"- {player.PlayerId} : {networkTransform.transform.localPosition} from {(sector == null ? "NULL" : sector.Name)}");
|
||||
offset += _debugLineSpacing;
|
||||
}
|
||||
|
||||
@ -244,10 +246,6 @@ namespace QSB
|
||||
QSBNetworkManager.Instance.networkPort = Port;
|
||||
}
|
||||
DebugMode = config.GetSettingsValue<bool>("debugMode");
|
||||
if (!DebugMode)
|
||||
{
|
||||
FindObjectsOfType<DebugZOverride>().ToList().ForEach(x => Destroy(x.gameObject));
|
||||
}
|
||||
ShowLinesInDebug = config.GetSettingsValue<bool>("showLinesInDebug");
|
||||
SocketedObjToDebug = config.GetSettingsValue<int>("socketedObjToDebug");
|
||||
}
|
||||
|
@ -91,7 +91,6 @@ namespace QSB
|
||||
spawnPrefabs.Add(_stickPrefab);
|
||||
|
||||
ConfigureNetworkManager();
|
||||
QSBSceneManager.OnUniverseSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void SetupNetworkId(GameObject go)
|
||||
@ -114,15 +113,6 @@ namespace QSB
|
||||
Destroy(go.GetComponent<NetworkIdentity>());
|
||||
}
|
||||
|
||||
public void OnDestroy() =>
|
||||
QSBSceneManager.OnUniverseSceneLoaded -= OnSceneLoaded;
|
||||
|
||||
private void OnSceneLoaded(OWScene scene)
|
||||
{
|
||||
QSBWorldSync.OldDialogueTrees.Clear();
|
||||
QSBWorldSync.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
|
||||
}
|
||||
|
||||
private void ConfigureNetworkManager()
|
||||
{
|
||||
networkAddress = QSBCore.DefaultServerIP;
|
||||
|
@ -25,7 +25,8 @@ namespace QSB
|
||||
DebugLog.DebugWrite($"COMPLETE SCENE LOAD ({oldScene} -> {newScene})", MessageType.Info);
|
||||
if (QSBCore.IsInMultiplayer)
|
||||
{
|
||||
WorldObjectManager.Rebuild(newScene);
|
||||
// So objects have time to be deleted, made, whatever
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() => WorldObjectManager.Rebuild(newScene));
|
||||
}
|
||||
var universe = InUniverse(newScene);
|
||||
OnSceneLoaded?.SafeInvoke(newScene, universe);
|
||||
|
@ -22,7 +22,7 @@ namespace QSB.QuantumSync.Events
|
||||
|
||||
public override bool CheckMessage(bool isServer, QuantumAuthorityMessage message)
|
||||
{
|
||||
if (!QuantumManager.Instance.IsReady)
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -63,10 +63,13 @@ namespace QSB.QuantumSync.Patches
|
||||
ref QuantumSocket ____recentlyObscuredSocket,
|
||||
QuantumSocket ____occupiedSocket)
|
||||
{
|
||||
var socketedWorldObject = QSBWorldSync.GetWorldFromUnity<QSBSocketedQuantumObject, SocketedQuantumObject>(__instance);
|
||||
if (socketedWorldObject.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
|
||||
if (WorldObjectManager.AllReady)
|
||||
{
|
||||
return false;
|
||||
var socketedWorldObject = QSBWorldSync.GetWorldFromUnity<QSBSocketedQuantumObject, SocketedQuantumObject>(__instance);
|
||||
if (socketedWorldObject.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var socket in ____childSockets)
|
||||
@ -160,6 +163,11 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
public static void Socketed_MoveToSocket(SocketedQuantumObject __instance, QuantumSocket socket)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (socket == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to move {__instance.name} to a null socket!", MessageType.Error);
|
||||
@ -193,10 +201,14 @@ namespace QSB.QuantumSync.Patches
|
||||
ref Transform[] ____shuffledObjects,
|
||||
ref bool __result)
|
||||
{
|
||||
var shuffleWorldObject = QSBWorldSync.GetWorldFromUnity<QSBQuantumShuffleObject, QuantumShuffleObject>(__instance);
|
||||
if (shuffleWorldObject.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
|
||||
QSBQuantumShuffleObject shuffleWorldObject = default;
|
||||
if (WorldObjectManager.AllReady)
|
||||
{
|
||||
return false;
|
||||
shuffleWorldObject = QSBWorldSync.GetWorldFromUnity<QSBQuantumShuffleObject, QuantumShuffleObject>(__instance);
|
||||
if (shuffleWorldObject.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
____indexList.Clear();
|
||||
@ -208,20 +220,32 @@ namespace QSB.QuantumSync.Patches
|
||||
____indexList[i] = ____indexList[random];
|
||||
____indexList[random] = temp;
|
||||
}
|
||||
|
||||
|
||||
for (var j = 0; j < ____shuffledObjects.Length; j++)
|
||||
{
|
||||
____shuffledObjects[j].localPosition = ____localPositions[____indexList[j]];
|
||||
}
|
||||
QSBEventManager.FireEvent(
|
||||
|
||||
if (WorldObjectManager.AllReady)
|
||||
{
|
||||
QSBEventManager.FireEvent(
|
||||
EventNames.QSBQuantumShuffle,
|
||||
shuffleWorldObject.ObjectId,
|
||||
____indexList.ToArray());
|
||||
__result = true;
|
||||
__result = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool MultiState_Start(MultiStateQuantumObject __instance, Sector ____sector, bool ____collapseOnStart)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBMultiStateQuantumObject, MultiStateQuantumObject>(__instance);
|
||||
if (qsbObj.ControllingPlayer == 0)
|
||||
{
|
||||
@ -250,6 +274,11 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
public static bool MultiState_ChangeQuantumState(MultiStateQuantumObject __instance)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBMultiStateQuantumObject, MultiStateQuantumObject>(__instance);
|
||||
if (qsbObj.ControllingPlayer == 0 && qsbObj.CurrentState == -1)
|
||||
{
|
||||
@ -261,6 +290,11 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
public static void QuantumState_SetVisible(QuantumState __instance, bool visible)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!visible)
|
||||
{
|
||||
return;
|
||||
|
@ -40,7 +40,7 @@ namespace QSB.QuantumSync.Patches
|
||||
GameObject[] ____deactivateAtEye
|
||||
)
|
||||
{
|
||||
if (QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck) && !QuantumManager.Instance.Shrine.IsPlayerInDarkness())
|
||||
if (QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck) && !QuantumManager.Shrine.IsPlayerInDarkness())
|
||||
{
|
||||
if (!skipInstantVisibilityCheck)
|
||||
{
|
||||
|
@ -13,9 +13,8 @@ namespace QSB.QuantumSync
|
||||
{
|
||||
internal class QuantumManager : WorldObjectManager
|
||||
{
|
||||
public static QuantumShrine Shrine { get; private set; }
|
||||
public static QuantumManager Instance { get; private set; }
|
||||
public QuantumShrine Shrine;
|
||||
public bool IsReady;
|
||||
|
||||
public override void Awake()
|
||||
{
|
||||
@ -44,7 +43,6 @@ namespace QSB.QuantumSync
|
||||
{
|
||||
Shrine = Resources.FindObjectsOfTypeAll<QuantumShrine>().First();
|
||||
}
|
||||
IsReady = true;
|
||||
}
|
||||
|
||||
public void PlayerLeave(uint playerId)
|
||||
@ -117,6 +115,10 @@ namespace QSB.QuantumSync
|
||||
|
||||
public static IEnumerable<PlayerInfo> GetEntangledPlayers(QuantumObject obj)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return Enumerable.Empty<PlayerInfo>();
|
||||
}
|
||||
var worldObj = GetObject(obj);
|
||||
return QSBPlayerManager.PlayerList.Where(x => x.EntangledObject == worldObj);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
component.MoveToRelativeLocation(location, AttachedObject.transform);
|
||||
}
|
||||
|
||||
if (QuantumManager.Instance.Shrine != AttachedObject)
|
||||
if (QuantumManager.Shrine != AttachedObject)
|
||||
{
|
||||
AttachedObject.transform.localRotation = message.LocalRotation;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace QSB.TransformSync
|
||||
protected abstract GameObject InitLocalTransform();
|
||||
protected abstract GameObject InitRemoteTransform();
|
||||
|
||||
private bool _isInitialized;
|
||||
protected bool _isInitialized;
|
||||
private const float SmoothTime = 0.1f;
|
||||
protected virtual float DistanceLeeway { get; } = 5f;
|
||||
private float _previousDistance;
|
||||
@ -62,6 +62,10 @@ namespace QSB.TransformSync
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject);
|
||||
}
|
||||
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
@ -46,15 +46,30 @@ namespace QSB.TransformSync
|
||||
/// Sets the position of the INVISIBLE transform to be correct, according to the reference sector and the position of the VISIBLE transform.
|
||||
/// </summary>
|
||||
/// <param name="worldPosition">The world position of the VISIBLE transform.</param>
|
||||
public void EncodePosition(Vector3 worldPosition)
|
||||
=> SetPosition(_referenceTransform.InverseTransformPoint(worldPosition));
|
||||
public void EncodePosition(Vector3 worldPosition)
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - _referenceTransform has not been set for {_attachedTransform.name}", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
SetPosition(_referenceTransform.InverseTransformPoint(worldPosition));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the rotation of the INVISIBLE transform to be correct, according to the reference sector and the rotation of the VISIBLE transform.
|
||||
/// </summary>
|
||||
/// <param name="worldPosition">The world rotation of the VISIBLE transform.</param>
|
||||
public void EncodeRotation(Quaternion worldRotation)
|
||||
=> SetRotation(_referenceTransform.InverseTransformRotation(worldRotation));
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - _referenceTransform has not been set for {_attachedTransform.name}", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
SetRotation(_referenceTransform.InverseTransformRotation(worldRotation));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the local position the VISIBLE transform should be set to, from the INVISIBLE transform.
|
||||
|
@ -31,7 +31,15 @@ namespace QSB.TransformSync
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
SetReferenceTransform(SectorSync.GetClosestSector(AttachedObject.transform).Transform);
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
{
|
||||
SetReferenceTransform(closestSector.Transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
|
@ -52,7 +52,7 @@ namespace QSB.TransformSync
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse) =>
|
||||
protected void OnSceneLoaded(OWScene scene, bool isInUniverse) =>
|
||||
_isInitialized = false;
|
||||
|
||||
protected virtual void Init()
|
||||
|
@ -33,7 +33,7 @@ namespace QSB.Utility
|
||||
lookAt.SetValue("_localFacingVector", Vector3.back);
|
||||
lookAt.SetValue("_localRotationAxis", Vector3.up);
|
||||
newBox.GetComponent<Text>().text = text;
|
||||
newBox.AddComponent<DebugZOverride>();
|
||||
newBox.AddComponent<ZOverride>();
|
||||
newBox.SetActive(true);
|
||||
return newBox;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ using UnityEngine.UI;
|
||||
|
||||
namespace QSB.Utility
|
||||
{
|
||||
public class DebugZOverride : MonoBehaviour
|
||||
public class ZOverride : MonoBehaviour
|
||||
{
|
||||
private const string shaderTestMode = "unity_GUIZTestMode";
|
||||
private readonly UnityEngine.Rendering.CompareFunction desiredUIComparison = UnityEngine.Rendering.CompareFunction.Always;
|
@ -4,6 +4,7 @@ using QSB.OrbSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
@ -54,7 +55,7 @@ namespace QSB.WorldSync
|
||||
}
|
||||
if (!WorldObjectsToUnityObjects.ContainsKey(unityObject))
|
||||
{
|
||||
DebugLog.ToConsole($"Error - WorldObjectsToUnityObjects does not contain \"{unityObject.name}\"!", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - WorldObjectsToUnityObjects does not contain \"{unityObject.name}\"! Called from {new StackTrace().GetFrame(1).GetMethod().Name}", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
return WorldObjectsToUnityObjects[unityObject] as TWorldObject;
|
||||
|
@ -7,11 +7,22 @@ namespace QSB.WorldSync
|
||||
{
|
||||
private static readonly List<WorldObjectManager> _managers = new List<WorldObjectManager>();
|
||||
|
||||
public static bool AllReady { get; private set; }
|
||||
|
||||
public virtual void Awake()
|
||||
=> _managers.Add(this);
|
||||
{
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
_managers.Add(this);
|
||||
}
|
||||
|
||||
public virtual void OnDestroy()
|
||||
=> _managers.Remove(this);
|
||||
{
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
_managers.Remove(this);
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool inUniverse)
|
||||
=> AllReady = false;
|
||||
|
||||
public static void Rebuild(OWScene scene)
|
||||
{
|
||||
@ -19,6 +30,7 @@ namespace QSB.WorldSync
|
||||
{
|
||||
manager.RebuildWorldObjects(scene);
|
||||
}
|
||||
AllReady = true;
|
||||
}
|
||||
|
||||
protected abstract void RebuildWorldObjects(OWScene scene);
|
||||
|
@ -80,7 +80,7 @@ QSB relies on exact orders of objects found using Resources.FindObjectsOfTypeAll
|
||||
| Marshmallow roasting | Yes |
|
||||
| Meteors | No |
|
||||
| Museum statue | Yes |
|
||||
| NPC animations | Kind of |
|
||||
| NPC animations | Yes |
|
||||
| Nomai orbs | Yes |
|
||||
| Nomai shuttle | Kind of |
|
||||
| Orbital Probe Cannon (direction) | No |
|
||||
@ -90,6 +90,7 @@ QSB relies on exact orders of objects found using Resources.FindObjectsOfTypeAll
|
||||
| Projection pools | Yes |
|
||||
| Quantum objects | Yes |
|
||||
| Ship log | Yes |
|
||||
| Solanum | No |
|
||||
| Timber Hearth satellite | No |
|
||||
| Tornadoes | No |
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user