221 lines
6.6 KiB
C#
Raw Normal View History

2021-04-28 00:22:08 +01:00
using OWML.Common;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.Utility;
using QuantumUNET.Transport;
2021-07-05 19:56:55 +01:00
using System;
using System.Collections.Generic;
2021-04-28 00:22:08 +01:00
using System.Linq;
using UnityEngine;
2021-05-02 13:59:39 +01:00
namespace QSB.Syncs.TransformSync
2021-04-28 00:22:08 +01:00
{
2021-04-28 10:02:16 +01:00
/*
2021-07-08 18:14:16 +01:00
* Rewrite number : 7
2021-04-28 10:02:16 +01:00
* God has cursed me for my hubris, and my work is never finished.
*/
2021-07-07 23:54:09 +01:00
public abstract class BaseTransformSync : SyncBase
2021-04-28 00:22:08 +01:00
{
2021-07-05 19:56:55 +01:00
private readonly static Dictionary<PlayerInfo, Dictionary<Type, BaseTransformSync>> _storedTransformSyncs = new Dictionary<PlayerInfo, Dictionary<Type, BaseTransformSync>>();
public static T GetPlayers<T>(PlayerInfo player)
2021-07-07 09:02:23 +01:00
where T : BaseTransformSync
2021-07-05 19:56:55 +01:00
{
var dictOfOwnedSyncs = _storedTransformSyncs[player];
var wantedSync = dictOfOwnedSyncs[typeof(T)];
if (wantedSync == default)
{
DebugLog.ToConsole($"Error - _storedTransformSyncs does not contain type:{typeof(T)} under player {player.PlayerId}. Attempting to find manually...", MessageType.Error);
var allSyncs = Resources.FindObjectsOfTypeAll<T>();
wantedSync = allSyncs.First(x => x.Player == player);
if (wantedSync == default)
{
DebugLog.ToConsole($"Error - Could not find type:{typeof(T)} for player {player.PlayerId} manually!", MessageType.Error);
return default;
}
}
return (T)wantedSync;
}
2021-04-28 00:22:08 +01:00
public virtual void Start()
{
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
DontDestroyOnLoad(gameObject);
_intermediaryTransform = new IntermediaryTransform(transform);
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
2021-07-05 19:56:55 +01:00
if (!_storedTransformSyncs.ContainsKey(Player))
{
_storedTransformSyncs.Add(Player, new Dictionary<Type, BaseTransformSync>());
}
var playerDict = _storedTransformSyncs[Player];
playerDict[GetType()] = this;
DebugLog.DebugWrite($"Added T:{GetType().Name} to dict of player {Player.PlayerId}", MessageType.Info);
2021-04-28 00:22:08 +01:00
}
protected virtual void OnDestroy()
{
if (!HasAuthority && AttachedObject != null)
{
2021-05-19 11:17:37 +01:00
Destroy(AttachedObject.gameObject);
2021-04-28 00:22:08 +01:00
}
2021-06-18 22:38:32 +01:00
2021-04-28 00:22:08 +01:00
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
2021-07-05 19:56:55 +01:00
var playerDict = _storedTransformSyncs[Player];
playerDict.Remove(GetType());
DebugLog.DebugWrite($"Removed T:{GetType().Name} from dict of player {Player.PlayerId}", MessageType.Info);
2021-04-28 00:22:08 +01:00
}
2021-06-19 11:26:05 +01:00
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
=> _isInitialized = false;
2021-04-28 00:22:08 +01:00
2021-07-07 23:04:00 +01:00
protected override void Init()
2021-04-28 00:22:08 +01:00
{
if (!QSBSceneManager.IsInUniverse)
{
DebugLog.ToConsole($"Error - {_logName} is being init-ed when not in the universe!", MessageType.Error);
}
2021-06-18 22:38:32 +01:00
if (!HasAuthority && AttachedObject != null)
{
2021-05-19 11:17:37 +01:00
Destroy(AttachedObject.gameObject);
}
2021-06-18 22:38:32 +01:00
2021-04-28 00:22:08 +01:00
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
_isInitialized = true;
2021-07-06 16:28:12 +01:00
if (QSBCore.DebugMode)
{
DebugBoxManager.CreateBox(AttachedObject.transform, 0, _logName);
}
2021-04-28 00:22:08 +01:00
}
public override void SerializeTransform(QNetworkWriter writer)
{
if (_intermediaryTransform == null)
{
_intermediaryTransform = new IntermediaryTransform(transform);
}
var worldPos = _intermediaryTransform.GetPosition();
var worldRot = _intermediaryTransform.GetRotation();
writer.Write(worldPos);
SerializeRotation(writer, worldRot);
_prevPosition = worldPos;
_prevRotation = worldRot;
}
public override void DeserializeTransform(QNetworkReader reader)
{
2021-05-08 16:57:01 +01:00
if (!QSBCore.WorldObjectsReady)
2021-04-28 00:22:08 +01:00
{
reader.ReadVector3();
DeserializeRotation(reader);
return;
}
var pos = reader.ReadVector3();
var rot = DeserializeRotation(reader);
if (HasAuthority)
{
return;
}
2021-04-28 13:37:51 +01:00
if (_intermediaryTransform == null)
{
_intermediaryTransform = new IntermediaryTransform(transform);
}
2021-04-28 00:22:08 +01:00
_intermediaryTransform.SetPosition(pos);
_intermediaryTransform.SetRotation(rot);
if (_intermediaryTransform.GetPosition() == Vector3.zero)
{
DebugLog.ToConsole($"Warning - {_logName} at (0,0,0)! - Given position was {pos}", MessageType.Warning);
2021-04-28 00:22:08 +01:00
}
}
2021-07-07 23:04:00 +01:00
protected override void UpdateTransform()
2021-04-28 00:22:08 +01:00
{
if (HasAuthority)
{
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
2021-04-28 10:02:16 +01:00
return;
2021-04-28 00:22:08 +01:00
}
2021-06-18 22:38:32 +01:00
2021-04-28 10:02:16 +01:00
var targetPos = _intermediaryTransform.GetTargetPosition_ParentedToReference();
var targetRot = _intermediaryTransform.GetTargetRotation_ParentedToReference();
if (targetPos != Vector3.zero && _intermediaryTransform.GetTargetPosition_Unparented() != Vector3.zero)
{
if (UseInterpolation)
{
AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, targetPos);
AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
}
else
{
AttachedObject.transform.localPosition = targetPos;
AttachedObject.transform.localRotation = targetRot;
}
2021-04-28 00:22:08 +01:00
}
}
public override bool HasMoved()
{
var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
return displacementMagnitude > 1E-03f
|| Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f;
}
public void SetReferenceTransform(Transform transform)
{
if (ReferenceTransform == transform)
{
return;
}
2021-06-18 22:38:32 +01:00
2021-04-28 00:22:08 +01:00
ReferenceTransform = transform;
_intermediaryTransform.SetReferenceTransform(transform);
if (AttachedObject == null)
{
DebugLog.ToConsole($"Warning - AttachedObject was null for {_logName} when trying to set reference transform to {transform?.name}. Waiting until not null...", MessageType.Warning);
2021-04-28 00:22:08 +01:00
QSBCore.UnityEvents.RunWhen(
() => AttachedObject != null,
() => ReparentAttachedObject(transform));
return;
}
2021-06-18 22:38:32 +01:00
2021-04-28 00:22:08 +01:00
if (!HasAuthority)
{
ReparentAttachedObject(transform);
}
if (HasAuthority || NetIdentity.ClientAuthorityOwner == null)
{
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
}
2021-04-28 00:22:08 +01:00
}
2021-07-05 20:02:47 +01:00
private void ReparentAttachedObject(Transform newParent)
2021-04-28 00:22:08 +01:00
{
if (AttachedObject.transform.parent != null && AttachedObject.transform.parent.GetComponent<Sector>() == null)
{
2021-04-28 10:02:16 +01:00
DebugLog.ToConsole($"Warning - Trying to reparent AttachedObject {AttachedObject.name} which wasnt attached to sector!", MessageType.Warning);
2021-04-28 00:22:08 +01:00
}
2021-06-18 22:38:32 +01:00
2021-07-05 20:02:47 +01:00
AttachedObject.transform.SetParent(newParent, true);
2021-07-07 19:47:31 +01:00
AttachedObject.transform.localScale = Vector3.one;
2021-04-28 00:22:08 +01:00
}
}
}