2021-03-09 19:45:00 +00:00
using OWML.Common ;
2020-12-31 12:10:55 +00:00
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 13:54:23 +00:00
using System ;
2021-03-09 19:45:00 +00:00
using System.Collections.Generic ;
2020-08-22 16:08:56 +00:00
using System.Linq ;
2020-08-21 13:04:13 +00:00
using UnityEngine ;
2020-02-13 19:23:26 +00:00
2020-11-03 22:29:23 +00:00
namespace QSB.SectorSync
2020-02-15 19:48:02 +00:00
{
2021-03-09 19:45:00 +00:00
public class SectorSync : MonoBehaviour
2020-12-02 21:23:01 +00:00
{
2021-08-12 13:20:59 +00:00
public bool IsReady { get ; private set ; }
2021-12-18 20:08:26 +00:00
public readonly List < QSBSector > SectorList = new ( ) ;
2021-02-19 12:54:48 +00:00
2021-03-09 19:45:00 +00:00
private SectorDetector _sectorDetector ;
2021-05-15 13:10:51 +00: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 16:17:46 +00:00
2021-08-12 13:20:59 +00:00
IsReady = false ;
2021-03-22 16:03:00 +00:00
}
2021-08-21 18:53:37 +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 21:38:32 +00:00
2021-07-13 14:24:57 +00: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 10:02:17 +00:00
2021-12-18 20:08:26 +00:00
SectorList . Clear ( ) ;
_sectorDetector . _sectorList . ForEach ( AddSector ) ;
2021-07-13 14:24:57 +00:00
2021-08-21 18:53:37 +00:00
_targetType = type ;
2021-08-12 13:20:59 +00:00
IsReady = true ;
2020-12-02 21:23:01 +00:00
}
2020-02-15 19:48:02 +00:00
2021-03-09 19:45:00 +00:00
private void AddSector ( Sector sector )
2020-12-02 21:23:01 +00:00
{
2021-12-26 06:37:20 +00:00
var worldObject = sector . GetWorldObject < QSBSector > ( ) ;
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-12-18 20:08:26 +00:00
return ;
2021-03-09 19:45:00 +00:00
}
2021-06-18 21:38:32 +00: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 21:38:32 +00:00
2021-03-09 19:45:00 +00:00
SectorList . Add ( worldObject ) ;
}
private void RemoveSector ( Sector sector )
{
2021-12-26 06:37:20 +00:00
var worldObject = sector . GetWorldObject < QSBSector > ( ) ;
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 21:38:32 +00: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 21:38:32 +00:00
2021-03-09 19:45:00 +00:00
SectorList . Remove ( worldObject ) ;
2020-12-02 21:23:01 +00:00
}
2020-08-05 19:59:50 +00:00
2021-12-18 20:08:26 +00:00
public QSBSector GetClosestSector ( )
2021-03-09 19:45:00 +00:00
{
2021-07-17 08:53:29 +00:00
if ( QSBSectorManager . Instance = = null | | ! QSBSectorManager . Instance . IsReady )
2021-03-09 19:45:00 +00:00
{
return null ;
}
2021-08-12 13:20:59 +00:00
if ( ! IsReady )
2021-07-10 19:34:43 +00:00
{
2021-12-18 20:08:26 +00:00
DebugLog . ToConsole ( $"Warning - Tried to use GetClosestSector() before this SectorSync is ready. Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Warning ) ;
2021-07-10 19:34:43 +00:00
return null ;
}
2021-12-18 20:08:26 +00:00
if ( _sectorDetector = = null )
2021-07-10 19:34:43 +00:00
{
2021-08-12 13:20:59 +00:00
IsReady = false ;
2021-07-10 19:34:43 +00:00
return null ;
}
2021-12-18 20:08:26 +00:00
var inASector = SectorList . Any ( x = > x . ShouldSyncTo ( _targetType ) ) ;
2021-06-19 10:26:05 +00:00
2021-12-18 20:08:26 +00:00
var listToCheck = inASector
? SectorList
: QSBWorldSync . GetWorldObjects < QSBSector > ( ) . Where ( x = > ! x . IsFakeSector & & x . Type ! = Sector . Name . Unnamed ) ;
2021-03-09 21:56:20 +00:00
2021-12-18 20:08:26 +00:00
var goodSectors = listToCheck . Where ( sector = > sector . ShouldSyncTo ( _targetType ) ) . ToList ( ) ;
2021-12-18 10:33:18 +00:00
2021-12-18 20:08:26 +00:00
if ( goodSectors . Count = = 0 )
2021-03-12 21:46:02 +00:00
{
2021-03-31 14:43:55 +00:00
return default ;
2021-03-12 21:46:02 +00:00
}
2021-06-18 21:38:32 +00:00
2021-12-18 20:08:26 +00:00
var closest = goodSectors
. OrderBy ( sector = > CalculateSectorScore ( sector , _sectorDetector . _attachedRigidbody ) ) . First ( ) ;
2021-12-18 10:33:18 +00:00
2021-12-18 20:18:41 +00:00
if ( inASector )
2021-12-18 20:08:26 +00:00
{
var pos = _sectorDetector . _attachedRigidbody . GetPosition ( ) ;
2021-12-18 10:33:18 +00:00
2021-12-18 20:18:41 +00:00
bool IsApproxCloseToClosestSector ( QSBSector sectorToCheck )
2021-12-18 20:21:43 +00:00
= > OWMath . ApproxEquals ( Vector3 . Distance ( sectorToCheck . Position , pos ) ,
Vector3 . Distance ( closest . Position , pos ) ,
0.01f ) ;
2021-12-18 20:18:41 +00:00
bool IsFakeSectorActive ( QSBSector fakeSectorToCheck )
= > goodSectors . Any ( x = > fakeSectorToCheck . FakeSector . AttachedSector = = x . AttachedObject ) ;
2021-12-18 10:33:18 +00:00
2021-12-18 20:08:26 +00:00
var fakeToSyncTo = QSBSectorManager . Instance . FakeSectors . FirstOrDefault ( x = > IsApproxCloseToClosestSector ( x ) & & IsFakeSectorActive ( x ) ) ;
return fakeToSyncTo ? ? closest ;
2021-03-11 20:02:23 +00:00
}
2021-03-13 10:19:02 +00:00
2021-12-18 20:08:26 +00:00
return closest ;
2021-03-09 21:56:20 +00:00
}
2021-12-18 20:08:26 +00:00
private static float CalculateSectorScore ( QSBSector sector , OWRigidbody rigidbody )
2021-04-21 10:02:17 +00:00
{
2021-12-18 20:08:26 +00:00
var distance = ( sector . Position - rigidbody . GetPosition ( ) ) . sqrMagnitude ;
2021-12-18 10:33:18 +00:00
var radius = GetRadius ( sector ) ;
var velocity = GetRelativeVelocity ( sector , rigidbody ) ;
2021-04-21 10:02:17 +00:00
2021-12-18 10:33:18 +00:00
return distance + Mathf . Pow ( radius , 2 ) + velocity ;
2021-04-21 10:02:17 +00:00
}
2021-12-18 20:08:26 +00:00
private static float GetRadius ( QSBSector sector )
2021-03-09 21:56:20 +00:00
{
// 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 21:38:32 +00:00
2021-03-09 21:56:20 +00:00
return 0f ;
2021-03-09 19:45:00 +00:00
}
2021-06-19 10:26:05 +00:00
2021-12-18 20:08:26 +00:00
private static float GetRelativeVelocity ( QSBSector sector , OWRigidbody rigidbody )
2021-04-21 10:02:17 +00:00
{
var sectorRigidBody = sector . AttachedObject . GetOWRigidbody ( ) ;
if ( sectorRigidBody ! = null & & rigidbody ! = null )
{
var relativeVelocity = sectorRigidBody . GetRelativeVelocity ( rigidbody ) ;
2021-12-18 10:33:18 +00:00
return relativeVelocity . sqrMagnitude ;
2021-04-21 10:02:17 +00:00
}
2021-06-18 21:38:32 +00:00
2021-04-21 10:02:17 +00:00
return 0 ;
}
2020-12-14 21:20:53 +00:00
}
2020-12-03 08:28:05 +00:00
}