217 lines
6.3 KiB
C#
Raw Normal View History

2021-03-09 19:45:00 +00:00
using OWML.Common;
2021-04-21 11:02:17 +01:00
using OWML.Utils;
using QSB.SectorSync.WorldObjects;
2021-02-19 12:42:37 +00:00
using QSB.Utility;
2021-03-09 19:45:00 +00:00
using QSB.WorldSync;
2021-08-10 14:54:23 +01:00
using System;
2021-03-09 19:45:00 +00:00
using System.Collections.Generic;
2020-08-22 17:08:56 +01:00
using System.Linq;
2020-08-21 14:04:13 +01:00
using UnityEngine;
2020-02-13 20:23:26 +01:00
2020-11-03 22:29:23 +00:00
namespace QSB.SectorSync
2020-02-15 20:48:02 +01:00
{
2021-03-09 19:45:00 +00:00
public class SectorSync : MonoBehaviour
2020-12-02 21:23:01 +00:00
{
public bool IsReady { get; private set; }
2021-11-20 19:49:50 +00:00
public List<QSBSector> SectorList = new();
2021-02-19 12:54:48 +00:00
2021-04-21 11:02:17 +01:00
private OWRigidbody _attachedOWRigidbody;
2021-03-09 19:45:00 +00:00
private SectorDetector _sectorDetector;
2021-05-15 14:10:51 +01:00
private TargetType _targetType;
2021-03-09 19:45:00 +00:00
2021-03-22 16:03:00 +00:00
private void OnDestroy()
{
if (_sectorDetector != null)
{
_sectorDetector.OnEnterSector -= AddSector;
_sectorDetector.OnExitSector -= RemoveSector;
}
2021-08-22 17:17:46 +01:00
IsReady = false;
2021-03-22 16:03:00 +00:00
}
public void Init(SectorDetector detector, TargetType type)
2020-12-02 21:23:01 +00:00
{
2021-03-09 19:45:00 +00:00
if (_sectorDetector != null)
2020-12-02 21:23:01 +00:00
{
2021-03-09 19:45:00 +00:00
_sectorDetector.OnEnterSector -= AddSector;
_sectorDetector.OnExitSector -= RemoveSector;
2020-12-02 21:23:01 +00:00
}
2021-06-18 22:38:32 +01:00
if (detector == null)
{
DebugLog.ToConsole($"Error - Trying to init SectorSync with null SectorDetector.", MessageType.Error);
return;
}
2021-03-09 19:45:00 +00:00
_sectorDetector = detector;
_sectorDetector.OnEnterSector += AddSector;
_sectorDetector.OnExitSector += RemoveSector;
2021-04-21 11:02:17 +01:00
_attachedOWRigidbody = _sectorDetector.GetValue<OWRigidbody>("_attachedRigidbody");
if (_attachedOWRigidbody == null)
{
DebugLog.ToConsole($"Warning - OWRigidbody for {_sectorDetector.name} is null!", MessageType.Warning);
}
2021-05-15 14:10:51 +01:00
PopulateSectorList();
_targetType = type;
IsReady = true;
2020-12-02 21:23:01 +00:00
}
2020-02-15 20:48:02 +01:00
private void PopulateSectorList()
{
var currentList = _sectorDetector.GetValue<List<Sector>>("_sectorList");
SectorList.Clear();
foreach (var sector in currentList)
{
if (sector == null)
{
continue;
}
AddSector(sector);
}
}
2021-03-09 19:45:00 +00:00
private void AddSector(Sector sector)
2020-12-02 21:23:01 +00:00
{
2021-11-01 15:49:00 +00:00
var worldObject = QSBWorldSync.GetWorldFromUnity<QSBSector>(sector);
2021-03-09 19:45:00 +00:00
if (worldObject == null)
2020-12-02 21:23:01 +00:00
{
2021-03-09 19:45:00 +00:00
DebugLog.ToConsole($"Error - Can't find QSBSector for sector {sector.name}!", MessageType.Error);
}
2021-06-18 22:38:32 +01:00
2021-03-09 19:45:00 +00:00
if (SectorList.Contains(worldObject))
{
2021-03-12 21:46:02 +00:00
DebugLog.ToConsole($"Warning - Trying to add {sector.name} for {gameObject.name}, but is already in list", MessageType.Warning);
2020-12-02 21:23:01 +00:00
return;
}
2021-06-18 22:38:32 +01:00
2021-03-09 19:45:00 +00:00
SectorList.Add(worldObject);
}
private void RemoveSector(Sector sector)
{
2021-11-01 15:49:00 +00:00
var worldObject = QSBWorldSync.GetWorldFromUnity<QSBSector>(sector);
2021-03-09 19:45:00 +00:00
if (worldObject == null)
2021-02-28 15:35:01 +00:00
{
2021-03-09 19:45:00 +00:00
DebugLog.ToConsole($"Error - Can't find QSBSector for sector {sector.name}!", MessageType.Error);
2021-02-28 15:35:01 +00:00
return;
}
2021-06-18 22:38:32 +01:00
2021-03-09 19:45:00 +00:00
if (!SectorList.Contains(worldObject))
2020-12-02 21:23:01 +00:00
{
2021-03-12 21:46:02 +00:00
DebugLog.ToConsole($"Warning - Trying to remove {sector.name} for {gameObject.name}, but is not in list!", MessageType.Warning);
2020-12-02 21:23:01 +00:00
return;
}
2021-06-18 22:38:32 +01:00
2021-03-09 19:45:00 +00:00
SectorList.Remove(worldObject);
2020-12-02 21:23:01 +00:00
}
2020-08-05 21:59:50 +02:00
2021-03-09 19:45:00 +00:00
public QSBSector GetClosestSector(Transform trans) // trans rights \o/
{
2021-07-17 09:53:29 +01:00
if (QSBSectorManager.Instance == null || !QSBSectorManager.Instance.IsReady)
2021-03-09 19:45:00 +00:00
{
return null;
}
if (!IsReady)
2021-07-10 20:34:43 +01:00
{
2021-09-02 11:24:13 +01:00
DebugLog.ToConsole($"Warning - Tried to use GetClosestSector() before this SectorSync is ready. Transform:{trans.name} Stacktrace:\r\n{Environment.StackTrace}", MessageType.Warning);
2021-07-10 20:34:43 +01:00
return null;
}
if (_sectorDetector == null || _attachedOWRigidbody == null || _targetType == TargetType.None)
{
IsReady = false;
2021-07-10 20:34:43 +01:00
DebugLog.ToConsole($"Error - SectorSync is no longer ready. Detector Null : {_sectorDetector == null}, OWRigidbody Null : {_attachedOWRigidbody == null}, None TargetType : {_targetType == TargetType.None}", MessageType.Error);
return null;
}
2021-10-24 10:47:25 +01:00
bool ShouldSyncTo(QSBSector sector, TargetType type)
{
if (sector == null)
{
DebugLog.ToConsole($"Warning - Tried to check if we should sync to null sector!", MessageType.Warning);
return false;
}
return sector.ShouldSyncTo(type);
}
var numSectorsCurrentlyIn = SectorList.Count(x => ShouldSyncTo(x, _targetType));
2021-06-19 11:26:05 +01:00
var listToCheck = numSectorsCurrentlyIn == 0
2021-06-13 19:44:35 +01:00
? QSBWorldSync.GetWorldObjects<QSBSector>().Where(x => !x.IsFakeSector && x.Type != Sector.Name.Unnamed)
2021-03-09 19:45:00 +00:00
: SectorList;
2021-03-09 21:56:20 +00:00
var activeNotNullNotBlacklisted = listToCheck.Where(sector => sector.AttachedObject != null
2021-05-15 14:10:51 +01:00
&& sector.ShouldSyncTo(_targetType));
2021-03-12 21:46:02 +00:00
if (activeNotNullNotBlacklisted.Count() == 0)
{
2021-03-31 15:43:55 +01:00
return default;
2021-03-12 21:46:02 +00:00
}
2021-06-18 22:38:32 +01:00
2021-03-09 21:56:20 +00:00
var ordered = activeNotNullNotBlacklisted
2021-04-21 11:02:17 +01:00
.OrderBy(sector => CalculateSectorScore(sector, trans, _attachedOWRigidbody));
2021-03-11 20:02:23 +00:00
// TODO : clean up this shit???
2021-03-11 20:02:23 +00:00
if (
numSectorsCurrentlyIn != 0 &&
2021-03-12 20:49:48 +00:00
// if any fake sectors are *roughly* in the same place as other sectors - we want fake sectors to override other sectors
2021-03-11 20:02:23 +00:00
QSBSectorManager.Instance.FakeSectors.Any(
2021-03-13 10:19:02 +00:00
x => OWMath.ApproxEquals(Vector3.Distance(x.Position, trans.position), Vector3.Distance(ordered.FirstOrDefault().Position, trans.position), 0.01f)
2021-03-11 20:02:23 +00:00
&& activeNotNullNotBlacklisted.Any(
y => y.AttachedObject == (x.AttachedObject as FakeSector).AttachedSector)))
{
return QSBSectorManager.Instance.FakeSectors.First(x => OWMath.ApproxEquals(Vector3.Distance(x.Position, trans.position), Vector3.Distance(ordered.FirstOrDefault().Position, trans.position), 0.01f));
}
2021-03-13 10:19:02 +00:00
2021-03-09 21:56:20 +00:00
return ordered.FirstOrDefault();
}
2021-04-21 11:02:17 +01:00
public static float CalculateSectorScore(QSBSector sector, Transform trans, OWRigidbody rigidbody)
{
var distance = Vector3.Distance(sector.Position, trans.position); // want to be small
var radius = GetRadius(sector); // want to be small
var velocity = GetRelativeVelocity(sector, rigidbody); // want to be small
2021-05-15 14:10:51 +01:00
return Mathf.Pow(distance, 2) + Mathf.Pow(radius, 2) + Mathf.Pow(velocity, 2);
2021-04-21 11:02:17 +01:00
}
public static float GetRadius(QSBSector sector)
2021-03-09 21:56:20 +00:00
{
if (sector == null)
{
return 0f;
}
// TODO : make this work for other stuff, not just shaped triggervolumes
var trigger = sector.AttachedObject.GetTriggerVolume();
if (trigger != null)
{
if (trigger.GetShape() != null)
{
return trigger.GetShape().CalcWorldBounds().radius;
}
}
2021-06-18 22:38:32 +01:00
2021-03-09 21:56:20 +00:00
return 0f;
2021-03-09 19:45:00 +00:00
}
2021-06-19 11:26:05 +01:00
2021-04-21 11:02:17 +01:00
public static float GetRelativeVelocity(QSBSector sector, OWRigidbody rigidbody)
{
var sectorRigidBody = sector.AttachedObject.GetOWRigidbody();
if (sectorRigidBody != null && rigidbody != null)
{
var relativeVelocity = sectorRigidBody.GetRelativeVelocity(rigidbody);
var relativeVelocityMagnitude = relativeVelocity.sqrMagnitude; // Remember this is squared for efficiency!
return relativeVelocityMagnitude;
}
2021-06-18 22:38:32 +01:00
2021-04-21 11:02:17 +01:00
return 0;
}
2020-12-14 21:20:53 +00:00
}
2020-12-03 08:28:05 +00:00
}