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 )
2021-05-08 00:10:30 +01:00
= > _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
{
2021-05-08 00:10:30 +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
2021-05-02 09:09:37 +01:00
if ( ! HasAuthority & & AttachedObject ! = null )
2021-05-02 08:54:00 +01:00
{
2021-05-19 11:17:37 +01:00
Destroy ( AttachedObject . gameObject ) ;
2021-05-02 08:54:00 +01:00
}
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 )
{
2021-05-08 00:10:30 +01:00
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 )
{
2021-05-19 12:12:13 +01:00
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 ) ;
}
2021-07-09 15:02:56 +01:00
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
}
}
}