2021-12-07 15:56:08 +00:00
using OWML.Common ;
2022-01-08 11:41:55 +00:00
using QSB.ConversationSync.Patches ;
2021-12-26 00:53:43 -08:00
using QSB.LogSync ;
2022-01-12 19:18:59 -08:00
using QSB.TriggerSync.WorldObjects ;
2020-09-29 21:34:46 +01:00
using QSB.Utility ;
2021-12-07 15:56:08 +00:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2020-12-23 22:43:05 +00:00
using UnityEngine ;
2020-08-13 19:25:12 +02:00
namespace QSB.WorldSync
{
2020-12-11 13:14:58 +00:00
public static class QSBWorldSync
2020-12-02 21:29:53 +00:00
{
2022-01-08 11:41:55 +00:00
public static List < CharacterDialogueTree > OldDialogueTrees { get ; private set ; } = new ( ) ;
public static Dictionary < string , bool > DialogueConditions { get ; private set ; } = new ( ) ;
public static Dictionary < string , bool > PersistentConditions { get ; private set ; } = new ( ) ;
public static List < FactReveal > ShipLogFacts { get ; private set ; } = new ( ) ;
2020-09-22 21:11:29 +01:00
2021-11-20 19:49:50 +00:00
private static readonly List < IWorldObject > WorldObjects = new ( ) ;
private static readonly Dictionary < MonoBehaviour , IWorldObject > WorldObjectsToUnityObjects = new ( ) ;
2020-12-14 21:41:56 +01:00
2022-01-08 11:41:55 +00:00
public static void Init ( )
{
DebugLog . DebugWrite ( $"Init QSBWorldSync" , MessageType . Info ) ;
OldDialogueTrees . Clear ( ) ;
OldDialogueTrees . AddRange ( GetUnityObjects < CharacterDialogueTree > ( ) ) ;
if ( ! QSBCore . IsHost )
{
return ;
}
DebugLog . DebugWrite ( $"DIALOGUE CONDITIONS :" ) ;
DialogueConditions = ( Dictionary < string , bool > ) DialogueConditionManager . SharedInstance . _dictConditions ;
foreach ( var item in DialogueConditions )
{
DebugLog . DebugWrite ( $"- {item.Key}, {item.Value}" ) ;
}
DebugLog . DebugWrite ( $"PERSISTENT CONDITIONS :" ) ;
var dictConditions = PlayerData . _currentGameSave . dictConditions ;
var syncedConditions = dictConditions . Where ( x = > ConversationPatches . PersistentConditionsToSync . Contains ( x . Key ) ) ;
PersistentConditions = syncedConditions . ToDictionary ( x = > x . Key , x = > x . Value ) ;
foreach ( var item in PersistentConditions )
{
DebugLog . DebugWrite ( $"- {item.Key}, {item.Value}" ) ;
}
}
public static void Reset ( )
{
DebugLog . DebugWrite ( $"Reset QSBWorldSync" , MessageType . Info ) ;
OldDialogueTrees . Clear ( ) ;
DialogueConditions . Clear ( ) ;
PersistentConditions . Clear ( ) ;
ShipLogFacts . Clear ( ) ;
}
2021-12-28 16:10:58 -08:00
public static IEnumerable < IWorldObject > GetWorldObjects ( ) = > WorldObjects ;
2020-12-24 10:06:17 +00:00
public static IEnumerable < TWorldObject > GetWorldObjects < TWorldObject > ( )
2021-12-11 15:08:56 -08:00
where TWorldObject : IWorldObject
2020-12-24 10:06:17 +00:00
= > WorldObjects . OfType < TWorldObject > ( ) ;
2020-08-13 19:25:12 +02:00
2021-12-25 22:37:20 -08:00
public static TWorldObject GetWorldObject < TWorldObject > ( this int objectId )
2021-12-11 15:08:56 -08:00
where TWorldObject : IWorldObject
2021-02-25 22:45:32 +00:00
{
2021-12-25 22:37:20 -08:00
if ( ! WorldObjects . IsInRange ( objectId ) )
2021-02-25 22:45:32 +00:00
{
2021-12-25 22:37:20 -08:00
DebugLog . ToConsole ( $"Warning - Tried to find {typeof(TWorldObject).Name} id {objectId}. Count is {WorldObjects.Count}." , MessageType . Warning ) ;
2021-02-25 22:45:32 +00:00
return default ;
}
2021-06-18 22:38:32 +01:00
2021-12-25 22:37:20 -08:00
if ( WorldObjects [ objectId ] is not TWorldObject worldObject )
2021-12-11 22:04:48 -08:00
{
2021-12-25 22:37:20 -08:00
DebugLog . ToConsole ( $"Error - {typeof(TWorldObject).Name} id {objectId} is actually {WorldObjects[objectId].GetType().Name}." , MessageType . Error ) ;
2021-12-11 22:04:48 -08:00
return default ;
}
return worldObject ;
2021-02-25 22:45:32 +00:00
}
2020-09-06 09:07:31 +01:00
2021-12-25 22:37:20 -08:00
public static TWorldObject GetWorldObject < TWorldObject > ( this MonoBehaviour unityObject )
2021-11-01 15:49:00 +00:00
where TWorldObject : IWorldObject
2021-03-18 16:57:56 +00:00
{
2021-03-25 20:56:26 +00:00
if ( unityObject = = null )
{
2021-12-04 09:14:48 +00:00
DebugLog . ToConsole ( $"Error - Trying to run GetWorldFromUnity with a null unity object! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:NULL, Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Error ) ;
2021-03-25 20:56:26 +00:00
return default ;
}
2021-06-18 22:38:32 +01:00
2021-03-25 20:56:26 +00:00
if ( ! QSBCore . IsInMultiplayer )
{
2021-12-04 09:14:48 +00:00
DebugLog . ToConsole ( $"Warning - Trying to run GetWorldFromUnity while not in multiplayer! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}, Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Warning ) ;
2021-03-25 20:56:26 +00:00
return default ;
}
2021-06-18 22:38:32 +01:00
2021-12-20 18:35:38 -08:00
if ( ! WorldObjectsToUnityObjects . TryGetValue ( unityObject , out var worldObject ) )
2021-03-18 16:57:56 +00:00
{
2021-12-04 09:14:48 +00:00
DebugLog . ToConsole ( $"Error - WorldObjectsToUnityObjects does not contain \" { unityObject . name } \ "! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}, Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Error ) ;
2021-03-18 16:57:56 +00:00
return default ;
}
2021-06-18 22:38:32 +01:00
2021-12-20 18:35:38 -08:00
if ( worldObject = = null )
2021-10-16 23:35:45 +01:00
{
2021-12-04 09:14:48 +00:00
DebugLog . ToConsole ( $"Error - World object for unity object {unityObject.name} is null! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}, Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Error ) ;
2021-10-16 23:35:45 +01:00
return default ;
}
2021-12-20 18:35:38 -08:00
return ( TWorldObject ) worldObject ;
2021-03-18 16:57:56 +00:00
}
2021-02-18 10:34:35 +00:00
2021-12-11 22:00:21 -08:00
public static void RemoveWorldObjects ( )
2021-02-09 21:35:31 +00:00
{
2021-12-02 00:42:24 -08:00
if ( WorldObjects . Count = = 0 )
2021-10-24 10:47:25 +01:00
{
2021-12-11 22:00:21 -08:00
DebugLog . ToConsole ( $"Warning - Trying to remove WorldObjects, but there are no WorldObjects!" , MessageType . Warning ) ;
2021-12-02 00:42:24 -08:00
return ;
2021-10-24 10:47:25 +01:00
}
2021-12-11 22:00:21 -08:00
foreach ( var item in WorldObjects )
2021-02-09 21:35:31 +00:00
{
2021-02-19 21:25:17 +00:00
try
{
item . OnRemoval ( ) ;
}
catch ( Exception e )
{
2021-10-24 10:47:25 +01: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 22:38:32 +01:00
2021-12-11 22:00:21 -08:00
WorldObjects . Clear ( ) ;
WorldObjectsToUnityObjects . Clear ( ) ;
2021-02-09 21:35:31 +00:00
}
2020-09-17 20:14:55 +01:00
2021-11-14 03:51:22 -08:00
public static IEnumerable < TUnityObject > GetUnityObjects < TUnityObject > ( )
where TUnityObject : MonoBehaviour
= > Resources . FindObjectsOfTypeAll < TUnityObject > ( )
. Where ( x = > x . gameObject . scene . name ! = null ) ;
2021-12-28 16:10:58 -08:00
public static void Init < TWorldObject , TUnityObject > ( )
2021-12-11 15:08:56 -08:00
where TWorldObject : WorldObject < TUnityObject > , new ( )
2021-01-29 15:29:50 +00:00
where TUnityObject : MonoBehaviour
2020-12-02 21:29:53 +00:00
{
2021-12-17 16:26:44 -08:00
var list = GetUnityObjects < TUnityObject > ( ) ;
2021-12-28 16:10:58 -08:00
Init < TWorldObject , TUnityObject > ( list ) ;
2021-12-15 21:09:10 +00:00
}
2021-12-28 16:10:58 -08:00
public static void Init < TWorldObject , TUnityObject > ( params Type [ ] typesToExclude )
2021-12-15 21:09:10 +00:00
where TWorldObject : WorldObject < TUnityObject > , new ( )
where TUnityObject : MonoBehaviour
{
var list = GetUnityObjects < TUnityObject > ( ) . Where ( x = > ! typesToExclude . Contains ( x . GetType ( ) ) ) ;
2021-12-28 16:10:58 -08:00
Init < TWorldObject , TUnityObject > ( list ) ;
2021-12-15 21:09:10 +00:00
}
2021-12-28 16:10:58 -08:00
public static void Init < TWorldObject , TUnityObject > ( IEnumerable < TUnityObject > listToInitFrom )
2021-12-15 21:09:10 +00:00
where TWorldObject : WorldObject < TUnityObject > , new ( )
where TUnityObject : MonoBehaviour
{
//DebugLog.DebugWrite($"{typeof(TWorldObject).Name} init : {listToInitFrom.Count()} instances.", MessageType.Info);
foreach ( var item in listToInitFrom )
2020-12-02 21:29:53 +00:00
{
2021-12-11 20:13:49 -08:00
var obj = new TWorldObject
{
2021-12-15 21:09:10 +00:00
AttachedObject = item ,
2022-01-12 20:10:04 -08:00
ObjectId = WorldObjects . Count
2021-12-11 20:13:49 -08:00
} ;
2021-12-15 21:09:10 +00:00
2021-12-11 14:38:54 -08:00
obj . Init ( ) ;
2022-01-12 19:12:37 -08:00
WorldObjects . Add ( obj ) ;
WorldObjectsToUnityObjects . Add ( item , obj ) ;
}
}
public static void Init < TWorldObject , TUnityObject > ( Func < TUnityObject , OWTriggerVolume > triggerSelector )
where TWorldObject : QSBTrigger < TUnityObject > , new ( )
where TUnityObject : MonoBehaviour
{
var list = GetUnityObjects < TUnityObject > ( )
. Select ( x = > ( triggerSelector ( x ) , x ) )
. Where ( x = > x . Item1 ) ;
foreach ( var ( item , owner ) in list )
{
var obj = new TWorldObject
{
AttachedObject = item ,
ObjectId = WorldObjects . Count ,
TriggerOwner = owner
} ;
obj . Init ( ) ;
2021-12-11 20:13:49 -08:00
WorldObjects . Add ( obj ) ;
2021-12-15 21:09:10 +00:00
WorldObjectsToUnityObjects . Add ( item , obj ) ;
2020-12-02 21:29:53 +00:00
}
}
2020-09-06 09:07:31 +01:00
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 19:53:55 +01:00
if ( ! QSBCore . IsHost )
2020-12-11 13:14:58 +00:00
{
2022-01-08 11:41:55 +00:00
DebugLog . ToConsole ( "Warning - Cannot write to dialogue condition dict when not server!" , MessageType . Warning ) ;
2020-12-11 13:14:58 +00:00
return ;
}
2021-06-18 22:38:32 +01:00
2020-12-11 13:14:58 +00:00
DialogueConditions [ name ] = state ;
}
2020-12-19 10:56:25 +00:00
2022-01-08 11:41:55 +00:00
public static void SetPersistentCondition ( string name , bool state )
{
if ( ! QSBCore . IsHost )
{
DebugLog . ToConsole ( "Warning - Cannot write to persistent condition dict when not server!" , MessageType . Warning ) ;
return ;
}
PersistentConditions [ name ] = state ;
}
2021-12-26 00:58:03 -08:00
public static void AddFactReveal ( string id , bool saveGame )
2020-12-19 10:56:25 +00:00
{
2021-08-08 19:53:55 +01: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 22:38:32 +01:00
2020-12-19 10:56:25 +00:00
if ( ShipLogFacts . Any ( x = > x . Id = = id ) )
{
return ;
}
2021-06-18 22:38:32 +01:00
2020-12-19 10:56:25 +00:00
ShipLogFacts . Add ( new FactReveal
{
Id = id ,
2021-12-26 00:58:03 -08:00
SaveGame = saveGame
2020-12-19 10:56:25 +00:00
} ) ;
}
2020-12-02 21:29:53 +00:00
}
2021-11-14 03:51:22 -08:00
}