quantum-space-buddies/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs

182 lines
4.8 KiB
C#
Raw Normal View History

2021-02-28 15:06:11 +00:00
using OWML.Common;
using OWML.Utils;
using QSB.Events;
2021-01-26 14:07:17 +00:00
using QSB.Player;
2021-02-19 09:40:46 +00:00
using QSB.Utility;
2021-01-26 14:07:17 +00:00
using QSB.WorldSync;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
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
where T : QuantumObject
2021-01-26 14:07:17 +00:00
{
2021-01-26 17:08:02 +00:00
public uint ControllingPlayer { get; set; }
2021-01-30 10:09:27 +00:00
public bool IsEnabled { get; set; }
2021-01-26 14:07:17 +00:00
2021-02-19 09:40:46 +00:00
public override void OnRemoval()
{
foreach (var shape in GetAttachedShapes())
{
2021-03-18 11:09:19 +00:00
shape.OnShapeActivated -= (Shape s)
2021-03-17 17:04:57 +00:00
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnEnable(s));
2021-03-18 11:09:19 +00:00
shape.OnShapeDeactivated -= (Shape s)
2021-03-17 17:04:57 +00:00
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnDisable(s));
}
2021-02-19 09:40:46 +00:00
}
public override void Init(T attachedObject, int id)
{
var debugBundle = QSBCore.DebugAssetBundle;
var sphere = debugBundle.LoadAsset<GameObject>("Assets/Sphere.prefab");
var cube = debugBundle.LoadAsset<GameObject>("Assets/Cube.prefab");
var capsule = debugBundle.LoadAsset<GameObject>("Assets/Capsule.prefab");
if (cube == null)
{
DebugLog.DebugWrite($"CUBE IS NULL");
}
if (sphere == null)
{
DebugLog.DebugWrite($"SPHERE IS NULL");
}
if (capsule == null)
{
DebugLog.DebugWrite($"CAPSULE IS NULL");
}
foreach (var shape in GetAttachedShapes())
{
if (shape == null)
{
break;
}
2021-03-17 17:04:57 +00:00
// Firing next update to give time for shapes to actually be disabled
2021-03-18 11:09:19 +00:00
shape.OnShapeActivated += (Shape s)
2021-03-17 17:04:57 +00:00
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnEnable(s));
2021-03-18 11:09:19 +00:00
shape.OnShapeDeactivated += (Shape s)
2021-03-17 17:04:57 +00:00
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnDisable(s));
if (shape is BoxShape boxShape)
{
var newCube = UnityEngine.Object.Instantiate(cube);
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)
{
var newSphere = UnityEngine.Object.Instantiate(sphere);
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-03-17 17:04:57 +00:00
}
2021-06-18 21:38:32 +00:00
2021-03-17 17:04:57 +00:00
if (GetAttachedShapes().Any(x => !x.enabled || !x.active))
{
ControllingPlayer = 0u;
IsEnabled = false;
}
else
{
IsEnabled = true;
}
2021-02-19 09:40:46 +00:00
}
private List<Shape> GetAttachedShapes()
{
2021-02-28 15:06:11 +00:00
if (AttachedObject == null)
{
return new List<Shape>();
}
2021-06-18 21:38:32 +00:00
var visibilityTrackers = AttachedObject.GetValue<VisibilityTracker[]>("_visibilityTrackers");
if (visibilityTrackers == null || visibilityTrackers.Length == 0)
{
return new List<Shape>();
}
2021-06-18 21:38:32 +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);
return new List<Shape>();
}
2021-06-18 21:38:32 +00:00
var totalShapes = new List<Shape>();
foreach (var tracker in visibilityTrackers)
{
var shapes = tracker.GetValue<Shape[]>("_shapes");
totalShapes.AddRange(shapes);
}
2021-06-18 21:38:32 +00:00
return totalShapes;
}
2021-03-17 17:04:57 +00:00
private void OnEnable(Shape s)
2021-01-26 14:07:17 +00:00
{
2021-01-30 10:09:27 +00:00
IsEnabled = true;
2021-08-08 18:53:55 +00:00
if (!QSBCore.WorldObjectsReady && !QSBCore.IsHost)
2021-02-14 09:43:36 +00:00
{
return;
}
2021-06-18 21:38:32 +00:00
2021-01-26 23:41:53 +00: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 21:38:32 +00:00
2021-03-17 17:04:57 +00:00
var id = QSBWorldSync.GetIdFromTypeSubset<IQSBQuantumObject>(this);
2021-01-26 23:41:53 +00:00
// no one is controlling this object right now, request authority
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, id, QSBPlayerManager.LocalPlayerId);
2021-01-26 14:07:17 +00:00
}
2021-03-17 17:04:57 +00:00
private void OnDisable(Shape s)
2021-01-26 14:07:17 +00:00
{
if (!IsEnabled)
{
return;
}
2021-06-18 21:38:32 +00:00
2021-04-28 15:28:02 +00:00
if (GetAttachedShapes().Any(x => x.isActiveAndEnabled))
2021-03-17 17:04:57 +00:00
{
return;
}
2021-06-18 21:38:32 +00:00
2021-01-30 10:09:27 +00:00
IsEnabled = false;
2021-08-08 18:53:55 +00:00
if (!QSBCore.WorldObjectsReady && !QSBCore.IsHost)
2021-02-14 09:43:36 +00:00
{
return;
}
2021-06-18 21:38:32 +00:00
2021-01-26 14:07:17 +00:00
if (ControllingPlayer != QSBPlayerManager.LocalPlayerId)
{
// not being controlled by us, don't care if we leave area
return;
}
2021-06-18 21:38:32 +00:00
2021-03-17 17:04:57 +00:00
var id = QSBWorldSync.GetIdFromTypeSubset<IQSBQuantumObject>(this);
2021-01-26 14:07:17 +00:00
// send event to other players that we're releasing authority
2021-02-13 10:11:56 +00:00
QSBEventManager.FireEvent(EventNames.QSBQuantumAuthority, id, 0u);
2021-01-26 14:07:17 +00:00
}
}
}