245 lines
7.5 KiB
C#
Raw Normal View History

2021-12-07 15:56:08 +00:00
using OWML.Common;
2022-01-08 11:41:55 +00:00
using QSB.ConversationSync.Patches;
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();
}
public static IEnumerable<IWorldObject> GetWorldObjects() => WorldObjects;
2020-12-24 10:06:17 +00:00
public static IEnumerable<TWorldObject> GetWorldObjects<TWorldObject>()
where TWorldObject : IWorldObject
2020-12-24 10:06:17 +00:00
=> WorldObjects.OfType<TWorldObject>();
2020-08-13 19:25:12 +02:00
public static TWorldObject GetWorldObject<TWorldObject>(this int objectId)
where TWorldObject : IWorldObject
2021-02-25 22:45:32 +00:00
{
if (!WorldObjects.IsInRange(objectId))
2021-02-25 22:45:32 +00: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
if (WorldObjects[objectId] is not TWorldObject worldObject)
2021-12-11 22:04:48 -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
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)
{
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)
{
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
{
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)
{
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);
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
{
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);
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
{
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-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
public static IEnumerable<TUnityObject> GetUnityObjects<TUnityObject>()
where TUnityObject : MonoBehaviour
=> Resources.FindObjectsOfTypeAll<TUnityObject>()
.Where(x => x.gameObject.scene.name != null);
public static void Init<TWorldObject, TUnityObject>()
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>();
Init<TWorldObject, TUnityObject>(list);
2021-12-15 21:09:10 +00: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()));
Init<TWorldObject, TUnityObject>(list);
2021-12-15 21:09:10 +00: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
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;
}
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,
SaveGame = saveGame
2020-12-19 10:56:25 +00:00
});
}
2020-12-02 21:29:53 +00:00
}
}