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

206 lines
6.0 KiB
C#
Raw Normal View History

2022-01-29 04:49:07 +00:00
using Cysharp.Threading.Tasks;
using OWML.Common;
2021-12-22 22:46:37 +00:00
using QSB.Messaging;
2021-01-05 15:56:14 +00:00
using QSB.Player;
2021-12-24 01:07:29 +00:00
using QSB.QuantumSync.Messages;
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;
2021-02-21 18:25:25 +00:00
using System.Collections.Generic;
2021-01-18 12:33:07 +00:00
using System.Linq;
2022-01-29 04:49:07 +00:00
using System.Threading;
2020-12-22 21:39:53 +00:00
using UnityEngine;
2022-03-03 03:46:33 +00:00
namespace QSB.QuantumSync;
internal class QuantumManager : WorldObjectManager
2020-12-22 21:39:53 +00:00
{
2022-03-03 03:46:33 +00:00
public override WorldObjectScene WorldObjectScene => WorldObjectScene.Both;
2022-03-03 03:46:33 +00:00
public static QuantumShrine Shrine { get; private set; }
2020-12-22 21:39:53 +00:00
2022-03-03 03:46:33 +00:00
public void Awake() => QSBPlayerManager.OnRemovePlayer += PlayerLeave;
2020-12-23 22:43:05 +00:00
2022-03-03 03:46:33 +00:00
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct)
{
DebugLog.DebugWrite("Building quantum objects...", MessageType.Info);
QSBWorldSync.Init<QSBQuantumState, QuantumState>();
QSBWorldSync.Init<QSBSocketedQuantumObject, SocketedQuantumObject>();
QSBWorldSync.Init<QSBMultiStateQuantumObject, MultiStateQuantumObject>();
QSBWorldSync.Init<QSBQuantumSocket, QuantumSocket>();
QSBWorldSync.Init<QSBQuantumShuffleObject, QuantumShuffleObject>();
QSBWorldSync.Init<QSBQuantumMoon, QuantumMoon>();
QSBWorldSync.Init<QSBEyeProxyQuantumMoon, EyeProxyQuantumMoon>();
QSBWorldSync.Init<QSBQuantumSkeletonTower, QuantumSkeletonTower>();
if (scene == OWScene.SolarSystem)
2020-12-22 21:39:53 +00:00
{
2022-03-03 03:46:33 +00:00
Shrine = QSBWorldSync.GetUnityObjects<QuantumShrine>().First();
}
UpdateFromDebugSetting();
}
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
public void PlayerLeave(PlayerInfo player)
{
if (!QSBCore.IsHost)
{
return;
2020-12-22 21:39:53 +00:00
}
2022-03-03 03:46:33 +00:00
foreach (var obj in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>())
2021-02-14 12:47:40 +00:00
{
2022-03-03 03:46:33 +00:00
if (obj.ControllingPlayer == player.PlayerId)
2021-03-23 13:18:29 +00:00
{
2022-03-03 03:46:33 +00:00
obj.SendMessage(new QuantumAuthorityMessage(obj.IsEnabled ? QSBPlayerManager.LocalPlayerId : 0u));
2021-03-23 13:18:29 +00:00
}
2022-03-03 03:46:33 +00:00
}
}
2021-06-18 21:38:32 +00:00
2022-03-03 03:46:33 +00:00
public void OnRenderObject()
{
if (!QSBCore.DebugSettings.DrawLines)
{
return;
2021-02-14 12:47:40 +00:00
}
2022-03-03 03:46:33 +00:00
if (Shrine != null)
2021-01-03 16:09:58 +00:00
{
2022-03-03 03:46:33 +00:00
Popcron.Gizmos.Sphere(Shrine.transform.position, 10f, Color.magenta);
}
}
2021-01-18 12:33:07 +00:00
public static (bool FoundPlayers, List<PlayerInfo> PlayersWhoCanSee) IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
2022-03-03 03:46:33 +00:00
{
if (!QSBWorldSync.AllObjectsReady)
{
return (false, new List<PlayerInfo>());
2021-01-26 14:07:17 +00:00
}
2022-03-03 03:46:33 +00:00
var playersWithCameras = QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera);
if (playersWithCameras.Count == 0)
{
2022-03-03 03:46:33 +00:00
DebugLog.ToConsole($"Warning - Could not find any players with cameras!", MessageType.Warning);
return (false, new List<PlayerInfo>());
2022-03-03 03:46:33 +00:00
}
2021-07-11 15:18:47 +00:00
2022-03-03 03:46:33 +00:00
if (!tracker.gameObject.activeInHierarchy)
{
return (false, new List<PlayerInfo>());
2022-03-03 03:46:33 +00:00
}
2021-06-18 21:38:32 +00:00
2022-03-03 03:46:33 +00:00
var playersWhoCanSee = new List<PlayerInfo>();
var foundPlayers = false;
foreach (var player in playersWithCameras)
{
if (player.Camera == null)
2021-03-25 20:56:26 +00:00
{
2022-03-06 09:01:02 +00:00
DebugLog.ToConsole($"Warning - Camera is null for id:{player}!", MessageType.Warning);
2022-03-03 03:46:33 +00:00
continue;
2021-03-25 20:56:26 +00:00
}
2021-06-18 21:38:32 +00:00
2022-03-03 03:46:33 +00:00
var isInFrustum = tracker.IsInFrustum(player.Camera.GetFrustumPlanes());
if (isInFrustum)
2021-03-25 20:56:26 +00:00
{
2022-03-03 03:46:33 +00:00
playersWhoCanSee.Add(player);
foundPlayers = true;
2021-03-25 20:56:26 +00:00
}
}
return (foundPlayers, playersWhoCanSee);
2022-03-03 03:46:33 +00:00
}
2022-03-06 11:27:15 +00:00
public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera) =>
tracker.gameObject.activeInHierarchy
&& IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera).FoundPlayers
2022-03-06 11:27:15 +00:00
&& QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera)
.Any(x => VisibilityOccluder.CanYouSee(tracker, x.Camera.mainCamera.transform.position));
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
public static IEnumerable<PlayerInfo> GetEntangledPlayers(QuantumObject obj)
{
if (!QSBWorldSync.AllObjectsReady)
{
return Enumerable.Empty<PlayerInfo>();
}
2022-03-03 03:46:33 +00:00
var worldObj = obj.GetWorldObject<IQSBQuantumObject>();
return QSBPlayerManager.PlayerList.Where(x => x.EntangledObject == worldObj);
}
#region debug shapes
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
private static GameObject _debugSphere, _debugCube, _debugCapsule;
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
private class DebugShape : MonoBehaviour { }
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
public static void UpdateFromDebugSetting()
{
if (QSBCore.DebugSettings.DrawQuantumVisibilityObjects)
2022-01-18 23:50:20 +00:00
{
2022-03-03 03:46:33 +00:00
if (_debugSphere == null)
2022-01-18 23:50:20 +00:00
{
2022-03-03 03:46:33 +00:00
_debugSphere = QSBCore.DebugAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/Sphere.prefab");
}
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
if (_debugCube == null)
{
_debugCube = QSBCore.DebugAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/Cube.prefab");
}
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
if (_debugCapsule == null)
{
_debugCapsule = QSBCore.DebugAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/Capsule.prefab");
}
2022-01-18 23:50:20 +00:00
2022-03-03 03:46:33 +00:00
foreach (var quantumObject in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>())
{
foreach (var shape in quantumObject.GetAttachedShapes())
2022-01-18 23:50:20 +00:00
{
2022-03-03 03:46:33 +00:00
if (shape is BoxShape boxShape)
2022-01-18 23:50:20 +00:00
{
2022-03-03 03:46:33 +00:00
var newCube = Instantiate(_debugCube);
newCube.transform.parent = shape.transform;
newCube.transform.localPosition = Vector3.zero;
newCube.transform.localRotation = Quaternion.Euler(0, 0, 0);
newCube.transform.localScale = boxShape.size;
newCube.AddComponent<DebugShape>();
}
else if (shape is SphereShape sphereShape)
{
var newSphere = Instantiate(_debugSphere);
newSphere.transform.parent = shape.transform;
newSphere.transform.localPosition = Vector3.zero;
newSphere.transform.localRotation = Quaternion.Euler(0, 0, 0);
newSphere.transform.localScale = Vector3.one * (sphereShape.radius * 2);
newSphere.AddComponent<DebugShape>();
}
else if (shape is CapsuleShape capsuleShape)
{
var newCapsule = Instantiate(_debugCapsule);
newCapsule.transform.parent = shape.transform;
newCapsule.transform.localPosition = Vector3.zero;
newCapsule.transform.localRotation = Quaternion.Euler(0, 0, 0);
newCapsule.transform.localScale = new Vector3(capsuleShape.radius * 2, capsuleShape.height, capsuleShape.radius * 2);
newCapsule.AddComponent<DebugShape>();
2022-01-18 23:50:20 +00:00
}
}
}
2022-03-03 03:46:33 +00:00
}
else
{
foreach (var quantumObject in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>())
2022-01-18 23:50:20 +00:00
{
2022-03-03 03:46:33 +00:00
foreach (var shape in quantumObject.GetAttachedShapes())
2022-01-18 23:50:20 +00:00
{
2022-03-03 03:46:33 +00:00
var debugShape = shape.GetComponentInChildren<DebugShape>();
if (debugShape)
2022-01-18 23:50:20 +00:00
{
2022-03-03 03:46:33 +00:00
Destroy(debugShape.gameObject);
2022-01-18 23:50:20 +00:00
}
}
}
}
}
2022-03-03 03:46:33 +00:00
#endregion
2022-03-06 11:27:15 +00:00
}