quantum-space-buddies/QSB/QuantumSync/QuantumManager.cs

142 lines
4.3 KiB
C#
Raw Normal View History

2021-01-31 16:14:17 +00:00
using OWML.Common;
using OWML.Utils;
2021-02-14 12:47:40 +00:00
using QSB.Events;
2021-01-05 15:56:14 +00:00
using QSB.Player;
2021-01-03 16:09:58 +00:00
using QSB.QuantumSync.WorldObjects;
2021-01-31 16:14:17 +00:00
using QSB.Utility;
using QSB.WorldSync;
2020-12-22 21:39:53 +00:00
using System.Collections.Generic;
2021-01-18 12:33:07 +00:00
using System.Linq;
2021-01-05 15:56:14 +00:00
using System.Reflection;
2020-12-22 21:39:53 +00:00
using UnityEngine;
namespace QSB.QuantumSync
{
internal class QuantumManager : MonoBehaviour
{
public static QuantumManager Instance { get; private set; }
2021-02-18 15:36:11 +00:00
public Dictionary<Shape[], VisibilityTracker> _shapesToTrackers = new Dictionary<Shape[], VisibilityTracker>();
public Dictionary<VisibilityObject, List<VisibilityTracker>> _objectToTrackers = new Dictionary<VisibilityObject, List<VisibilityTracker>>();
2021-01-18 12:33:07 +00:00
public QuantumShrine Shrine;
public bool IsReady;
2020-12-22 21:39:53 +00:00
public void Awake()
{
Instance = this;
2021-01-31 16:14:17 +00:00
QSBSceneManager.OnUniverseSceneLoaded += RebuildQuantumObjects;
2020-12-22 21:39:53 +00:00
}
2021-01-31 16:14:17 +00:00
public void OnDestroy() => QSBSceneManager.OnUniverseSceneLoaded -= RebuildQuantumObjects;
2020-12-23 22:43:05 +00:00
2021-01-31 16:14:17 +00:00
public void RebuildQuantumObjects(OWScene scene)
2020-12-22 21:39:53 +00:00
{
2021-02-01 15:44:21 +00:00
DebugLog.DebugWrite("Rebuilding quantum objects...", MessageType.Warning);
2021-02-18 15:36:11 +00:00
QSBWorldSync.Init<QSBSocketedQuantumObject, SocketedQuantumObject>();
QSBWorldSync.Init<QSBMultiStateQuantumObject, MultiStateQuantumObject>();
QSBWorldSync.Init<QSBQuantumSocket, QuantumSocket>();
QSBWorldSync.Init<QSBQuantumShuffleObject, QuantumShuffleObject>();
2021-01-26 14:07:17 +00:00
if (scene == OWScene.SolarSystem)
{
Shrine = Resources.FindObjectsOfTypeAll<QuantumShrine>().First();
}
2021-02-18 15:36:11 +00:00
var visibilityObjects = Resources.FindObjectsOfTypeAll<VisibilityObject>().Where(
x => x != null
&& x.GetValue<VisibilityTracker[]>("_visibilityTrackers") != null
&& x.GetValue<VisibilityTracker[]>("_visibilityTrackers")?.Length != 0);
var trackers = Resources.FindObjectsOfTypeAll<VisibilityTracker>();
foreach (var tracker in trackers)
{
if (tracker.GetType() != typeof(ShapeVisibilityTracker))
{
continue;
}
var shapes = tracker.GetValue<Shape[]>("_shapes");
if (shapes == null)
{
continue;
}
_shapesToTrackers.Add(shapes, tracker);
var visibilityObject = visibilityObjects.FirstOrDefault(x => x.GetValue<VisibilityTracker[]>("_visibilityTrackers").Contains(tracker));
if (visibilityObject == null)
{
continue;
}
if (_objectToTrackers.ContainsKey(visibilityObject))
{
_objectToTrackers[visibilityObject].Add(tracker);
}
else
{
_objectToTrackers.Add(
visibilityObject,
new List<VisibilityTracker>()
{
tracker
});
}
}
IsReady = true;
2020-12-22 21:39:53 +00:00
}
2021-02-14 12:47:40 +00:00
public void CheckExistingPlayers()
{
DebugLog.DebugWrite("Checking quantum objects for non-existent players...", MessageType.Info);
var quantumObjects = QSBWorldSync.GetWorldObjects<IQSBQuantumObject>().ToList();
for (var i = 0; i < quantumObjects.Count; i++)
{
var obj = quantumObjects[i];
if (!QSBPlayerManager.PlayerExists(obj.ControllingPlayer))
{
var idToSend = obj.IsEnabled ? QSBPlayerManager.LocalPlayerId : 0u;
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, i, idToSend);
}
}
}
2021-01-26 14:07:17 +00:00
public void OnRenderObject()
2021-01-03 16:09:58 +00:00
{
2021-01-31 16:14:17 +00:00
if (!QSBCore.HasWokenUp || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug)
2021-01-03 16:09:58 +00:00
{
return;
}
2021-01-18 12:33:07 +00:00
2021-01-26 14:07:17 +00:00
if (Shrine != null)
{
Popcron.Gizmos.Sphere(Shrine.transform.position, 10f, Color.magenta);
}
}
public static bool IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
{
return tracker.gameObject.activeInHierarchy
&& QSBPlayerManager.GetPlayerCameras(!ignoreLocalCamera)
.Any(x => (bool)tracker.GetType()
.GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(tracker, new object[] { x.GetFrustumPlanes() }));
}
public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
{
return tracker.gameObject.activeInHierarchy
&& IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera)
&& QSBPlayerManager.GetPlayerCameras(!ignoreLocalCamera)
.Any(x => VisibilityOccluder.CanYouSee(tracker, x.mainCamera.transform.position));
}
2021-02-18 10:34:35 +00:00
public int GetId(IQSBQuantumObject obj)
=> QSBWorldSync
.GetWorldObjects<IQSBQuantumObject>()
.ToList()
.IndexOf(obj);
public IQSBQuantumObject GetObject(int id)
=> QSBWorldSync
.GetWorldObjects<IQSBQuantumObject>()
.ToList()[id];
2020-12-22 21:39:53 +00:00
}
2020-12-23 10:43:13 +00:00
}