2021-02-28 15:06:11 +00:00
|
|
|
|
using OWML.Common;
|
2021-12-23 17:07:29 -08:00
|
|
|
|
using QSB.Messaging;
|
2021-01-26 14:07:17 +00:00
|
|
|
|
using QSB.Player;
|
2021-12-23 17:07:29 -08:00
|
|
|
|
using QSB.QuantumSync.Messages;
|
2021-02-19 09:40:46 +00:00
|
|
|
|
using QSB.Utility;
|
2021-01-26 14:07:17 +00:00
|
|
|
|
using QSB.WorldSync;
|
2021-02-27 14:23:35 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2021-10-18 09:02:48 +01:00
|
|
|
|
using UnityEngine;
|
2022-01-06 14:57:53 -08:00
|
|
|
|
using Object = UnityEngine.Object;
|
2021-01-26 14:07:17 +00:00
|
|
|
|
|
|
|
|
|
namespace QSB.QuantumSync.WorldObjects
|
|
|
|
|
{
|
2021-01-29 15:30:40 +00:00
|
|
|
|
internal abstract class QSBQuantumObject<T> : WorldObject<T>, IQSBQuantumObject
|
2021-02-27 14:23:35 +00:00
|
|
|
|
where T : QuantumObject
|
2021-01-26 14:07:17 +00:00
|
|
|
|
{
|
2022-01-11 19:21:45 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// whether the controlling player is always the host <br/>
|
|
|
|
|
/// also means this object is considered always enabled
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected virtual bool HostControls => false;
|
2022-01-02 21:26:52 -08:00
|
|
|
|
public uint ControllingPlayer { get; set; }
|
2022-01-11 19:21:45 -08:00
|
|
|
|
public bool IsEnabled { get; private set; }
|
2021-01-26 14:07:17 +00:00
|
|
|
|
|
2021-02-19 09:40:46 +00:00
|
|
|
|
public override void OnRemoval()
|
|
|
|
|
{
|
2022-01-11 19:21:45 -08:00
|
|
|
|
if (HostControls)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-27 14:23:35 +00:00
|
|
|
|
foreach (var shape in GetAttachedShapes())
|
|
|
|
|
{
|
2021-12-02 12:38:38 +00:00
|
|
|
|
shape.OnShapeActivated -= OnEnable;
|
|
|
|
|
shape.OnShapeDeactivated -= OnDisable;
|
2021-02-27 14:23:35 +00:00
|
|
|
|
}
|
2021-02-19 09:40:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-11 14:38:54 -08:00
|
|
|
|
public override void Init()
|
2021-02-19 09:40:46 +00:00
|
|
|
|
{
|
2022-01-06 14:57:53 -08:00
|
|
|
|
if (QSBCore.ShowQuantumVisibilityObjects)
|
2021-10-18 09:02:48 +01:00
|
|
|
|
{
|
2022-01-06 14:57:53 -08:00
|
|
|
|
var debugBundle = QSBCore.DebugAssetBundle;
|
|
|
|
|
var sphere = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Sphere.prefab");
|
|
|
|
|
var cube = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Cube.prefab");
|
|
|
|
|
var capsule = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Capsule.prefab");
|
2021-10-18 09:02:48 +01:00
|
|
|
|
|
2022-01-06 14:57:53 -08:00
|
|
|
|
if (cube == null)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($"CUBE IS NULL");
|
|
|
|
|
}
|
2021-10-18 09:02:48 +01:00
|
|
|
|
|
2022-01-06 14:57:53 -08:00
|
|
|
|
if (sphere == null)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($"SPHERE IS NULL");
|
|
|
|
|
}
|
2021-10-18 09:02:48 +01:00
|
|
|
|
|
2022-01-06 14:57:53 -08:00
|
|
|
|
if (capsule == null)
|
2021-02-27 14:23:35 +00:00
|
|
|
|
{
|
2022-01-06 14:57:53 -08:00
|
|
|
|
DebugLog.DebugWrite($"CAPSULE IS NULL");
|
2021-02-27 14:23:35 +00:00
|
|
|
|
}
|
2021-10-18 09:02:48 +01:00
|
|
|
|
|
2022-01-06 14:57:53 -08:00
|
|
|
|
foreach (var shape in GetAttachedShapes())
|
2021-10-18 09:02:48 +01:00
|
|
|
|
{
|
2021-10-20 09:21:26 +01:00
|
|
|
|
if (shape is BoxShape boxShape)
|
|
|
|
|
{
|
2022-01-02 23:53:38 -08:00
|
|
|
|
var newCube = Object.Instantiate(cube);
|
2021-10-20 09:21:26 +01:00
|
|
|
|
newCube.transform.parent = shape.transform;
|
|
|
|
|
newCube.transform.localPosition = Vector3.zero;
|
|
|
|
|
newCube.transform.localRotation = Quaternion.Euler(0, 0, 0);
|
|
|
|
|
newCube.transform.localScale = boxShape.size;
|
|
|
|
|
}
|
|
|
|
|
else if (shape is SphereShape sphereShape)
|
|
|
|
|
{
|
2022-01-02 23:53:38 -08:00
|
|
|
|
var newSphere = Object.Instantiate(sphere);
|
2021-10-20 09:21:26 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
else if (shape is CapsuleShape capsuleShape)
|
|
|
|
|
{
|
|
|
|
|
var newCapsule = Object.Instantiate(capsule);
|
|
|
|
|
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);
|
|
|
|
|
}
|
2021-10-18 09:02:48 +01:00
|
|
|
|
}
|
2021-03-17 17:04:57 +00:00
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2021-12-11 15:30:35 -08:00
|
|
|
|
StartDelayedReady();
|
2021-12-02 12:38:38 +00:00
|
|
|
|
QSBCore.UnityEvents.FireInNUpdates(LateInit, 5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LateInit()
|
|
|
|
|
{
|
2021-12-11 15:30:35 -08:00
|
|
|
|
FinishDelayedReady();
|
2022-01-11 19:21:45 -08:00
|
|
|
|
|
|
|
|
|
if (HostControls)
|
|
|
|
|
{
|
|
|
|
|
// smallest player id is the host
|
|
|
|
|
ControllingPlayer = QSBPlayerManager.PlayerList.Min(x => x.PlayerId);
|
|
|
|
|
IsEnabled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-02 21:26:52 -08:00
|
|
|
|
var attachedShapes = GetAttachedShapes();
|
|
|
|
|
if (attachedShapes.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
IsEnabled = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-12-02 12:38:38 +00:00
|
|
|
|
|
2022-01-06 14:57:53 -08:00
|
|
|
|
foreach (var shape in attachedShapes)
|
|
|
|
|
{
|
|
|
|
|
shape.OnShapeActivated += OnEnable;
|
|
|
|
|
shape.OnShapeDeactivated += OnDisable;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-02 21:26:52 -08:00
|
|
|
|
if (attachedShapes.All(x => x.enabled && x.gameObject.activeInHierarchy && x.active))
|
2021-03-17 17:04:57 +00:00
|
|
|
|
{
|
2022-01-02 21:26:52 -08:00
|
|
|
|
IsEnabled = true;
|
2021-02-27 14:23:35 +00:00
|
|
|
|
}
|
2021-12-02 12:38:38 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2022-01-02 21:26:52 -08:00
|
|
|
|
ControllingPlayer = 0u;
|
|
|
|
|
IsEnabled = false;
|
2021-12-02 12:38:38 +00:00
|
|
|
|
}
|
2021-02-19 09:40:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-02 12:38:38 +00:00
|
|
|
|
public List<Shape> GetAttachedShapes()
|
2021-02-27 14:23:35 +00:00
|
|
|
|
{
|
2021-02-28 15:06:11 +00:00
|
|
|
|
if (AttachedObject == null)
|
|
|
|
|
{
|
|
|
|
|
return new List<Shape>();
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2021-12-02 12:38:38 +00:00
|
|
|
|
var visibilityTrackers = AttachedObject._visibilityTrackers;
|
2021-02-27 14:23:35 +00:00
|
|
|
|
if (visibilityTrackers == null || visibilityTrackers.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return new List<Shape>();
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2021-02-27 14:23:35 +00:00
|
|
|
|
if (visibilityTrackers.Any(x => x.GetType() == typeof(RendererVisibilityTracker)))
|
|
|
|
|
{
|
2021-02-28 15:06:11 +00:00
|
|
|
|
DebugLog.ToConsole($"Warning - {AttachedObject.name} has a RendererVisibilityTracker!", MessageType.Warning);
|
2021-02-27 14:23:35 +00:00
|
|
|
|
return new List<Shape>();
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2021-02-27 14:23:35 +00:00
|
|
|
|
var totalShapes = new List<Shape>();
|
2021-12-02 12:38:38 +00:00
|
|
|
|
foreach (ShapeVisibilityTracker tracker in visibilityTrackers)
|
2021-02-27 14:23:35 +00:00
|
|
|
|
{
|
2021-12-02 12:38:38 +00:00
|
|
|
|
if (tracker == null)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.ToConsole($"Warning - a ShapeVisibilityTracker in {LogName} is null!", MessageType.Warning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-07 21:24:39 -08:00
|
|
|
|
// if the tracker is not active, this won't have been set, so just do it ourselves
|
|
|
|
|
tracker._shapes ??= tracker.GetComponents<Shape>();
|
|
|
|
|
totalShapes.AddRange(tracker._shapes.Where(x => x != null));
|
2021-02-27 14:23:35 +00:00
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2021-02-27 14:23:35 +00:00
|
|
|
|
return totalShapes;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-11 19:21:45 -08:00
|
|
|
|
public void SetIsQuantum(bool isQuantum) => AttachedObject.SetIsQuantum(isQuantum);
|
|
|
|
|
|
2021-03-17 17:04:57 +00:00
|
|
|
|
private void OnEnable(Shape s)
|
2021-01-26 14:07:17 +00:00
|
|
|
|
{
|
2021-12-02 12:38:38 +00:00
|
|
|
|
if (IsEnabled)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-30 10:09:27 +00:00
|
|
|
|
IsEnabled = true;
|
2022-01-02 21:26:52 -08:00
|
|
|
|
if (!WorldObjectManager.AllObjectsReady && !QSBCore.IsHost)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2022-01-02 21:26:52 -08:00
|
|
|
|
if (ControllingPlayer != 0)
|
2021-01-26 14:07:17 +00:00
|
|
|
|
{
|
2021-01-26 23:41:53 +00:00
|
|
|
|
// controlled by another player, dont care that we activate it
|
2021-01-26 14:07:17 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2021-01-26 23:41:53 +00:00
|
|
|
|
// no one is controlling this object right now, request authority
|
2022-01-02 21:26:52 -08:00
|
|
|
|
((IQSBQuantumObject)this).SendMessage(new QuantumAuthorityMessage(QSBPlayerManager.LocalPlayerId));
|
2021-01-26 14:07:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-03 00:15:57 -08:00
|
|
|
|
private void OnDisable(Shape s) =>
|
|
|
|
|
// we wait a frame here in case the shapes get disabled as we switch from 1 visibility tracker to another
|
|
|
|
|
QSBCore.UnityEvents.FireOnNextUpdate(() =>
|
2021-02-27 14:23:35 +00:00
|
|
|
|
{
|
2022-01-03 00:15:57 -08:00
|
|
|
|
if (!IsEnabled)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2022-01-03 00:15:57 -08:00
|
|
|
|
if (GetAttachedShapes().Any(x => x.isActiveAndEnabled))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2022-01-03 00:15:57 -08:00
|
|
|
|
IsEnabled = false;
|
|
|
|
|
if (!WorldObjectManager.AllObjectsReady && !QSBCore.IsHost)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2022-01-03 00:15:57 -08:00
|
|
|
|
if (ControllingPlayer != QSBPlayerManager.LocalPlayerId)
|
|
|
|
|
{
|
|
|
|
|
// not being controlled by us, don't care if we leave area
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-18 22:38:32 +01:00
|
|
|
|
|
2022-01-03 00:15:57 -08:00
|
|
|
|
// send event to other players that we're releasing authority
|
|
|
|
|
((IQSBQuantumObject)this).SendMessage(new QuantumAuthorityMessage(0u));
|
|
|
|
|
});
|
2022-01-06 16:10:44 +00:00
|
|
|
|
|
|
|
|
|
public override void DisplayLines()
|
|
|
|
|
{
|
2022-01-07 20:46:58 +00:00
|
|
|
|
if (AttachedObject == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var localPlayer = QSBPlayerManager.LocalPlayer;
|
|
|
|
|
|
|
|
|
|
if (localPlayer == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var body = localPlayer.Body;
|
|
|
|
|
|
|
|
|
|
if (body == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-06 16:10:44 +00:00
|
|
|
|
if (ControllingPlayer == 0)
|
|
|
|
|
{
|
|
|
|
|
if (IsEnabled)
|
|
|
|
|
{
|
|
|
|
|
Popcron.Gizmos.Line(AttachedObject.transform.position,
|
2022-01-07 20:46:58 +00:00
|
|
|
|
body.transform.position,
|
2022-01-06 16:10:44 +00:00
|
|
|
|
Color.magenta * 0.25f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-07 20:46:58 +00:00
|
|
|
|
var player = QSBPlayerManager.GetPlayer(ControllingPlayer);
|
|
|
|
|
|
|
|
|
|
if (player == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var playerBody = player.Body;
|
2022-01-11 19:21:45 -08:00
|
|
|
|
|
2022-01-07 20:46:58 +00:00
|
|
|
|
if (playerBody == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-06 16:10:44 +00:00
|
|
|
|
Popcron.Gizmos.Line(AttachedObject.transform.position,
|
2022-01-07 20:46:58 +00:00
|
|
|
|
playerBody.transform.position,
|
2022-01-06 16:10:44 +00:00
|
|
|
|
Color.magenta);
|
|
|
|
|
}
|
2021-01-26 14:07:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|