2021-12-07 15:56:08 +00:00
using OWML.Common ;
2021-12-02 00:42:24 -08:00
using QSB.Player ;
2022-01-07 17:12:08 -08:00
using QSB.Player.TransformSync ;
2021-12-02 00:42:24 -08:00
using QSB.Utility ;
2021-12-07 15:56:08 +00:00
using System ;
using System.Collections.Generic ;
2021-03-23 13:18:29 +00:00
using UnityEngine ;
namespace QSB.WorldSync
{
2021-12-20 18:35:38 -08:00
public enum WorldObjectType
{
Both ,
SolarSystem ,
Eye
}
2021-03-23 13:18:29 +00:00
public abstract class WorldObjectManager : MonoBehaviour
{
2021-11-20 19:49:50 +00:00
private static readonly List < WorldObjectManager > _managers = new ( ) ;
2021-03-23 13:18:29 +00:00
2021-12-04 09:51:27 +00:00
/// <summary>
/// Set when all WorldObjectManagers have called Init() on all their objects (AKA all the objects are created)
/// </summary>
public static bool AllObjectsAdded { get ; private set ; }
/// <summary>
/// Set when all WorldObjects have finished running Init()
/// </summary>
public static bool AllObjectsReady { get ; private set ; }
2021-05-02 08:54:00 +01:00
2021-12-20 18:35:38 -08:00
/// <summary>
/// when the scene does not match the type, this manager will not build its world objects
/// </summary>
public abstract WorldObjectType WorldObjectType { get ; }
2021-03-25 22:01:10 +00:00
public virtual void Awake ( )
2021-05-02 08:54:00 +01:00
{
QSBSceneManager . OnSceneLoaded + = OnSceneLoaded ;
_managers . Add ( this ) ;
}
2021-03-23 13:18:29 +00:00
public virtual void OnDestroy ( )
2021-05-02 08:54:00 +01:00
{
QSBSceneManager . OnSceneLoaded - = OnSceneLoaded ;
_managers . Remove ( this ) ;
}
2021-12-02 00:42:24 -08:00
public static void SetNotReady ( )
{
2021-12-04 09:51:27 +00:00
AllObjectsAdded = false ;
AllObjectsReady = false ;
2021-12-02 00:42:24 -08:00
}
2021-07-17 09:52:46 +01:00
2021-12-02 00:42:24 -08:00
private void OnSceneLoaded ( OWScene oldScene , OWScene newScene , bool inUniverse )
{
2021-12-04 09:51:27 +00:00
AllObjectsAdded = false ;
AllObjectsReady = false ;
2021-12-02 00:42:24 -08:00
}
2021-03-23 13:18:29 +00:00
public static void Rebuild ( OWScene scene )
2021-07-17 09:52:46 +01:00
{
if ( ! QSBNetworkManager . Instance . IsReady )
{
2021-12-11 10:50:17 +00:00
DebugLog . ToConsole ( $"Warning - Tried to rebuild WorldObjects when Network Manager not ready! Building when ready..." , MessageType . Warning ) ;
2021-07-17 09:52:46 +01:00
QSBCore . UnityEvents . RunWhen ( ( ) = > QSBNetworkManager . Instance . IsReady , ( ) = > Rebuild ( scene ) ) ;
return ;
}
2022-01-07 17:12:08 -08:00
if ( PlayerTransformSync . LocalInstance = = null )
2021-07-17 09:52:46 +01:00
{
2021-12-11 10:50:17 +00:00
DebugLog . ToConsole ( $"Warning - Tried to rebuild WorldObjects when LocalPlayer is not ready! Building when ready..." , MessageType . Warning ) ;
2022-01-07 17:12:08 -08:00
QSBCore . UnityEvents . RunWhen ( ( ) = > PlayerTransformSync . LocalInstance , ( ) = > Rebuild ( scene ) ) ;
2021-07-17 09:52:46 +01:00
return ;
}
2021-12-11 10:50:17 +00:00
DoRebuild ( scene ) ;
2021-07-17 09:52:46 +01:00
}
private static void DoRebuild ( OWScene scene )
2021-03-23 13:18:29 +00:00
{
2021-12-11 22:00:21 -08:00
QSBWorldSync . RemoveWorldObjects ( ) ;
2021-12-02 00:42:24 -08:00
_numManagersReadying = 0 ;
_numObjectsReadying = 0 ;
2021-12-04 09:51:27 +00:00
AllObjectsAdded = false ;
AllObjectsReady = false ;
2021-03-23 13:18:29 +00:00
foreach ( var manager in _managers )
{
2021-12-20 18:35:38 -08:00
switch ( manager . WorldObjectType )
{
case WorldObjectType . SolarSystem when QSBSceneManager . CurrentScene ! = OWScene . SolarSystem :
case WorldObjectType . Eye when QSBSceneManager . CurrentScene ! = OWScene . EyeOfTheUniverse :
2021-12-20 18:47:02 -08:00
DebugLog . DebugWrite ( $"skipping {manager.GetType().Name} as it is type {manager.WorldObjectType} and scene is {QSBSceneManager.CurrentScene}" ) ;
2021-12-20 18:35:38 -08:00
continue ;
}
2021-07-17 09:52:46 +01:00
try
{
2021-12-04 09:51:27 +00:00
DebugLog . DebugWrite ( $"Rebuilding {manager.GetType().Name}" , MessageType . Info ) ;
2021-07-17 09:52:46 +01:00
manager . RebuildWorldObjects ( scene ) ;
}
catch ( Exception ex )
{
2021-12-11 21:45:28 -08:00
DebugLog . ToConsole ( $"Exception - Exception when trying to rebuild WorldObjects of manager {manager.GetType().Name} : {ex.Message} Stacktrace :\r\n{ex.StackTrace}" , MessageType . Error ) ;
2021-07-17 09:52:46 +01:00
}
2021-03-23 13:18:29 +00:00
}
2021-06-18 22:38:32 +01:00
2021-12-02 00:42:24 -08:00
QSBCore . UnityEvents . RunWhen ( ( ) = > _numManagersReadying = = 0 , ( ) = >
2021-10-16 23:35:45 +01:00
{
2021-12-04 09:51:27 +00:00
AllObjectsAdded = true ;
2021-12-02 00:42:24 -08:00
DebugLog . DebugWrite ( "World Objects added." , MessageType . Success ) ;
QSBCore . UnityEvents . RunWhen ( ( ) = > _numObjectsReadying = = 0 , ( ) = >
{
2021-12-04 09:51:27 +00:00
AllObjectsReady = true ;
2021-12-02 00:42:24 -08:00
DebugLog . DebugWrite ( "World Objects ready." , MessageType . Success ) ;
} ) ;
} ) ;
2021-10-16 23:35:45 +01:00
}
2021-10-29 23:00:13 +01:00
2021-03-23 13:18:29 +00:00
protected abstract void RebuildWorldObjects ( OWScene scene ) ;
2021-12-02 00:42:24 -08:00
private static uint _numManagersReadying ;
internal static uint _numObjectsReadying ;
/// indicates that this won't become ready immediately
protected void StartDelayedReady ( ) = > _numManagersReadying + + ;
/// indicates that this is now ready
protected void FinishDelayedReady ( ) = > _numManagersReadying - - ;
2021-03-23 13:18:29 +00:00
}
}