2022-01-16 06:53:45 -08:00
using Mirror ;
using OWML.Common ;
2021-07-07 22:12:41 +01:00
using QSB.Player ;
using QSB.Utility ;
2021-07-17 09:51:47 +01:00
using QSB.WorldSync ;
2021-08-14 14:45:52 +01:00
using System ;
using System.Linq ;
2021-07-07 22:12:41 +01:00
using UnityEngine ;
namespace QSB.Syncs
{
2022-01-14 22:39:41 -08:00
/ *
2022-01-14 22:41:36 -08:00
* Rewrite number : 10
2022-01-14 22:39:41 -08:00
* God has cursed me for my hubris , and my work is never finished .
* /
public abstract class SyncBase : QSBNetworkTransform
2022-01-14 20:59:42 -08:00
{
/// <summary>
/// valid if IsPlayerObject, otherwise null
/// </summary>
public PlayerInfo Player { get ; private set ; }
private bool _baseIsReady
{
get
{
if ( netId is uint . MaxValue or 0 )
{
return false ;
}
if ( ! WorldObjectManager . AllObjectsAdded )
{
return false ;
}
if ( IsPlayerObject )
{
if ( ! Player . IsReady & & ! isLocalPlayer )
{
return false ;
}
}
return true ;
}
}
2022-01-16 06:11:44 -08:00
protected abstract bool IsReady { get ; }
protected abstract bool UseInterpolation { get ; }
2022-01-16 07:56:08 -08:00
protected virtual bool AllowDisabledAttachedObject = > false ;
2022-01-16 06:11:44 -08:00
protected abstract bool AllowNullReferenceTransform { get ; }
2022-01-16 06:53:45 -08:00
protected virtual bool IsPlayerObject = > false ;
protected virtual bool OnlyApplyOnDeserialize = > false ;
2022-01-14 20:59:42 -08:00
2022-01-16 05:38:06 -08:00
public Transform AttachedTransform { get ; private set ; }
public Transform ReferenceTransform { get ; private set ; }
2022-01-14 20:59:42 -08:00
public string LogName = > ( IsPlayerObject ? $"{Player.PlayerId}." : string . Empty ) + $"{netId}:{GetType().Name}" ;
protected const float SmoothTime = 0.1f ;
private Vector3 _positionSmoothVelocity ;
private Quaternion _rotationSmoothVelocity ;
2022-01-16 05:38:06 -08:00
public bool IsInitialized { get ; private set ; }
2022-01-14 20:59:42 -08:00
protected Vector3 SmoothPosition ;
protected Quaternion SmoothRotation ;
2022-01-16 04:34:52 -08:00
protected abstract Transform InitAttachedTransform ( ) ;
2022-01-16 06:53:45 -08:00
protected abstract void GetFromAttached ( ) ;
protected abstract void ApplyToAttached ( ) ;
2022-01-14 20:59:42 -08:00
public virtual void Start ( )
{
if ( IsPlayerObject )
{
// get player objects spawned before this object (or is this one)
// and use the closest one
Player = QSBPlayerManager . PlayerList
. Where ( x = > x . PlayerId < = netId )
. OrderBy ( x = > x . PlayerId ) . Last ( ) ;
}
DontDestroyOnLoad ( gameObject ) ;
QSBSceneManager . OnSceneLoaded + = OnSceneLoaded ;
}
protected virtual void OnDestroy ( )
{
2022-01-16 07:56:08 -08:00
if ( IsPlayerObject & & ! hasAuthority & & AttachedTransform ! = null )
2022-01-14 20:59:42 -08:00
{
2022-01-16 04:34:52 -08:00
Destroy ( AttachedTransform . gameObject ) ;
2022-01-14 20:59:42 -08:00
}
QSBSceneManager . OnSceneLoaded - = OnSceneLoaded ;
}
protected virtual void Init ( )
{
if ( ! QSBSceneManager . IsInUniverse )
{
DebugLog . ToConsole ( $"Error - {LogName} is being init-ed when not in the universe!" , MessageType . Error ) ;
}
2022-01-16 07:56:08 -08:00
if ( IsPlayerObject & & ! hasAuthority & & AttachedTransform ! = null )
2022-01-14 20:59:42 -08:00
{
2022-01-16 04:34:52 -08:00
Destroy ( AttachedTransform . gameObject ) ;
2022-01-14 20:59:42 -08:00
}
2022-01-16 04:34:52 -08:00
AttachedTransform = InitAttachedTransform ( ) ;
IsInitialized = true ;
2022-01-14 20:59:42 -08:00
}
2022-01-16 04:34:52 -08:00
protected virtual void OnSceneLoaded ( OWScene oldScene , OWScene newScene , bool isInUniverse ) = > IsInitialized = false ;
2022-01-14 20:59:42 -08:00
2022-01-16 06:53:45 -08:00
private bool _shouldApply ;
2022-01-16 07:23:35 -08:00
protected override void Deserialize ( NetworkReader reader , bool initialState )
2022-01-16 06:53:45 -08:00
{
2022-01-16 07:23:35 -08:00
base . Deserialize ( reader , initialState ) ;
2022-01-16 06:53:45 -08:00
if ( OnlyApplyOnDeserialize )
{
_shouldApply = true ;
}
}
2022-01-16 06:11:44 -08:00
protected sealed override void Update ( )
2022-01-14 20:59:42 -08:00
{
2022-01-16 04:34:52 -08:00
if ( ! IsInitialized & & IsReady & & _baseIsReady )
2022-01-14 20:59:42 -08:00
{
try
{
Init ( ) ;
}
catch ( Exception ex )
{
DebugLog . ToConsole ( $"Exception when initializing {name} : {ex}" , MessageType . Error ) ;
2022-01-16 02:36:39 -08:00
return ;
2022-01-14 20:59:42 -08:00
}
}
2022-01-16 04:34:52 -08:00
else if ( IsInitialized & & ( ! IsReady | | ! _baseIsReady ) )
2022-01-14 20:59:42 -08:00
{
2022-01-16 04:34:52 -08:00
IsInitialized = false ;
2022-01-14 20:59:42 -08:00
return ;
}
2022-01-16 04:34:52 -08:00
if ( ! IsInitialized )
2022-01-14 20:59:42 -08:00
{
return ;
}
if ( AttachedTransform = = null )
{
DebugLog . ToConsole ( $"Warning - AttachedObject {LogName} is null." , MessageType . Warning ) ;
2022-01-16 04:34:52 -08:00
IsInitialized = false ;
2022-01-14 20:59:42 -08:00
return ;
}
2022-01-16 04:52:48 -08:00
if ( ! AttachedTransform . gameObject . activeInHierarchy & & ! AllowDisabledAttachedObject )
2022-01-14 20:59:42 -08:00
{
return ;
}
2022-01-16 02:36:39 -08:00
2022-01-16 04:52:48 -08:00
if ( ReferenceTransform = = null & & ! AllowNullReferenceTransform )
2022-01-14 20:59:42 -08:00
{
2022-01-16 04:34:52 -08:00
DebugLog . ToConsole ( $"Warning - {LogName}'s ReferenceTransform is null. AttachedObject:{AttachedTransform.name}" , MessageType . Warning ) ;
return ;
2022-01-14 20:59:42 -08:00
}
2022-01-16 04:34:52 -08:00
if ( ReferenceTransform ! = null & & ReferenceTransform . position = = Vector3 . zero & & ReferenceTransform ! = Locator . GetRootTransform ( ) )
2022-01-14 20:59:42 -08:00
{
2022-01-16 04:34:52 -08:00
DebugLog . ToConsole ( $"Warning - {LogName}'s ReferenceTransform is at (0,0,0). ReferenceTransform:{ReferenceTransform.name}, AttachedObject:{AttachedTransform.name}" , MessageType . Warning ) ;
2022-01-14 20:59:42 -08:00
}
2022-01-16 04:34:52 -08:00
if ( ReferenceTransform = = Locator . GetRootTransform ( ) )
2022-01-14 20:59:42 -08:00
{
return ;
}
2022-01-16 07:23:35 -08:00
if ( UseInterpolation )
2022-01-14 20:59:42 -08:00
{
2022-01-16 07:56:55 -08:00
SmoothPosition = Vector3 . SmoothDamp ( SmoothPosition , transform . position , ref _positionSmoothVelocity , SmoothTime ) ;
SmoothRotation = QuaternionHelper . SmoothDamp ( SmoothRotation , transform . rotation , ref _rotationSmoothVelocity , SmoothTime ) ;
2022-01-14 20:59:42 -08:00
}
2022-01-16 06:53:45 -08:00
if ( hasAuthority )
{
GetFromAttached ( ) ;
}
else
{
if ( OnlyApplyOnDeserialize & & _shouldApply )
{
_shouldApply = false ;
ApplyToAttached ( ) ;
}
else
{
ApplyToAttached ( ) ;
}
}
2022-01-14 20:59:42 -08:00
base . Update ( ) ;
}
public void SetReferenceTransform ( Transform referenceTransform )
{
if ( ReferenceTransform = = referenceTransform )
{
return ;
}
ReferenceTransform = referenceTransform ;
if ( hasAuthority )
{
transform . position = ReferenceTransform . ToRelPos ( AttachedTransform . position ) ;
transform . rotation = ReferenceTransform . ToRelRot ( AttachedTransform . rotation ) ;
}
else if ( UseInterpolation )
{
SmoothPosition = ReferenceTransform . ToRelPos ( AttachedTransform . position ) ;
SmoothRotation = ReferenceTransform . ToRelRot ( AttachedTransform . rotation ) ;
}
}
protected virtual void OnRenderObject ( )
{
if ( ! QSBCore . ShowLinesInDebug
2022-01-16 04:34:52 -08:00
| | ! IsInitialized
2022-01-14 20:59:42 -08:00
| | AttachedTransform = = null
| | ReferenceTransform = = null )
{
return ;
}
/ * Red Cube = Where visible object should be
* Green cube = Where visible object is
* Magenta cube = Reference transform
* Red Line = Connection between Red Cube and Green Cube
* Cyan Line = Connection between Green cube and reference transform
* /
Popcron . Gizmos . Cube ( ReferenceTransform . FromRelPos ( transform . position ) , ReferenceTransform . FromRelRot ( transform . rotation ) , Vector3 . one / 8 , Color . red ) ;
Popcron . Gizmos . Line ( ReferenceTransform . FromRelPos ( transform . position ) , AttachedTransform . transform . position , Color . red ) ;
Popcron . Gizmos . Cube ( AttachedTransform . transform . position , AttachedTransform . transform . rotation , Vector3 . one / 6 , Color . green ) ;
Popcron . Gizmos . Cube ( ReferenceTransform . position , ReferenceTransform . rotation , Vector3 . one / 8 , Color . magenta ) ;
Popcron . Gizmos . Line ( AttachedTransform . transform . position , ReferenceTransform . position , Color . cyan ) ;
}
private void OnGUI ( )
{
if ( ! QSBCore . ShowDebugLabels | |
Event . current . type ! = EventType . Repaint )
{
return ;
}
if ( AttachedTransform ! = null )
{
DebugGUI . DrawLabel ( AttachedTransform . transform , LogName ) ;
}
}
}
2021-07-07 22:12:41 +01:00
}