2020-09-29 20:34:46 +00:00
using OWML.Common ;
2021-04-11 16:05:02 +00:00
using QSB.OrbSync.TransformSync ;
2020-12-31 12:10:55 +00:00
using QSB.OrbSync.WorldObjects ;
2020-09-29 20:34:46 +00:00
using QSB.Utility ;
2020-09-06 08:07:31 +00:00
using System ;
2020-09-04 19:57:35 +00:00
using System.Collections.Generic ;
2020-08-13 17:25:12 +00:00
using System.Linq ;
2020-12-23 22:43:05 +00:00
using UnityEngine ;
2020-08-13 17:25:12 +00:00
namespace QSB.WorldSync
{
2020-12-11 13:14:58 +00:00
public static class QSBWorldSync
2020-12-02 21:29:53 +00:00
{
2020-12-14 20:41:56 +00:00
public static List < NomaiInterfaceOrb > OldOrbList { get ; set ; } = new List < NomaiInterfaceOrb > ( ) ;
public static List < CharacterDialogueTree > OldDialogueTrees { get ; set ; } = new List < CharacterDialogueTree > ( ) ;
2020-12-11 13:14:58 +00:00
public static Dictionary < string , bool > DialogueConditions { get ; } = new Dictionary < string , bool > ( ) ;
2020-12-19 10:56:25 +00:00
public static List < FactReveal > ShipLogFacts { get ; } = new List < FactReveal > ( ) ;
2020-09-22 20:11:29 +00:00
2020-12-24 08:41:38 +00:00
private static readonly List < IWorldObject > WorldObjects = new List < IWorldObject > ( ) ;
2021-03-07 09:27:23 +00:00
private static readonly Dictionary < MonoBehaviour , IWorldObject > WorldObjectsToUnityObjects = new Dictionary < MonoBehaviour , IWorldObject > ( ) ;
2020-12-14 20:41:56 +00:00
2020-12-24 10:06:17 +00:00
public static IEnumerable < TWorldObject > GetWorldObjects < TWorldObject > ( )
= > WorldObjects . OfType < TWorldObject > ( ) ;
2020-08-13 17:25:12 +00:00
2021-02-24 10:45:25 +00:00
public static TWorldObject GetWorldFromId < TWorldObject > ( int id )
2021-02-25 22:45:32 +00:00
{
if ( id < 0 | | id > = GetWorldObjects < TWorldObject > ( ) . Count ( ) )
{
2021-02-26 13:12:29 +00:00
DebugLog . ToConsole ( $"Warning - Tried to find {typeof(TWorldObject).Name} id {id}. Count is {GetWorldObjects<TWorldObject>().Count()}." , MessageType . Warning ) ;
2021-02-25 22:45:32 +00:00
return default ;
}
2021-06-18 21:38:32 +00:00
2021-02-25 22:45:32 +00:00
return GetWorldObjects < TWorldObject > ( ) . ToList ( ) [ id ] ;
}
2020-09-06 08:07:31 +00:00
2021-11-01 19:51:37 +00:00
public static IWorldObject GetWorldFromUnity ( MonoBehaviour unityObject )
{
if ( ! WorldObjectManager . AllReady )
{
return default ;
}
if ( unityObject = = null )
{
DebugLog . ToConsole ( $"Error - Trying to run GetWorldFromUnity with a null unity object! TUnityObject:NULL" , MessageType . Error ) ;
return default ;
}
if ( ! QSBCore . IsInMultiplayer )
{
DebugLog . ToConsole ( $"Warning - Trying to run GetWorldFromUnity while not in multiplayer! TUnityObject:{unityObject.GetType().Name}" , MessageType . Warning ) ;
return default ;
}
if ( ! WorldObjectsToUnityObjects . ContainsKey ( unityObject ) )
{
DebugLog . ToConsole ( $"Error - WorldObjectsToUnityObjects does not contain \" { unityObject . name } \ "! TUnityObject:{unityObject.GetType().Name}" , MessageType . Error ) ;
return default ;
}
var returnObject = WorldObjectsToUnityObjects [ unityObject ] ;
if ( returnObject = = null )
{
DebugLog . ToConsole ( $"Error - World object for unity object {unityObject.name} is null! TUnityObject:{unityObject.GetType().Name}" , MessageType . Error ) ;
return default ;
}
2021-11-09 19:39:56 +00:00
return returnObject ;
2021-11-01 19:51:37 +00:00
}
2021-11-01 15:49:00 +00:00
public static TWorldObject GetWorldFromUnity < TWorldObject > ( MonoBehaviour unityObject )
where TWorldObject : IWorldObject
2021-03-18 16:57:56 +00:00
{
2021-07-17 08:53:13 +00:00
if ( ! WorldObjectManager . AllReady )
{
return default ;
}
2021-03-25 20:56:26 +00:00
if ( unityObject = = null )
{
2021-11-01 15:49:00 +00:00
DebugLog . ToConsole ( $"Error - Trying to run GetWorldFromUnity with a null unity object! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:NULL" , MessageType . Error ) ;
2021-03-25 20:56:26 +00:00
return default ;
}
2021-06-18 21:38:32 +00:00
2021-03-25 20:56:26 +00:00
if ( ! QSBCore . IsInMultiplayer )
{
2021-11-01 15:49:00 +00:00
DebugLog . ToConsole ( $"Warning - Trying to run GetWorldFromUnity while not in multiplayer! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}" , MessageType . Warning ) ;
2021-03-25 20:56:26 +00:00
return default ;
}
2021-06-18 21:38:32 +00:00
2021-03-18 16:57:56 +00:00
if ( ! WorldObjectsToUnityObjects . ContainsKey ( unityObject ) )
{
2021-11-01 15:49:00 +00:00
DebugLog . ToConsole ( $"Error - WorldObjectsToUnityObjects does not contain \" { unityObject . name } \ "! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}" , MessageType . Error ) ;
2021-03-18 16:57:56 +00:00
return default ;
}
2021-06-18 21:38:32 +00:00
2021-11-01 15:49:00 +00:00
var returnObject = ( TWorldObject ) WorldObjectsToUnityObjects [ unityObject ] ;
2021-10-16 22:35:45 +00:00
2021-11-01 15:49:00 +00:00
if ( returnObject = = null )
2021-10-16 22:35:45 +00:00
{
2021-11-01 15:49:00 +00:00
DebugLog . ToConsole ( $"Error - World object for unity object {unityObject.name} is null! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}" , MessageType . Error ) ;
2021-10-16 22:35:45 +00:00
return default ;
}
return returnObject ;
2021-03-18 16:57:56 +00:00
}
2021-02-18 10:34:35 +00:00
2021-11-01 15:49:00 +00:00
public static int GetIdFromUnity < TWorldObject > ( MonoBehaviour unityObject )
where TWorldObject : IWorldObject
= > GetWorldFromUnity < TWorldObject > ( unityObject ) . ObjectId ;
2021-02-24 10:45:25 +00:00
public static int GetIdFromTypeSubset < TTypeSubset > ( TTypeSubset typeSubset )
2021-02-25 22:45:32 +00:00
{
2021-02-25 22:46:31 +00:00
var index = GetWorldObjects < TTypeSubset > ( ) . ToList ( ) . IndexOf ( typeSubset ) ;
2021-02-25 22:45:32 +00:00
if ( index = = - 1 )
{
DebugLog . ToConsole ( $"Warning - {(typeSubset as IWorldObject).Name} doesn't exist in list of {typeof(TTypeSubset).Name} !" , MessageType . Warning ) ;
}
2021-06-18 21:38:32 +00:00
2021-02-25 22:45:32 +00:00
return index ;
}
2021-02-24 10:45:25 +00:00
2020-12-24 08:41:38 +00:00
public static void RemoveWorldObjects < TWorldObject > ( )
2021-02-09 21:35:31 +00:00
{
2021-10-24 09:47:25 +00:00
if ( WorldObjects = = null | | WorldObjects . Count = = 0 )
{
DebugLog . ToConsole ( $"Warning - Trying to remove WorldObjects of type {typeof(TWorldObject).Name}, but there are no WorldObjects!" ) ;
}
2021-02-09 21:35:31 +00:00
var itemsToRemove = WorldObjects . Where ( x = > x is TWorldObject ) ;
2021-10-24 09:47:25 +00:00
2021-02-09 21:35:31 +00:00
foreach ( var item in itemsToRemove )
{
2021-10-24 09:47:25 +00:00
if ( item is null )
{
DebugLog . ToConsole ( $"Error - Trying to remove a null WorldObject of type {typeof(TWorldObject).Name}." , MessageType . Error ) ;
continue ;
}
2021-02-19 21:25:17 +00:00
try
{
2021-10-24 09:47:25 +00:00
WorldObjectsToUnityObjects . Remove ( item . ReturnObject ( ) ) ;
2021-02-19 21:25:17 +00:00
item . OnRemoval ( ) ;
}
catch ( Exception e )
{
2021-10-24 09:47:25 +00:00
DebugLog . ToConsole ( $"Error - Exception in OnRemoval() for {item.GetType()}. Message : {e.Message}, Stack trace : {e.StackTrace}" , MessageType . Error ) ;
2021-02-19 21:25:17 +00:00
}
2021-02-09 21:35:31 +00:00
}
2021-06-18 21:38:32 +00:00
2021-02-09 21:35:31 +00:00
WorldObjects . RemoveAll ( x = > x is TWorldObject ) ;
}
2020-09-17 19:14:55 +00:00
2021-11-13 08:42:59 +00:00
public static IEnumerable < TUnityObject > GetUnityObjects < TUnityObject > ( )
where TUnityObject : MonoBehaviour
= > Resources . FindObjectsOfTypeAll < TUnityObject > ( )
. Where ( x = > x . gameObject . scene . name ! = null ) ;
2021-11-11 02:40:02 +00:00
2021-11-13 08:42:59 +00:00
public static void Init < TWorldObject , TUnityObject > ( )
2020-12-24 08:06:23 +00:00
where TWorldObject : WorldObject < TUnityObject >
2021-01-29 15:29:50 +00:00
where TUnityObject : MonoBehaviour
2020-12-02 21:29:53 +00:00
{
2021-02-14 09:43:36 +00:00
RemoveWorldObjects < TWorldObject > ( ) ;
2021-11-13 08:42:59 +00:00
var list = GetUnityObjects < TUnityObject > ( ) . ToList ( ) ;
2021-08-08 19:04:55 +00:00
//DebugLog.DebugWrite($"{typeof(TWorldObject).Name} init : {list.Count} instances.", MessageType.Info);
2020-12-23 22:43:05 +00:00
for ( var id = 0 ; id < list . Count ; id + + )
2020-12-02 21:29:53 +00:00
{
2021-02-24 10:45:25 +00:00
var obj = CreateWorldObject < TWorldObject > ( ) ;
2020-12-23 22:43:05 +00:00
obj . Init ( list [ id ] , id ) ;
2021-03-02 09:53:52 +00:00
WorldObjectsToUnityObjects . Add ( list [ id ] , obj ) ;
2020-12-02 21:29:53 +00:00
}
}
2020-09-06 08:07:31 +00:00
2020-12-24 08:12:47 +00:00
private static TWorldObject CreateWorldObject < TWorldObject > ( )
2020-12-24 08:41:38 +00:00
where TWorldObject : IWorldObject
2020-12-24 08:12:47 +00:00
{
var worldObject = ( TWorldObject ) Activator . CreateInstance ( typeof ( TWorldObject ) ) ;
WorldObjects . Add ( worldObject ) ;
2021-10-16 22:35:45 +00:00
if ( worldObject = = null )
{
// if this happens, god help you
DebugLog . ToConsole ( $"Error - CreateWorldObject is returning a null value! This is very bad!" , MessageType . Error ) ;
}
2020-12-24 08:12:47 +00:00
return worldObject ;
}
2021-07-07 08:02:23 +00:00
2020-12-23 22:43:05 +00:00
public static void HandleSlotStateChange ( NomaiInterfaceSlot slot , NomaiInterfaceOrb affectingOrb , bool state )
{
var slotList = GetWorldObjects < QSBOrbSlot > ( ) . ToList ( ) ;
if ( ! slotList . Any ( ) )
{
return ;
}
2021-06-18 21:38:32 +00:00
2021-02-19 21:25:17 +00:00
var qsbSlot = slotList . FirstOrDefault ( x = > x . AttachedObject = = slot ) ;
if ( qsbSlot = = null )
{
DebugLog . ToConsole ( $"Error - No QSBOrbSlot found for {slot.name}!" , MessageType . Error ) ;
return ;
}
2021-06-18 21:38:32 +00:00
2021-10-26 13:08:23 +00:00
var orbSync = NomaiOrbTransformSync . OrbTransformSyncs . Where ( x = > x ! = null ) . FirstOrDefault ( x = > x . AttachedObject = = affectingOrb . transform ) ;
2021-03-23 13:18:29 +00:00
if ( orbSync = = null )
{
DebugLog . ToConsole ( $"Error - No NomaiOrbTransformSync found for {affectingOrb.name} (For slot {slot.name})!" , MessageType . Error ) ;
return ;
}
2021-06-18 21:38:32 +00:00
2020-12-23 22:43:05 +00:00
if ( orbSync . HasAuthority )
{
qsbSlot . HandleEvent ( state , OldOrbList . IndexOf ( affectingOrb ) ) ;
}
}
2020-12-11 22:42:21 +00:00
public static void SetDialogueCondition ( string name , bool state )
2020-12-11 13:14:58 +00:00
{
2021-08-08 18:53:55 +00:00
if ( ! QSBCore . IsHost )
2020-12-11 13:14:58 +00:00
{
2020-12-19 18:44:27 +00:00
DebugLog . ToConsole ( "Warning - Cannot write to condition dict when not server!" , MessageType . Warning ) ;
2020-12-11 13:14:58 +00:00
return ;
}
2021-06-18 21:38:32 +00:00
2020-12-11 13:14:58 +00:00
DialogueConditions [ name ] = state ;
}
2020-12-19 10:56:25 +00:00
public static void AddFactReveal ( string id , bool saveGame , bool showNotification )
{
2021-08-08 18:53:55 +00:00
if ( ! QSBCore . IsHost )
2020-12-19 10:56:25 +00:00
{
2020-12-19 18:44:27 +00:00
DebugLog . ToConsole ( "Warning - Cannot write to fact list when not server!" , MessageType . Warning ) ;
2020-12-19 10:56:25 +00:00
return ;
}
2021-06-18 21:38:32 +00:00
2020-12-19 10:56:25 +00:00
if ( ShipLogFacts . Any ( x = > x . Id = = id ) )
{
return ;
}
2021-06-18 21:38:32 +00:00
2020-12-19 10:56:25 +00:00
ShipLogFacts . Add ( new FactReveal
{
Id = id ,
SaveGame = saveGame ,
ShowNotification = showNotification
} ) ;
}
2020-12-02 21:29:53 +00:00
}
2021-11-11 02:40:02 +00:00
}