diff --git a/NewHorizons/Builder/Volumes/CreditsVolumeBuilder.cs b/NewHorizons/Builder/Volumes/CreditsVolumeBuilder.cs index 81c3c6ce..4f1c0ecb 100644 --- a/NewHorizons/Builder/Volumes/CreditsVolumeBuilder.cs +++ b/NewHorizons/Builder/Volumes/CreditsVolumeBuilder.cs @@ -1,5 +1,6 @@ using NewHorizons.Components.Volumes; using NewHorizons.External.Modules.Volumes.VolumeInfos; +using OWML.Common; using OWML.Utils; using UnityEngine; @@ -7,12 +8,13 @@ namespace NewHorizons.Builder.Volumes { internal static class CreditsVolumeBuilder { - public static LoadCreditsVolume Make(GameObject planetGO, Sector sector, LoadCreditsVolumeInfo info) + public static LoadCreditsVolume Make(GameObject planetGO, Sector sector, LoadCreditsVolumeInfo info, IModBehaviour mod) { var volume = VolumeBuilder.Make(planetGO, sector, info); volume.gameOver = info.gameOver; volume.deathType = info.deathType == null ? null : EnumUtils.Parse(info.deathType.ToString(), DeathType.Default); + volume.mod = mod; return volume; } diff --git a/NewHorizons/Builder/Volumes/VolumesBuildManager.cs b/NewHorizons/Builder/Volumes/VolumesBuildManager.cs index bdaa4a5a..128717f6 100644 --- a/NewHorizons/Builder/Volumes/VolumesBuildManager.cs +++ b/NewHorizons/Builder/Volumes/VolumesBuildManager.cs @@ -209,7 +209,7 @@ namespace NewHorizons.Builder.Volumes { foreach (var creditsVolume in config.Volumes.creditsVolume) { - CreditsVolumeBuilder.Make(go, sector, creditsVolume); + CreditsVolumeBuilder.Make(go, sector, creditsVolume, mod); } } } diff --git a/NewHorizons/Components/NHGameOverManager.cs b/NewHorizons/Components/NHGameOverManager.cs index 93a7339a..354b8319 100644 --- a/NewHorizons/Components/NHGameOverManager.cs +++ b/NewHorizons/Components/NHGameOverManager.cs @@ -1,7 +1,9 @@ using NewHorizons.External.Modules; using NewHorizons.External.SerializableEnums; using NewHorizons.Handlers; +using NewHorizons.Utility.Files; using NewHorizons.Utility.OWML; +using OWML.Common; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -48,13 +50,13 @@ namespace NewHorizons.Components } } - public void StartGameOverSequence(GameOverModule gameOver, DeathType? deathType) + public void StartGameOverSequence(GameOverModule gameOver, DeathType? deathType, IModBehaviour mod = null) { _gameOverSequenceStarted = true; - Delay.StartCoroutine(GameOver(gameOver, deathType)); + Delay.StartCoroutine(GameOver(gameOver, deathType, mod)); } - private IEnumerator GameOver(GameOverModule gameOver, DeathType? deathType) + private IEnumerator GameOver(GameOverModule gameOver, DeathType? deathType, IModBehaviour mod) { OWInput.ChangeInputMode(InputMode.None); ReticleController.Hide(); @@ -104,15 +106,17 @@ namespace NewHorizons.Components yield return new WaitUntil(ReadytoLoadCreditsScene); } - LoadCreditsScene(gameOver); + LoadCreditsScene(gameOver, mod); } private bool ReadytoLoadCreditsScene() => _gameOverController._fadedOutText && _gameOverController._textAnimator.IsComplete(); - private void LoadCreditsScene(GameOverModule gameOver) + private void LoadCreditsScene(GameOverModule gameOver, IModBehaviour mod) { NHLogger.LogVerbose($"Load credits {gameOver.creditsType}"); + + switch (gameOver.creditsType) { case NHCreditsType.Fast: @@ -124,6 +128,32 @@ namespace NewHorizons.Components case NHCreditsType.Kazoo: TimelineObliterationController.s_hasRealityEnded = true; LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack); + break; + case NHCreditsType.Custom: + // We can't load in custom music if an IModBehaviour cannot be provided. This should only happen if called via TryHijackDeathSequence(). + if (mod is null) + NHLogger.LogWarning("Credits called using TryHijackDeathSequence(), custom credits audio cannot not be loaded."); + + LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack); + + // Patch new music + var musicSource = Locator.FindObjectsOfType().Where(x => x.name == "AudioSource").Single(); + musicSource.Stop(); + if (mod is not null) + { + AudioUtilities.SetAudioClip(musicSource, gameOver.audio, mod); + } + musicSource.SetMaxVolume(gameOver.audioVolume); + musicSource.loop = gameOver.audioLooping; + + // Patch scroll duration + var creditsScroll = Locator.FindObjectOfType(); + creditsScroll._scrollDuration = gameOver.scrollDuration; + + // Restart credits scroll + creditsScroll.Start(); + musicSource.FadeIn(gameOver.audioFadeInLength); + break; default: // GameOverController disables post processing diff --git a/NewHorizons/Components/Volumes/LoadCreditsVolume.cs b/NewHorizons/Components/Volumes/LoadCreditsVolume.cs index 26f75831..4f2dbfeb 100644 --- a/NewHorizons/Components/Volumes/LoadCreditsVolume.cs +++ b/NewHorizons/Components/Volumes/LoadCreditsVolume.cs @@ -1,4 +1,5 @@ using NewHorizons.External.Modules; +using OWML.Common; using UnityEngine; @@ -8,12 +9,13 @@ namespace NewHorizons.Components.Volumes { public GameOverModule gameOver; public DeathType? deathType; + public IModBehaviour mod; public override void OnTriggerVolumeEntry(GameObject hitObj) { if (hitObj.CompareTag("PlayerDetector") && enabled && (string.IsNullOrEmpty(gameOver.condition) || DialogueConditionManager.SharedInstance.GetConditionState(gameOver.condition))) { - NHGameOverManager.Instance.StartGameOverSequence(gameOver, deathType); + NHGameOverManager.Instance.StartGameOverSequence(gameOver, deathType, mod); } } diff --git a/NewHorizons/External/Modules/GameOverModule.cs b/NewHorizons/External/Modules/GameOverModule.cs index 00d029bd..dee5f302 100644 --- a/NewHorizons/External/Modules/GameOverModule.cs +++ b/NewHorizons/External/Modules/GameOverModule.cs @@ -2,6 +2,7 @@ using NewHorizons.External.SerializableData; using NewHorizons.External.SerializableEnums; using Newtonsoft.Json; using System.ComponentModel; +using System.ComponentModel.DataAnnotations; namespace NewHorizons.External.Modules { @@ -24,6 +25,40 @@ namespace NewHorizons.External.Modules /// public string condition; + /// + /// Path to the audio file to use as custom music for the credits. + /// Note: only applies when creditsType is set to "custom". + /// + public string audio; + + /// + /// The length of the fade in and out for the credits music. + /// Note: only applies when creditsType is set to "custom". + /// + [DefaultValue(1f)] + public float audioVolume; + + /// + /// Determines if the credits music should loop. + /// Note: only applies when creditsType is set to "custom". + /// + [DefaultValue(false)] + public bool audioLooping; + + /// + /// The length of the fade in for the credits music. + /// Note: only applies when creditsType is set to "custom". + /// + [DefaultValue(0f)] + public float audioFadeInLength; + + /// + /// Duration of the credits scroll in seconds. + /// Note: only applies when creditsType is set to "custom". + /// + [DefaultValue(120f)] + public float scrollDuration; + /// /// The type of credits that will run after the game over message is shown /// diff --git a/NewHorizons/External/SerializableEnums/NHCreditsType.cs b/NewHorizons/External/SerializableEnums/NHCreditsType.cs index 83c1dc51..f4d0f6c4 100644 --- a/NewHorizons/External/SerializableEnums/NHCreditsType.cs +++ b/NewHorizons/External/SerializableEnums/NHCreditsType.cs @@ -13,6 +13,8 @@ namespace NewHorizons.External.SerializableEnums [EnumMember(Value = @"kazoo")] Kazoo = 2, - [EnumMember(Value = @"none")] None = 3 + [EnumMember(Value = @"custom")] Custom = 3, + + [EnumMember(Value = @"none")] None = 4 } } diff --git a/NewHorizons/NewHorizons.csproj.user b/NewHorizons/NewHorizons.csproj.user index 5e39a9dd..44729020 100644 --- a/NewHorizons/NewHorizons.csproj.user +++ b/NewHorizons/NewHorizons.csproj.user @@ -1,4 +1,4 @@ - + $(AppData)\OuterWildsModManager\OWML\Mods\xen.NewHorizons