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 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
{
2021-08-12 14:20:59 +01:00
public bool IsReady { get ; private set ; }
2021-12-13 19:08:01 -08:00
public readonly List < QSBSector > SectorList = new ( ) ;
2021-02-19 12:54:48 +00:00
2021-12-15 03:17:45 -08:00
private OWRigidbody _body ;
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
2021-08-12 14:20:59 +01:00
IsReady = false ;
2021-03-22 16:03:00 +00:00
}
2021-12-15 03:17:45 -08:00
public void Init ( SectorDetector detector , OWRigidbody body , 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
2021-07-13 15:24:57 +01:00
if ( detector = = null )
{
DebugLog . ToConsole ( $"Error - Trying to init SectorSync with null SectorDetector." , MessageType . Error ) ;
return ;
}
2021-12-15 03:17:45 -08:00
_body = body ;
2021-03-09 19:45:00 +00:00
_sectorDetector = detector ;
_sectorDetector . OnEnterSector + = AddSector ;
_sectorDetector . OnExitSector + = RemoveSector ;
2021-04-21 11:02:17 +01:00
2021-12-13 19:08:01 -08:00
SectorList . Clear ( ) ;
_sectorDetector . _sectorList . ForEach ( AddSector ) ;
2021-07-13 15:24:57 +01:00
2021-08-21 19:53:37 +01:00
_targetType = type ;
2021-08-12 14:20:59 +01:00
IsReady = true ;
2020-12-02 21:23:01 +00:00
}
2020-02-15 20:48:02 +01:00
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-12-13 19:08:01 -08:00
return ;
2021-03-09 19:45:00 +00:00
}
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-12-13 19:08:01 -08:00
public QSBSector GetClosestSector ( )
2021-03-09 19:45:00 +00:00
{
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 ;
}
2021-08-12 14:20:59 +01:00
if ( ! IsReady )
2021-07-10 20:34:43 +01:00
{
2021-12-13 19:08:01 -08:00
DebugLog . ToConsole ( $"Warning - Tried to use GetClosestSector() before this SectorSync is ready. Stacktrace:\r\n{Environment.StackTrace}" , MessageType . Warning ) ;
2021-07-10 20:34:43 +01:00
return null ;
}
2021-12-13 19:08:01 -08:00
if ( _sectorDetector = = null )
2021-07-10 20:34:43 +01:00
{
2021-08-12 14:20:59 +01:00
IsReady = false ;
2021-07-10 20:34:43 +01:00
return null ;
}
2021-12-13 19:08:01 -08:00
var useSectorList = SectorList . Any ( x = > x . ShouldSyncTo ( _targetType ) ) ;
var listToCheck = useSectorList
? SectorList
: QSBWorldSync . GetWorldObjects < QSBSector > ( ) . Where ( x = > ! x . IsFakeSector & & x . Type ! = Sector . Name . Unnamed ) ;
2021-06-19 11:26:05 +01:00
2021-12-13 19:08:01 -08:00
var goodSectors = listToCheck
. Where ( x = > x . ShouldSyncTo ( _targetType ) )
. ToList ( ) ;
if ( goodSectors . Count = = 0 )
2021-03-12 21:46:02 +00:00
{
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-12-13 19:08:01 -08:00
var closest = goodSectors
2021-12-15 03:17:45 -08:00
. OrderBy ( CalculateSectorScore ) . First ( ) ;
2021-03-11 20:02:23 +00:00
2021-12-13 19:08:01 -08:00
if ( useSectorList )
2021-03-11 20:02:23 +00:00
{
2021-12-15 03:17:45 -08:00
var pos = _body . GetPosition ( ) ;
2021-12-13 19:08:01 -08:00
// if any fake sectors are *roughly* in the same place as other sectors - we want fake sectors to override other sectors
var fakeSector = QSBSectorManager . Instance . FakeSectors . FirstOrDefault ( x = >
OWMath . ApproxEquals ( Vector3 . Distance ( x . Position , pos ) , Vector3 . Distance ( closest . Position , pos ) , 0.01f ) & &
goodSectors . Any ( y = > x . FakeSector . AttachedSector = = y . AttachedObject )
) ;
return fakeSector ? ? closest ;
2021-03-11 20:02:23 +00:00
}
2021-03-13 10:19:02 +00:00
2021-12-13 19:08:01 -08:00
return closest ;
2021-03-09 21:56:20 +00:00
}
2021-12-15 03:17:45 -08:00
private float CalculateSectorScore ( QSBSector sector )
2021-04-21 11:02:17 +01:00
{
2021-12-15 03:17:45 -08:00
var distance = Vector3 . Distance ( sector . Position , _body . GetPosition ( ) ) ; // want to be small
2021-04-21 11:02:17 +01:00
var radius = GetRadius ( sector ) ; // want to be small
2021-12-15 03:17:45 -08:00
var velocity = GetRelativeVelocity ( sector ) ; // want to be small
2021-04-21 11:02:17 +01:00
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
}
2021-12-13 19:08:01 -08:00
private 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-12-15 03:17:45 -08:00
private float GetRelativeVelocity ( QSBSector sector )
2021-04-21 11:02:17 +01:00
{
var sectorRigidBody = sector . AttachedObject . GetOWRigidbody ( ) ;
2021-12-15 03:17:45 -08:00
if ( sectorRigidBody ! = null & & _body ! = null )
2021-04-21 11:02:17 +01:00
{
2021-12-15 03:17:45 -08:00
var relativeVelocity = sectorRigidBody . GetRelativeVelocity ( _body ) ;
2021-04-21 11:02:17 +01:00
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
}
2021-12-13 19:08:01 -08:00
}