mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
100 lines
No EOL
3.2 KiB
C#
100 lines
No EOL
3.2 KiB
C#
using ABI_RC.Core.InteractionSystem;
|
|
using ABI_RC.Core.Player;
|
|
using ABI_RC.Core.Savior;
|
|
using ABI.CCK.Components;
|
|
using UnityEngine;
|
|
|
|
namespace NAK.RelativeSync.Components;
|
|
|
|
public class RelativeSyncMarker : MonoBehaviour
|
|
{
|
|
public int pathHash { get; private set; }
|
|
|
|
public bool IsComponentActive
|
|
=> _component.isActiveAndEnabled;
|
|
|
|
public bool ApplyRelativePosition = true;
|
|
public bool ApplyRelativeRotation = true;
|
|
public bool OnlyApplyRelativeHeading;
|
|
|
|
private MonoBehaviour _component;
|
|
|
|
private void Start()
|
|
{
|
|
string path = GetGameObjectPath(transform);
|
|
int hash = path.GetHashCode();
|
|
|
|
// check if it already exists (this **should** only matter in worlds)
|
|
if (RelativeSyncManager.RelativeSyncTransforms.ContainsKey(hash))
|
|
{
|
|
RelativeSyncMod.Logger.Warning($"Duplicate RelativeSyncMarker found at path {path}");
|
|
if (!FindAvailableHash(ref hash)) // super lazy fix idfc
|
|
{
|
|
RelativeSyncMod.Logger.Error($"Failed to find available hash for RelativeSyncMarker after 16 tries! {path}");
|
|
return;
|
|
}
|
|
}
|
|
|
|
pathHash = hash;
|
|
RelativeSyncManager.RelativeSyncTransforms.Add(hash, this);
|
|
|
|
ConfigureForPotentialMovementParent();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
RelativeSyncManager.RelativeSyncTransforms.Remove(pathHash);
|
|
}
|
|
|
|
private void ConfigureForPotentialMovementParent()
|
|
{
|
|
if (!gameObject.TryGetComponent(out CVRMovementParent movementParent))
|
|
{
|
|
_component = GetComponent<CVRSeat>(); // users cant animate enabled state so i dont think matters
|
|
return;
|
|
}
|
|
_component = movementParent;
|
|
|
|
// TODO: a refactor may be needed to handle the orientation mode being animated
|
|
|
|
// respect orientation mode & gravity zone
|
|
ApplyRelativeRotation = movementParent.orientationMode == CVRMovementParent.OrientationMode.RotateWithParent;
|
|
OnlyApplyRelativeHeading = movementParent.GetComponent<GravityZone>() == null;
|
|
}
|
|
|
|
private static string GetGameObjectPath(Transform transform)
|
|
{
|
|
// props already have a unique instance identifier at root
|
|
// worlds uhhhh, dont duplicate the same thing over and over thx
|
|
// avatars on remote/local client have diff path, we need to account for it -_-
|
|
|
|
string path = transform.name;
|
|
while (transform.parent != null)
|
|
{
|
|
transform = transform.parent;
|
|
|
|
// only true at root of local player object
|
|
if (transform.CompareTag("Player"))
|
|
{
|
|
path = MetaPort.Instance.ownerId + "/" + path;
|
|
break;
|
|
} // remote player object root is already player guid
|
|
|
|
path = transform.name + "/" + path;
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
private bool FindAvailableHash(ref int hash)
|
|
{
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
hash += 1;
|
|
if (!RelativeSyncManager.RelativeSyncTransforms.ContainsKey(hash)) return true;
|
|
}
|
|
|
|
// failed to find a hash in 16 tries, dont care
|
|
return false;
|
|
}
|
|
} |