2022-01-28 20:49:07 -08:00
using Cysharp.Threading.Tasks ;
2022-01-29 15:33:33 -08:00
using MonoMod.Utils ;
2022-01-28 20:49:07 -08:00
using OWML.Common ;
2022-04-06 11:35:40 -07:00
using QSB.ConversationSync.Messages ;
2021-12-26 00:53:43 -08:00
using QSB.LogSync ;
2022-04-06 11:35:40 -07:00
using QSB.LogSync.Messages ;
2022-01-25 23:46:41 -08:00
using QSB.Messaging ;
2022-01-18 00:27:32 -08:00
using QSB.Player.TransformSync ;
2022-01-12 19:18:59 -08:00
using QSB.TriggerSync.WorldObjects ;
2020-09-29 21:34:46 +01:00
using QSB.Utility ;
2022-03-14 00:51:25 -07:00
using QSB.Utility.LinkedWorldObject ;
2021-12-07 15:56:08 +00:00
using System ;
using System.Collections.Generic ;
2022-12-06 17:12:25 +00:00
using System.Diagnostics ;
2021-12-07 15:56:08 +00:00
using System.Linq ;
2022-01-28 20:49:07 -08:00
using System.Threading ;
2020-12-23 22:43:05 +00:00
using UnityEngine ;
2020-08-13 19:25:12 +02:00
2022-03-02 19:46:33 -08:00
namespace QSB.WorldSync ;
public static class QSBWorldSync
2020-08-13 19:25:12 +02:00
{
2022-03-02 19:46:33 -08:00
public static WorldObjectManager [ ] Managers ;
2022-12-12 14:06:37 -08:00
private static readonly Dictionary < string , List < IWorldObject > > _managerToBuiltObjects = new ( ) ;
public static readonly Dictionary < string , string > ManagerHashes = new ( ) ;
2022-03-02 19:46:33 -08: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 ; }
private static CancellationTokenSource _cts ;
private static readonly Dictionary < WorldObjectManager , UniTask > _managersBuilding = new ( ) ;
private static readonly Dictionary < IWorldObject , UniTask > _objectsIniting = new ( ) ;
public static async UniTaskVoid BuildWorldObjects ( OWScene scene )
2020-12-02 21:29:53 +00:00
{
2022-03-02 19:46:33 -08:00
if ( _cts ! = null )
2022-02-24 22:04:54 -08:00
{
2022-03-02 19:46:33 -08:00
return ;
}
2022-01-28 21:05:04 -08:00
2022-03-02 19:46:33 -08:00
_cts = new CancellationTokenSource ( ) ;
2022-01-28 21:05:04 -08:00
2022-03-02 19:46:33 -08:00
if ( ! PlayerTransformSync . LocalInstance )
{
DebugLog . ToConsole ( "Warning - Tried to build WorldObjects when LocalPlayer is not ready! Building when ready..." , MessageType . Warning ) ;
await UniTask . WaitUntil ( ( ) = > PlayerTransformSync . LocalInstance , cancellationToken : _cts . Token ) ;
}
2022-01-18 00:27:32 -08:00
2022-03-02 19:46:33 -08:00
GameInit ( ) ;
2022-02-27 04:40:44 -08:00
2022-03-02 19:46:33 -08:00
foreach ( var manager in Managers )
{
2022-04-10 16:33:47 -07:00
if ( ShouldIgnoreManager ( manager ) )
2022-03-11 10:04:11 -08:00
{
continue ;
}
2022-03-02 19:46:33 -08:00
var task = UniTask . Create ( async ( ) = >
{
await manager . Try ( "building world objects" , async ( ) = >
2022-01-28 20:49:07 -08:00
{
2022-03-02 19:46:33 -08:00
await manager . BuildWorldObjects ( scene , _cts . Token ) ;
DebugLog . DebugWrite ( $"Built {manager}" , MessageType . Info ) ;
2022-01-28 20:49:07 -08:00
} ) ;
2022-03-02 19:46:33 -08:00
_managersBuilding . Remove ( manager ) ;
} ) ;
if ( ! task . Status . IsCompleted ( ) )
2022-02-27 04:40:44 -08:00
{
2022-03-02 19:46:33 -08:00
_managersBuilding . Add ( manager , task ) ;
2022-02-27 04:40:44 -08:00
}
2022-03-02 19:46:33 -08:00
}
2022-01-28 20:49:07 -08:00
2022-03-02 19:46:33 -08:00
await _managersBuilding . Values ;
if ( _cts = = null )
{
return ;
}
2022-02-16 00:59:24 -08:00
2022-03-02 19:46:33 -08:00
AllObjectsAdded = true ;
DebugLog . DebugWrite ( "World Objects added." , MessageType . Success ) ;
2022-01-28 20:49:07 -08:00
2022-11-09 14:35:33 -08:00
DeterministicManager . OnWorldObjectsAdded ( ) ;
2022-12-12 14:06:37 -08:00
foreach ( var item in _managerToBuiltObjects )
2022-12-06 17:12:25 +00:00
{
var worldObjects = item . Value ;
var hash = worldObjects . Select ( x = > x . GetType ( ) . Name ) . GetMD5Hash ( ) ;
ManagerHashes [ item . Key ] = hash ;
}
2022-10-08 20:18:22 +01:00
2022-03-14 00:51:25 -07:00
if ( ! QSBCore . IsHost )
{
2022-12-06 17:12:25 +00:00
foreach ( var item in ManagerHashes )
{
new WorldObjectsHashMessage ( item . Key , item . Value ) . Send ( ) ;
}
2022-03-14 00:51:25 -07:00
new RequestLinksMessage ( ) . Send ( ) ;
}
2022-03-02 19:46:33 -08:00
await _objectsIniting . Values ;
if ( _cts = = null )
{
return ;
}
2022-01-28 20:49:07 -08:00
2022-03-02 19:46:33 -08:00
AllObjectsReady = true ;
DebugLog . DebugWrite ( "World Objects ready." , MessageType . Success ) ;
2022-01-18 00:27:32 -08:00
2022-03-02 19:46:33 -08:00
if ( ! QSBCore . IsHost )
2022-02-24 22:04:54 -08:00
{
2022-03-02 19:46:33 -08:00
new RequestInitialStatesMessage ( ) . Send ( ) ;
}
}
2022-01-28 21:56:39 -08:00
2022-03-02 19:46:33 -08:00
public static void RemoveWorldObjects ( )
{
if ( _cts = = null )
{
return ;
}
2022-01-28 21:17:59 -08:00
2022-03-02 19:46:33 -08:00
if ( _managersBuilding . Count > 0 )
{
DebugLog . DebugWrite ( $"{_managersBuilding.Count} managers still building" , MessageType . Warning ) ;
}
2022-02-25 10:00:57 -08:00
2022-03-02 19:46:33 -08:00
if ( _objectsIniting . Count > 0 )
{
DebugLog . DebugWrite ( $"{_objectsIniting.Count} objects still initing" , MessageType . Warning ) ;
}
2022-01-18 00:46:27 -08:00
2022-03-02 19:46:33 -08:00
_cts . Cancel ( ) ;
_cts . Dispose ( ) ;
_cts = null ;
2022-01-18 00:46:27 -08:00
2022-03-02 19:46:33 -08:00
_managersBuilding . Clear ( ) ;
_objectsIniting . Clear ( ) ;
AllObjectsAdded = false ;
AllObjectsReady = false ;
2022-01-18 00:46:27 -08:00
2022-12-12 14:06:37 -08:00
_managerToBuiltObjects . Clear ( ) ;
ManagerHashes . Clear ( ) ;
2022-12-06 17:12:25 +00:00
2022-03-02 19:46:33 -08:00
GameReset ( ) ;
2022-01-18 00:27:32 -08:00
2022-04-06 11:35:40 -07:00
foreach ( var worldObject in WorldObjects )
2022-03-02 19:46:33 -08:00
{
2022-04-06 11:35:40 -07:00
worldObject . Try ( "removing" , worldObject . OnRemoval ) ;
RequestInitialStatesMessage . SendInitialState - = worldObject . SendInitialState ;
2022-02-24 22:04:54 -08:00
}
2020-09-22 21:11:29 +01:00
2022-03-02 19:46:33 -08:00
WorldObjects . Clear ( ) ;
UnityObjectsToWorldObjects . Clear ( ) ;
2020-12-14 21:41:56 +01:00
2022-03-02 19:46:33 -08:00
foreach ( var manager in Managers )
{
2022-04-10 16:33:47 -07:00
if ( ShouldIgnoreManager ( manager ) )
{
continue ;
}
2022-03-02 19:46:33 -08:00
manager . Try ( "unbuilding world objects" , manager . UnbuildWorldObjects ) ;
}
}
2022-01-08 11:41:55 +00:00
2022-04-10 16:33:47 -07:00
private static bool ShouldIgnoreManager ( WorldObjectManager manager )
{
if ( manager . DlcOnly & & ! QSBCore . DLCInstalled )
{
return true ;
}
switch ( manager . WorldObjectScene )
{
case WorldObjectScene . SolarSystem when QSBSceneManager . CurrentScene ! = OWScene . SolarSystem :
case WorldObjectScene . Eye when QSBSceneManager . CurrentScene ! = OWScene . EyeOfTheUniverse :
return true ;
}
return false ;
}
2022-03-02 19:46:33 -08:00
// =======================================================================================================
2022-01-08 11:41:55 +00:00
2022-04-06 11:40:42 -07:00
private static readonly Dictionary < string , bool > DialogueConditions = new ( ) ;
2022-03-02 19:46:33 -08:00
private static readonly Dictionary < string , bool > PersistentConditions = new ( ) ;
2022-04-06 11:40:42 -07:00
private static readonly List < FactReveal > ShipLogFacts = new ( ) ;
2022-01-08 11:41:55 +00:00
2022-03-02 19:46:33 -08:00
private static readonly List < IWorldObject > WorldObjects = new ( ) ;
2022-04-01 13:48:49 -07:00
private static readonly Dictionary < MonoBehaviour , IWorldObject > UnityObjectsToWorldObjects = new ( ) ;
2022-01-08 11:41:55 +00:00
2022-05-03 21:53:18 -07:00
static QSBWorldSync ( )
{
QSBSceneManager . OnPreSceneLoad + = ( _ , _ ) = >
RemoveWorldObjects ( ) ;
QSBSceneManager . OnPostSceneLoad + = ( _ , loadScene ) = >
{
if ( QSBCore . IsInMultiplayer & & loadScene . IsUniverseScene ( ) )
{
2022-11-09 12:01:54 -08:00
// So objects have time to be deleted, made, whatever
// i.e. wait until Start has been called
2022-11-09 12:43:22 -08:00
// TODO: see if this number of frames actually works. TWEAK!
Delay . RunFramesLater ( 10 , ( ) = > BuildWorldObjects ( loadScene ) . Forget ( ) ) ;
2022-05-03 21:53:18 -07:00
}
} ;
2022-04-06 11:35:40 -07:00
RequestInitialStatesMessage . SendInitialState + = to = >
{
DialogueConditions . ForEach ( condition
= > new DialogueConditionMessage ( condition . Key , condition . Value ) { To = to } . Send ( ) ) ;
ShipLogFacts . ForEach ( fact
= > new RevealFactMessage ( fact . Id , fact . SaveGame , false ) { To = to } . Send ( ) ) ;
} ;
2022-05-03 21:53:18 -07:00
}
2022-04-06 11:35:40 -07:00
2022-03-02 19:46:33 -08:00
private static void GameInit ( )
{
2022-04-10 16:33:47 -07:00
DebugLog . DebugWrite ( "GameInit QSBWorldSync" , MessageType . Info ) ;
2022-01-08 11:41:55 +00:00
2022-03-02 19:46:33 -08:00
if ( ! QSBCore . IsHost )
{
return ;
2022-01-08 11:41:55 +00:00
}
2022-03-02 19:46:33 -08:00
DialogueConditions . Clear ( ) ;
DialogueConditions . AddRange ( DialogueConditionManager . SharedInstance . _dictConditions ) ;
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
PersistentConditions . Clear ( ) ;
2022-03-27 00:24:07 -07:00
PersistentConditions . AddRange ( PlayerData . _currentGameSave . dictConditions ) ;
2022-03-02 19:46:33 -08:00
}
2020-09-06 09:07:31 +01:00
2022-03-02 19:46:33 -08:00
private static void GameReset ( )
{
2022-04-10 16:33:47 -07:00
DebugLog . DebugWrite ( "GameReset QSBWorldSync" , MessageType . Info ) ;
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
DialogueConditions . Clear ( ) ;
PersistentConditions . Clear ( ) ;
ShipLogFacts . Clear ( ) ;
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
public static IEnumerable < IWorldObject > GetWorldObjects ( ) = > WorldObjects ;
2022-02-27 04:40:44 -08:00
2022-03-02 19:46:33 -08:00
public static IEnumerable < TWorldObject > GetWorldObjects < TWorldObject > ( )
where TWorldObject : IWorldObject
= > WorldObjects . OfType < TWorldObject > ( ) ;
2022-02-27 04:40:44 -08:00
2022-07-24 10:13:59 -07:00
public static IEnumerable < IWorldObject > GetWorldObjects ( Type type )
= > WorldObjects . Where ( type . IsInstanceOfType ) ;
2022-07-24 16:24:41 +01:00
2022-03-02 19:46:33 -08:00
public static TWorldObject GetWorldObject < TWorldObject > ( this int objectId )
where TWorldObject : IWorldObject
{
if ( ! WorldObjects . IsInRange ( objectId ) )
{
2022-03-11 00:58:14 -08:00
DebugLog . ToConsole ( $"Warning - Tried to find {typeof(TWorldObject).Name} id {objectId}. Count is {WorldObjects.Count}." , MessageType . Warning ) ;
2022-03-02 19:46:33 -08:00
return default ;
2021-03-18 16:57:56 +00:00
}
2021-02-18 10:34:35 +00:00
2022-03-02 19:46:33 -08:00
if ( WorldObjects [ objectId ] is not TWorldObject worldObject )
2020-12-02 21:29:53 +00:00
{
2022-10-08 20:18:22 +01:00
DebugLog . ToConsole ( $"Error - WorldObject id {objectId} is {WorldObjects[objectId].GetType().Name}, expected {typeof(TWorldObject).Name}." , MessageType . Error ) ;
2022-03-02 19:46:33 -08:00
return default ;
2021-12-15 21:09:10 +00:00
}
2022-03-02 19:46:33 -08:00
return worldObject ;
}
public static TWorldObject GetWorldObject < TWorldObject > ( this MonoBehaviour unityObject )
where TWorldObject : IWorldObject
{
if ( ! unityObject )
2021-12-15 21:09:10 +00:00
{
2022-03-11 00:58:14 -08: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 ) ;
2022-03-02 19:46:33 -08:00
return default ;
2021-12-15 21:09:10 +00:00
}
2022-04-01 13:48:49 -07:00
if ( ! UnityObjectsToWorldObjects . TryGetValue ( unityObject , out var worldObject ) )
2021-12-15 21:09:10 +00:00
{
2022-03-30 01:47:23 -07:00
DebugLog . ToConsole ( $"Error - UnityObjectsToWorldObjects does not contain \" { unityObject . name } \ "! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}, Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Error ) ;
2022-03-02 19:46:33 -08:00
return default ;
2022-01-12 19:12:37 -08:00
}
2022-04-01 13:48:49 -07:00
return ( TWorldObject ) worldObject ;
2022-03-02 19:46:33 -08:00
}
2022-01-12 19:12:37 -08:00
2022-05-29 14:37:27 -07:00
public static bool TryGetWorldObject < TWorldObject > ( this MonoBehaviour unityObject , out TWorldObject worldObject )
where TWorldObject : IWorldObject
{
if ( ! unityObject )
{
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 ) ;
worldObject = default ;
return false ;
}
if ( ! UnityObjectsToWorldObjects . TryGetValue ( unityObject , out var iWorldObject ) )
{
worldObject = default ;
return false ;
}
worldObject = ( TWorldObject ) iWorldObject ;
return true ;
}
2022-05-03 08:48:24 +01:00
/// <summary>
2022-05-03 21:57:52 -07:00
/// not deterministic across platforms.
/// iterates thru all objects and throws error if there isn't exactly 1.
2022-05-03 08:48:24 +01:00
/// </summary>
public static TUnityObject GetUnityObject < TUnityObject > ( )
where TUnityObject : MonoBehaviour
2022-05-03 21:57:52 -07:00
= > GetUnityObjects < TUnityObject > ( ) . Single ( ) ;
2022-05-03 08:48:24 +01:00
2022-03-02 19:46:33 -08:00
/// <summary>
2022-10-29 15:48:35 -07:00
/// not deterministic across platforms.
/// excludes prefabs and DontDestroyOnLoad objects.
2022-03-02 19:46:33 -08:00
/// </summary>
public static IEnumerable < TUnityObject > GetUnityObjects < TUnityObject > ( )
where TUnityObject : MonoBehaviour
= > Resources . FindObjectsOfTypeAll < TUnityObject > ( )
2022-10-29 15:48:35 -07:00
. Where ( x = > x . gameObject . scene . name is not ( null or "DontDestroyOnLoad" ) ) ;
2022-03-02 19:46:33 -08:00
2022-12-06 17:12:25 +00:00
// https://stackoverflow.com/a/48570616
2022-12-12 15:03:41 -08:00
private static string NameOfCallingClass ( )
2022-12-06 17:12:25 +00:00
{
string fullName ;
Type declaringType ;
var skipFrames = 2 ;
do
{
var method = new StackFrame ( skipFrames , false ) . GetMethod ( ) ;
declaringType = method . DeclaringType ;
if ( declaringType = = null )
{
return method . Name ;
}
skipFrames + + ;
fullName = CleanupFullName ( declaringType . FullName ) ;
}
while ( declaringType . Module . Name . Equals ( "mscorlib.dll" , StringComparison . OrdinalIgnoreCase ) | | declaringType = = typeof ( QSBWorldSync ) ) ;
return fullName ;
}
private static string CleanupFullName ( string fullName )
{
var ret = fullName ;
var indexOfPlus = fullName . LastIndexOf ( '+' ) ;
if ( indexOfPlus ! = - 1 )
{
ret = fullName . Remove ( indexOfPlus ) ;
}
var indexOfDot = ret . LastIndexOf ( '.' ) ;
if ( indexOfDot ! = - 1 )
{
ret = ret . Substring ( indexOfDot + 1 ) ;
}
return ret ;
}
2022-03-02 19:46:33 -08:00
public static void Init < TWorldObject , TUnityObject > ( )
where TWorldObject : WorldObject < TUnityObject > , new ( )
where TUnityObject : MonoBehaviour
{
var list = GetUnityObjects < TUnityObject > ( ) . SortDeterministic ( ) ;
Init < TWorldObject , TUnityObject > ( list ) ;
}
2022-01-28 23:22:13 -08:00
2022-03-02 19:46:33 -08:00
public static void Init < TWorldObject , TUnityObject > ( params Type [ ] typesToExclude )
where TWorldObject : WorldObject < TUnityObject > , new ( )
where TUnityObject : MonoBehaviour
{
var list = GetUnityObjects < TUnityObject > ( )
. Where ( x = > ! typesToExclude . Contains ( x . GetType ( ) ) )
. SortDeterministic ( ) ;
Init < TWorldObject , TUnityObject > ( list ) ;
}
2022-02-27 04:40:44 -08:00
2022-03-02 19:46:33 -08:00
/// <summary>
/// make sure to sort the list!
/// </summary>
public static void Init < TWorldObject , TUnityObject > ( IEnumerable < TUnityObject > listToInitFrom )
where TWorldObject : WorldObject < TUnityObject > , new ( )
where TUnityObject : MonoBehaviour
{
foreach ( var item in listToInitFrom )
{
var obj = new TWorldObject
2022-02-27 04:40:44 -08:00
{
2022-03-02 19:46:33 -08:00
AttachedObject = item ,
ObjectId = WorldObjects . Count
} ;
AddAndInit ( obj , item ) ;
2020-12-02 21:29:53 +00:00
}
2022-03-02 19:46:33 -08:00
}
2020-09-06 09:07:31 +01:00
2022-03-02 19:46:33 -08:00
public static void Init < TWorldObject , TUnityObject > ( Func < TUnityObject , OWTriggerVolume > triggerSelector )
where TWorldObject : QSBTrigger < TUnityObject > , new ( )
where TUnityObject : MonoBehaviour
{
var list = GetUnityObjects < TUnityObject > ( ) . SortDeterministic ( ) ;
foreach ( var owner in list )
2020-12-11 13:14:58 +00:00
{
2022-03-02 19:46:33 -08:00
var item = triggerSelector ( owner ) ;
if ( ! item )
2020-12-11 13:14:58 +00:00
{
2022-03-02 19:46:33 -08:00
continue ;
2020-12-11 13:14:58 +00:00
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
var obj = new TWorldObject
{
AttachedObject = item ,
ObjectId = WorldObjects . Count ,
TriggerOwner = owner
} ;
AddAndInit ( obj , item ) ;
2020-12-11 13:14:58 +00:00
}
2022-03-02 19:46:33 -08:00
}
private static void AddAndInit < TWorldObject , TUnityObject > ( TWorldObject worldObject , TUnityObject unityObject )
where TWorldObject : WorldObject < TUnityObject >
where TUnityObject : MonoBehaviour
{
2022-04-01 13:48:49 -07:00
if ( ! UnityObjectsToWorldObjects . TryAdd ( unityObject , worldObject ) )
2022-04-01 19:08:03 +01:00
{
2022-04-01 13:48:49 -07:00
DebugLog . ToConsole ( $"Error - UnityObjectsToWorldObjects already contains \" { unityObject . name } \ "! TWorldObject:{typeof(TWorldObject).Name}, TUnityObject:{unityObject.GetType().Name}, Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Error ) ;
return ;
2022-04-01 19:08:03 +01:00
}
2020-12-19 10:56:25 +00:00
2022-12-06 17:12:25 +00:00
var className = NameOfCallingClass ( ) ;
2022-12-12 14:06:37 -08:00
if ( ! _managerToBuiltObjects . ContainsKey ( className ) )
2022-12-06 17:12:25 +00:00
{
2022-12-12 14:06:37 -08:00
_managerToBuiltObjects . Add ( className , new List < IWorldObject > { worldObject } ) ;
2022-12-06 17:12:25 +00:00
}
else
{
2022-12-12 14:06:37 -08:00
_managerToBuiltObjects [ className ] . Add ( worldObject ) ;
2022-12-06 17:12:25 +00:00
}
2022-04-06 11:35:40 -07:00
WorldObjects . Add ( worldObject ) ;
RequestInitialStatesMessage . SendInitialState + = worldObject . SendInitialState ;
2022-03-02 19:46:33 -08:00
var task = UniTask . Create ( async ( ) = >
2022-01-08 11:41:55 +00:00
{
2022-03-02 19:46:33 -08:00
await worldObject . Try ( "initing" , ( ) = > worldObject . Init ( _cts . Token ) ) ;
_objectsIniting . Remove ( worldObject ) ;
} ) ;
if ( ! task . Status . IsCompleted ( ) )
{
_objectsIniting . Add ( worldObject , task ) ;
}
}
2022-01-08 11:41:55 +00:00
2022-03-02 19:46:33 -08:00
public static void SetDialogueCondition ( string name , bool state )
{
if ( ! QSBCore . IsHost )
{
DebugLog . ToConsole ( "Warning - Cannot write to dialogue condition dict when not server!" , MessageType . Warning ) ;
return ;
2022-01-08 11:41:55 +00:00
}
2022-03-02 19:46:33 -08:00
DialogueConditions [ name ] = state ;
}
public static void SetPersistentCondition ( string name , bool state )
{
if ( ! QSBCore . IsHost )
2020-12-19 10:56:25 +00:00
{
2022-03-02 19:46:33 -08:00
DebugLog . ToConsole ( "Warning - Cannot write to persistent condition dict when not server!" , MessageType . Warning ) ;
return ;
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
PersistentConditions [ name ] = state ;
}
2022-02-24 22:04:54 -08:00
2022-03-02 19:46:33 -08:00
public static void AddFactReveal ( string id , bool saveGame )
{
if ( ! QSBCore . IsHost )
{
DebugLog . ToConsole ( "Warning - Cannot write to fact list when not server!" , MessageType . Warning ) ;
return ;
}
if ( ShipLogFacts . Any ( x = > x . Id = = id ) )
{
return ;
2020-12-19 10:56:25 +00:00
}
2022-03-02 19:46:33 -08:00
ShipLogFacts . Add ( new FactReveal
{
Id = id ,
SaveGame = saveGame
} ) ;
2020-12-02 21:29:53 +00:00
}
2022-03-11 10:04:11 -08:00
}