232 lines
7.3 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using OWML.Common;
2021-04-11 17:05:02 +01:00
using QSB.OrbSync.TransformSync;
using QSB.OrbSync.WorldObjects;
2020-09-29 21:34:46 +01:00
using QSB.Utility;
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
{
public static List<NomaiInterfaceOrb> OldOrbList { get; set; } = new();
public static List<CharacterDialogueTree> OldDialogueTrees { get; set; } = new();
public static Dictionary<string, bool> DialogueConditions { get; } = new();
public static List<FactReveal> ShipLogFacts { get; } = 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
2020-12-24 10:06:17 +00:00
public static IEnumerable<TWorldObject> GetWorldObjects<TWorldObject>()
=> WorldObjects.OfType<TWorldObject>();
2020-08-13 19:25:12 +02:00
2021-02-24 10:45:25 +00:00
public static TWorldObject GetWorldFromId<TWorldObject>(int id)
2021-02-25 22:45:32 +00:00
{
var worldObjects = GetWorldObjects<TWorldObject>().ToList();
if (id < 0 || id >= worldObjects.Count)
2021-02-25 22:45:32 +00:00
{
DebugLog.ToConsole($"Warning - Tried to find {typeof(TWorldObject).Name} id {id}. Count is {worldObjects.Count}.", MessageType.Warning);
2021-02-25 22:45:32 +00:00
return default;
}
2021-06-18 22:38:32 +01:00
return worldObjects[id];
2021-02-25 22:45:32 +00:00
}
2020-09-06 09:07:31 +01:00
2021-11-01 19:51:37 +00:00
public static IWorldObject GetWorldFromUnity(MonoBehaviour unityObject)
{
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.TryGetValue(unityObject, out var returnObject))
2021-11-01 19:51:37 +00:00
{
DebugLog.ToConsole($"Error - WorldObjectsToUnityObjects does not contain \"{unityObject.name}\"! TUnityObject:{unityObject.GetType().Name}", MessageType.Error);
return default;
}
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-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 22:38:32 +01: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 22:38:32 +01:00
if (!WorldObjectsToUnityObjects.TryGetValue(unityObject, out var returnObject))
2021-03-18 16:57:56 +00:00
{
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 22:38:32 +01:00
2021-11-01 15:49:00 +00:00
if (returnObject == null)
{
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);
return default;
}
return (TWorldObject)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 - {((IWorldObject)typeSubset).Name} doesn't exist in list of {typeof(TTypeSubset).Name} !", MessageType.Warning);
2021-02-25 22:45:32 +00:00
}
2021-06-18 22:38:32 +01:00
2021-02-25 22:45:32 +00:00
return index;
}
2021-02-24 10:45:25 +00:00
public static void RemoveWorldObjects<TWorldObject>()
2021-02-09 21:35:31 +00:00
{
if (WorldObjects.Count == 0)
2021-10-24 10:47:25 +01:00
{
DebugLog.ToConsole($"Warning - Trying to remove WorldObjects of type {typeof(TWorldObject).Name}, but there are no WorldObjects!", MessageType.Warning);
return;
2021-10-24 10:47:25 +01:00
}
2021-02-09 21:35:31 +00:00
var itemsToRemove = WorldObjects.Where(x => x is TWorldObject);
2021-10-24 10:47:25 +01:00
2021-02-09 21:35:31 +00:00
foreach (var item in itemsToRemove)
{
try
{
2021-10-24 10:47:25 +01:00
WorldObjectsToUnityObjects.Remove(item.ReturnObject());
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-02-09 21:35:31 +00:00
WorldObjects.RemoveAll(x => x is TWorldObject);
}
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>
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>();
var list = GetUnityObjects<TUnityObject>().ToList();
2021-08-08 20:04:55 +01: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 09:07:31 +01:00
2020-12-24 09:12:47 +01:00
private static TWorldObject CreateWorldObject<TWorldObject>()
where TWorldObject : IWorldObject
2020-12-24 09:12:47 +01:00
{
var worldObject = (TWorldObject)Activator.CreateInstance(typeof(TWorldObject));
WorldObjects.Add(worldObject);
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 09:12:47 +01:00
return worldObject;
}
2021-07-07 09:02:23 +01: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 22:38:32 +01: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 22:38:32 +01: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 22:38:32 +01: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 19:53:55 +01: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 22:38:32 +01: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 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,
ShowNotification = showNotification
});
}
2020-12-02 21:29:53 +00:00
}
}