diff --git a/NewHorizons/Builder/Body/SingularityBuilder.cs b/NewHorizons/Builder/Body/SingularityBuilder.cs index 9db42133..72648881 100644 --- a/NewHorizons/Builder/Body/SingularityBuilder.cs +++ b/NewHorizons/Builder/Body/SingularityBuilder.cs @@ -11,6 +11,7 @@ using NewHorizons.Builder.Props; using NewHorizons.Utility.OWML; using NewHorizons.Utility.OuterWilds; using NewHorizons.External.SerializableData; +using NewHorizons.Builder.Volumes; namespace NewHorizons.Builder.Body { @@ -134,6 +135,17 @@ namespace NewHorizons.Builder.Body } NHLogger.LogVerbose($"Pairing singularities [{blackHoleID}], [{whiteHoleID}]"); blackHoleVolume._whiteHole = whiteHoleVolume; + + // If warping to a vanilla planet, we add a streaming volume to pre-load it + var streamingGroup = whiteHoleVolume.GetAttachedOWRigidbody().GetComponentInChildren(); + if (streamingGroup != null) + { + var streamingVolume = VolumeBuilder.Make(blackHoleVolume.GetAttachedOWRigidbody().gameObject, blackHoleVolume.GetComponentInParent(), + new External.Modules.Volumes.VolumeInfos.VolumeInfo() { radius = 100f }); + streamingVolume.streamingGroup = streamingGroup; + streamingVolume.transform.parent = blackHoleVolume.transform; + streamingVolume.transform.localPosition = Vector3.zero; + } } } diff --git a/NewHorizons/Builder/Volumes/StreamingWarpVolumeBuilder.cs b/NewHorizons/Builder/Volumes/StreamingWarpVolumeBuilder.cs new file mode 100644 index 00000000..365b21dd --- /dev/null +++ b/NewHorizons/Builder/Volumes/StreamingWarpVolumeBuilder.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.Builder.Volumes +{ + internal class StreamingWarpVolumeBuilder + { + } +} diff --git a/NewHorizons/Components/Volumes/BaseVolume.cs b/NewHorizons/Components/Volumes/BaseVolume.cs index f313310c..970c3ad9 100644 --- a/NewHorizons/Components/Volumes/BaseVolume.cs +++ b/NewHorizons/Components/Volumes/BaseVolume.cs @@ -3,22 +3,27 @@ using UnityEngine; namespace NewHorizons.Components.Volumes { [RequireComponent(typeof(OWTriggerVolume))] - public abstract class BaseVolume : MonoBehaviour + public abstract class BaseVolume : SectoredMonoBehaviour { private OWTriggerVolume _triggerVolume; - public virtual void Awake() + public override void Awake() { + base.Awake(); _triggerVolume = this.GetRequiredComponent(); _triggerVolume.OnEntry += OnTriggerVolumeEntry; _triggerVolume.OnExit += OnTriggerVolumeExit; } - public virtual void OnDestroy() + public override void OnDestroy() { - if (_triggerVolume == null) return; - _triggerVolume.OnEntry -= OnTriggerVolumeEntry; - _triggerVolume.OnExit -= OnTriggerVolumeExit; + base.OnDestroy(); + + if (_triggerVolume != null) + { + _triggerVolume.OnEntry -= OnTriggerVolumeEntry; + _triggerVolume.OnExit -= OnTriggerVolumeExit; + } } public abstract void OnTriggerVolumeEntry(GameObject hitObj); diff --git a/NewHorizons/Components/Volumes/StreamingWarpVolume.cs b/NewHorizons/Components/Volumes/StreamingWarpVolume.cs new file mode 100644 index 00000000..25616c48 --- /dev/null +++ b/NewHorizons/Components/Volumes/StreamingWarpVolume.cs @@ -0,0 +1,110 @@ +using UnityEngine; + +namespace NewHorizons.Components.Volumes +{ + /// + /// Currently only relevant for Vanilla planets, which actually have streaming groups + /// + internal class StreamingWarpVolume : BaseVolume + { + public StreamingGroup streamingGroup; + private bool _probeInVolume; + private bool _playerInVolume; + private bool _preloadingRequiredAssets; + private bool _preloadingGeneralAssets; + + private SurveyorProbe _probe; + + public void Start() + { + _probe = Locator.GetProbe(); + base.enabled = false; + } + + public void FixedUpdate() + { + bool probeActive = _probe.IsLaunched() && !_probe.IsAnchored(); + + bool shouldBeLoadingRequiredAssets = _playerInVolume || (_probeInVolume && probeActive); + bool shouldBeLoadingGeneralAssets = _playerInVolume; + + UpdatePreloadingState(shouldBeLoadingRequiredAssets, shouldBeLoadingGeneralAssets); + } + + private void UpdatePreloadingState(bool shouldBeLoadingRequiredAssets, bool shouldBeLoadingGeneralAssets) + { + if (!this._preloadingRequiredAssets && shouldBeLoadingRequiredAssets) + { + this.streamingGroup.RequestRequiredAssets(0); + this._preloadingRequiredAssets = true; + } + else if (this._preloadingRequiredAssets && !shouldBeLoadingRequiredAssets) + { + this.streamingGroup.ReleaseRequiredAssets(); + this._preloadingRequiredAssets = false; + } + if (!this._preloadingGeneralAssets && shouldBeLoadingGeneralAssets) + { + this.streamingGroup.RequestGeneralAssets(0); + this._preloadingGeneralAssets = true; + return; + } + if (this._preloadingGeneralAssets && !shouldBeLoadingGeneralAssets) + { + this.streamingGroup.ReleaseGeneralAssets(); + this._preloadingGeneralAssets = false; + } + } + + public override void OnSectorOccupantsUpdated() + { + if (this._sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe)) + { + if (StreamingManager.isStreamingEnabled && this.streamingGroup != null) + { + base.enabled = true; + return; + } + } + else + { + this.UpdatePreloadingState(false, false); + base.enabled = false; + } + } + + public override void OnTriggerVolumeEntry(GameObject hitObj) + { + OWRigidbody attachedOWRigidbody = hitObj.GetAttachedOWRigidbody(false); + if (attachedOWRigidbody != null) + { + if (attachedOWRigidbody.CompareTag("Player")) + { + this._playerInVolume = true; + return; + } + if (attachedOWRigidbody.CompareTag("Probe")) + { + this._probeInVolume = true; + } + } + } + + public override void OnTriggerVolumeExit(GameObject hitObj) + { + OWRigidbody attachedOWRigidbody = hitObj.GetAttachedOWRigidbody(false); + if (attachedOWRigidbody != null) + { + if (attachedOWRigidbody.CompareTag("Player")) + { + this._playerInVolume = false; + return; + } + if (attachedOWRigidbody.CompareTag("Probe")) + { + this._probeInVolume = false; + } + } + } + } +}