diff --git a/NewHorizons/Builder/Atmosphere/AtmosphereBuilder.cs b/NewHorizons/Builder/Atmosphere/AtmosphereBuilder.cs index 29854385..ac38cd76 100644 --- a/NewHorizons/Builder/Atmosphere/AtmosphereBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/AtmosphereBuilder.cs @@ -100,6 +100,15 @@ namespace NewHorizons.Builder.Atmosphere atmoGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); atmoGO.SetActive(true); + // CullGroups have already set up their renderers when this is done so we need to add ourself to it + // TODO: There are probably other builders where this is relevant + // This in particular was a bug affecting hazy dreams + if (sector != null && sector.gameObject.GetComponent() is CullGroup cullGroup) + { + cullGroup.RecursivelyAddRenderers(atmoGO.transform, true); + cullGroup.SetVisible(cullGroup.IsVisible()); + } + return atmoGO; } } diff --git a/NewHorizons/Builder/Body/CometTailBuilder.cs b/NewHorizons/Builder/Body/CometTailBuilder.cs index 9633b316..2af94def 100644 --- a/NewHorizons/Builder/Body/CometTailBuilder.cs +++ b/NewHorizons/Builder/Body/CometTailBuilder.cs @@ -60,14 +60,22 @@ namespace NewHorizons.Builder.Body } } - public static void Make(GameObject planetGO, Sector sector, CometTailModule cometTailModule, PlanetConfig config) + public static void Make(GameObject planetGO, Sector sector, CometTailModule cometTailModule, PlanetConfig config, AstroObject ao) { - if (config.Orbit.primaryBody == null) + var primaryBody = ao.GetPrimaryBody(); + + if (!string.IsNullOrEmpty(config.Orbit.primaryBody)) primaryBody = AstroObjectLocator.GetAstroObject(config.Orbit.primaryBody); + + if (primaryBody == null) { NHLogger.LogError($"Comet {planetGO.name} does not orbit anything. That makes no sense"); return; } + if (string.IsNullOrEmpty(cometTailModule.primaryBody)) + cometTailModule.primaryBody = !string.IsNullOrEmpty(config.Orbit.primaryBody) ? config.Orbit.primaryBody + : primaryBody.GetKey(); + var rootObj = new GameObject("CometRoot"); rootObj.SetActive(false); rootObj.transform.parent = sector?.transform ?? planetGO.transform; @@ -79,13 +87,11 @@ namespace NewHorizons.Builder.Body if (cometTailModule.rotationOverride != null) controller.SetRotationOverride(cometTailModule.rotationOverride); - if (string.IsNullOrEmpty(cometTailModule.primaryBody)) cometTailModule.primaryBody = config.Orbit.primaryBody; - Delay.FireOnNextUpdate(() => { controller.SetPrimaryBody( - AstroObjectLocator.GetAstroObject(cometTailModule.primaryBody).transform, - AstroObjectLocator.GetAstroObject(config.Orbit.primaryBody).GetAttachedOWRigidbody() + AstroObjectLocator.GetAstroObject(cometTailModule.primaryBody).transform, + primaryBody.GetAttachedOWRigidbody() ); }); diff --git a/NewHorizons/Builder/Body/ProxyBuilder.cs b/NewHorizons/Builder/Body/ProxyBuilder.cs index 0b4cafc3..943726eb 100644 --- a/NewHorizons/Builder/Body/ProxyBuilder.cs +++ b/NewHorizons/Builder/Body/ProxyBuilder.cs @@ -203,7 +203,7 @@ namespace NewHorizons.Builder.Body if (body.Config.CometTail != null) { - CometTailBuilder.Make(proxy, null, body.Config.CometTail, body.Config); + CometTailBuilder.Make(proxy, null, body.Config.CometTail, body.Config, planetGO.GetComponent()); } if (body.Config.Props?.proxyDetails != null) diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 825af0c1..d7400937 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -473,10 +473,14 @@ namespace NewHorizons.Builder.Props { // These flood toggles are to disable flooded docks on the Stranger // Presumably the user isn't making one of those - foreach (var toggle in dock.GetComponents()) + foreach (var toggle in dock.GetComponents().Concat(dock.GetComponentsInChildren())) { Component.DestroyImmediate(toggle); } + foreach (var floodSensor in dock.GetComponents().Concat(dock.GetComponentsInChildren())) + { + Component.DestroyImmediate(floodSensor); + } } } diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index 2ebf64fc..8639d3c7 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -43,6 +43,7 @@ namespace NewHorizons.Builder.Props private static GameObject _autoPrefab; private static GameObject _visionTorchDetectorPrefab; private static GameObject _standingVisionTorchPrefab; + private static GameObject _standingVisionTorchCleanPrefab; private static readonly int EmissionMap = Shader.PropertyToID("_EmissionMap"); private static bool _isInit; @@ -90,13 +91,28 @@ namespace NewHorizons.Builder.Props _visionTorchDetectorPrefab.AddComponent()._destroyOnDLCNotOwned = true; } + if (_standingVisionTorchCleanPrefab == null) + { + _standingVisionTorchCleanPrefab = SearchUtilities.Find("DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_4/Interactibles_DreamZone_4_Upper/Prefab_IP_VisionTorchProjector")?.gameObject?.InstantiateInactive()?.Rename("Prefab_DW_VisionTorchProjector")?.DontDestroyOnLoad(); + if (_standingVisionTorchCleanPrefab == null) + NHLogger.LogWarning($"Tried to make standing vision torch prefab but couldn't. Do you have the DLC installed?"); + else + { + _standingVisionTorchCleanPrefab.AddComponent()._destroyOnDLCNotOwned = true; + GameObject.DestroyImmediate(_standingVisionTorchCleanPrefab.FindChild("Prefab_IP_Reel_PrisonPeephole_Vision")); + } + } + if (_standingVisionTorchPrefab == null) { _standingVisionTorchPrefab = SearchUtilities.Find("RingWorld_Body/Sector_RingWorld/Sector_SecretEntrance/Interactibles_SecretEntrance/Experiment_1/VisionTorchApparatus/VisionTorchRoot/Prefab_IP_VisionTorchProjector")?.gameObject?.InstantiateInactive()?.Rename("Prefab_IP_VisionTorchProjector")?.DontDestroyOnLoad(); if (_standingVisionTorchPrefab == null) NHLogger.LogWarning($"Tried to make standing vision torch prefab but couldn't. Do you have the DLC installed?"); else + { _standingVisionTorchPrefab.AddComponent()._destroyOnDLCNotOwned = true; + GameObject.Instantiate(_standingVisionTorchCleanPrefab.FindChild("Effects_IP_SIM_VisionTorch"), _standingVisionTorchPrefab.transform, false).Rename("Effects_IP_SIM_VisionTorch"); + } } } @@ -446,10 +462,11 @@ namespace NewHorizons.Builder.Props { InitPrefabs(); - if (_standingVisionTorchPrefab == null) return null; + if (_standingVisionTorchPrefab == null || _standingVisionTorchCleanPrefab == null) return null; // Spawn the torch itself - var standingTorch = DetailBuilder.Make(planetGO, sector, mod, _standingVisionTorchPrefab, new DetailInfo(info)); + var prefab = info.reelCondition == ProjectionInfo.SlideReelCondition.Pristine ? _standingVisionTorchCleanPrefab : _standingVisionTorchPrefab; + var standingTorch = DetailBuilder.Make(planetGO, sector, mod, prefab, new DetailInfo(info)); if (standingTorch == null) { diff --git a/NewHorizons/Builder/Volumes/CreditsVolumeBuilder.cs b/NewHorizons/Builder/Volumes/CreditsVolumeBuilder.cs index 5692c3e5..cd55f9da 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; volume.gameObject.SetActive(true); diff --git a/NewHorizons/Builder/Volumes/VolumesBuildManager.cs b/NewHorizons/Builder/Volumes/VolumesBuildManager.cs index 66c33c49..be8f3e45 100644 --- a/NewHorizons/Builder/Volumes/VolumesBuildManager.cs +++ b/NewHorizons/Builder/Volumes/VolumesBuildManager.cs @@ -247,7 +247,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..37661562 100644 --- a/NewHorizons/Components/NHGameOverManager.cs +++ b/NewHorizons/Components/NHGameOverManager.cs @@ -1,7 +1,11 @@ using NewHorizons.External.Modules; using NewHorizons.External.SerializableEnums; using NewHorizons.Handlers; +using NewHorizons.Patches.CreditsScenePatches; +using NewHorizons.Utility.Files; using NewHorizons.Utility.OWML; +using OWML.Common; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -15,14 +19,14 @@ namespace NewHorizons.Components /// Mod unique id to game over module list /// Done as a dictionary so that Reload Configs can overwrite entries per mod /// - public static Dictionary gameOvers = new(); + public static Dictionary gameOvers = new(); public static NHGameOverManager Instance { get; private set; } private GameOverController _gameOverController; private PlayerCameraEffectController _playerCameraEffectController; - private GameOverModule[] _gameOvers; + private (IModBehaviour mod, GameOverModule gameOver)[] _gameOvers; private bool _gameOverSequenceStarted; @@ -36,25 +40,35 @@ namespace NewHorizons.Components _gameOverController = FindObjectOfType(); _playerCameraEffectController = FindObjectOfType(); - _gameOvers = gameOvers.SelectMany(x => x.Value).ToArray(); + var gameOverList = new List<(IModBehaviour, GameOverModule)>(); + foreach (var gameOverPair in gameOvers) + { + var mod = gameOverPair.Key; + foreach (var gameOver in gameOverPair.Value) + { + gameOverList.Add((mod, gameOver)); + } + } + _gameOvers = gameOverList.ToArray(); } public void TryHijackDeathSequence() { - var gameOver = _gameOvers.FirstOrDefault(x => !string.IsNullOrEmpty(x.condition) && DialogueConditionManager.SharedInstance.GetConditionState(x.condition)); - if (!_gameOverSequenceStarted && gameOver != null && !Locator.GetDeathManager()._finishedDLC) + var gameOver = _gameOvers.FirstOrDefault(x => !string.IsNullOrEmpty(x.gameOver.condition) + && DialogueConditionManager.SharedInstance.GetConditionState(x.gameOver.condition)); + if (!_gameOverSequenceStarted && gameOver != default && !Locator.GetDeathManager()._finishedDLC) { - StartGameOverSequence(gameOver, null); + StartGameOverSequence(gameOver.gameOver, null, gameOver.mod); } } - public void StartGameOverSequence(GameOverModule gameOver, DeathType? deathType) + public void StartGameOverSequence(GameOverModule gameOver, DeathType? deathType, IModBehaviour mod) { _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,12 +118,12 @@ 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}"); @@ -125,6 +139,9 @@ namespace NewHorizons.Components TimelineObliterationController.s_hasRealityEnded = true; LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack); break; + case NHCreditsType.Custom: + LoadCustomCreditsScene(gameOver, mod); + break; default: // GameOverController disables post processing _gameOverController._flashbackCamera.postProcessing.enabled = true; @@ -134,5 +151,42 @@ namespace NewHorizons.Components break; } } + + private void LoadCustomCreditsScene(GameOverModule gameOver, IModBehaviour mod) + { + LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack); + + // Unfortunately we can't make this a private method, as EventArgs/EventHandler enforces the (sender, e) parameters, which prevents us from passing in gameOver and mod, which we need. + EventHandler onCreditsBuilt = null; // needs to be done so we can unsubscribe from within the lambda. + onCreditsBuilt = (sender, e) => + { + // Unsubscribe first, playing it safe in case it NREs + CreditsPatches.CreditsBuilt -= onCreditsBuilt; + + // Patch new music clip + var musicSource = Locator.FindObjectsOfType().Where(x => x.name == "AudioSource").Single(); // AudioSource that plays the credits music is literally called "AudioSource", luckily it's the only one called that. Lazy OW devs do be lazy. + if (!string.IsNullOrEmpty(gameOver.audio)) // string.Empty is default value for "audio" in GameOverModule, means no audio is specified. + { + AudioUtilities.SetAudioClip(musicSource, gameOver.audio, mod); // Load audio if specified + } + else + { + musicSource.AssignAudioLibraryClip(AudioType.PLACEHOLDER); // Otherwise default custom credits are silent - AudioType.PLACEHOLDER is silence (apparently) + } + + musicSource.loop = gameOver.audioLooping; + musicSource._maxSourceVolume = gameOver.audioVolume; + + // Override fade in + musicSource.Stop(); + musicSource.Play(); + + // Patch scroll duration + var creditsScroll = Locator.FindObjectOfType(); + creditsScroll._scrollDuration = gameOver.length; + }; + + CreditsPatches.CreditsBuilt += onCreditsBuilt; + } } } 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..5d73f4a3 100644 --- a/NewHorizons/External/Modules/GameOverModule.cs +++ b/NewHorizons/External/Modules/GameOverModule.cs @@ -24,6 +24,31 @@ namespace NewHorizons.External.Modules /// public string condition; + /// + /// The audio to use for the credits music. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list. + /// Credits will be silent unless this attribute is specified. + /// 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 = 1f; + + /// + /// Determines if the credits music should loop. + /// Note: only applies when creditsType is set to "custom". + /// + [DefaultValue(false)] public bool audioLooping = false; + + /// + /// Duration of the credits scroll in seconds. + /// Note: only applies when creditsType is set to "custom". + /// + [DefaultValue(120f)] public float length = 120f; + /// /// The type of credits that will run after the game over message is shown /// diff --git a/NewHorizons/External/Modules/Props/EchoesOfTheEye/ProjectionInfo.cs b/NewHorizons/External/Modules/Props/EchoesOfTheEye/ProjectionInfo.cs index e059c310..43424ec0 100644 --- a/NewHorizons/External/Modules/Props/EchoesOfTheEye/ProjectionInfo.cs +++ b/NewHorizons/External/Modules/Props/EchoesOfTheEye/ProjectionInfo.cs @@ -82,7 +82,7 @@ namespace NewHorizons.External.Modules.Props.EchoesOfTheEye [DefaultValue("sevenSlides")] public SlideReelType reelModel = SlideReelType.SevenSlides; /// - /// Exclusive to the slide reel type. Condition/material of the reel. Antique is the Stranger, Pristine is the Dreamworld, Rusted is a burned reel. + /// Exclusive to the slide reel and standing vision torch type. Condition/material of the reel. Antique is the Stranger, Pristine is the Dreamworld, Rusted (exclusive to slide reels) is a burned reel. /// [DefaultValue("antique")] public SlideReelCondition reelCondition = SlideReelCondition.Antique; 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/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 858131e9..8b0c01f2 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -657,7 +657,7 @@ namespace NewHorizons.Handlers if (body.Config.CometTail != null) { - CometTailBuilder.Make(go, sector, body.Config.CometTail, body.Config); + CometTailBuilder.Make(go, sector, body.Config.CometTail, body.Config, go.GetComponent()); } if (body.Config.Lava != null) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index f81400a9..113be63b 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -849,7 +849,7 @@ namespace NewHorizons } if (addonConfig.gameOver != null) { - NHGameOverManager.gameOvers[mod.ModHelper.Manifest.UniqueName] = addonConfig.gameOver; + NHGameOverManager.gameOvers[mod] = addonConfig.gameOver; } AddonConfigs[mod] = addonConfig; 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 diff --git a/NewHorizons/Patches/CreditsScenePatches/CreditsPatches.cs b/NewHorizons/Patches/CreditsScenePatches/CreditsPatches.cs index 8892f334..037b30bf 100644 --- a/NewHorizons/Patches/CreditsScenePatches/CreditsPatches.cs +++ b/NewHorizons/Patches/CreditsScenePatches/CreditsPatches.cs @@ -1,17 +1,30 @@ using HarmonyLib; using NewHorizons.Handlers; +using System; namespace NewHorizons.Patches.CreditsScenePatches { [HarmonyPatch(typeof(Credits))] public static class CreditsPatches { + public static event EventHandler CreditsBuilt; // Used in NHGameOverManager to patch credits music and scroll speed + [HarmonyPrefix] [HarmonyPatch(nameof(Credits.Start))] public static void Credits_Start(Credits __instance) { CreditsHandler.AddCredits(__instance); } + + [HarmonyPostfix] + [HarmonyPatch(nameof(Credits.BuildCredits))] + public static void Credits_BuildCredits_Post(Credits __instance) + { + // Do things BuildCredits() normally does + + // Fire event once finished + CreditsBuilt?.Invoke(__instance, new EventArgs()); + } } } diff --git a/NewHorizons/Utility/Files/AudioUtilities.cs b/NewHorizons/Utility/Files/AudioUtilities.cs index fe09d46e..f3c2924d 100644 --- a/NewHorizons/Utility/Files/AudioUtilities.cs +++ b/NewHorizons/Utility/Files/AudioUtilities.cs @@ -27,23 +27,34 @@ namespace NewHorizons.Utility.Files source._clipArrayLength = 0; source._clipSelectionOnPlay = OWAudioSource.ClipSelectionOnPlay.MANUAL; source.clip = clip; + NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was loaded from a file"); return; } catch { - NHLogger.LogError($"Could not load file {audio}"); + NHLogger.LogError($"[{nameof(AudioUtilities)}] : Could not load file {audio}"); } } if (EnumUtils.TryParse(audio, out AudioType type)) { source._audioLibraryClip = type; + NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was an AudioType enum"); } else { var audioClip = SearchUtilities.FindResourceOfTypeAndName(audio); - if (audioClip == null) NHLogger.Log($"Couldn't find audio clip {audio}"); - else source.clip = audioClip; + if (audioClip == null) + { + NHLogger.LogError($"[{nameof(AudioUtilities)}] : Couldn't find audio clip {audio}"); + } + else + { + NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was an AudioClip resource"); + // Else if this is set it will try to change the clip back when it starts playing + source._audioLibraryClip = AudioType.None; + source.clip = audioClip; + } } } diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index 9f4da941..216ea14a 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -445,6 +445,11 @@ namespace NewHorizons.Utility return globalMusicController._endTimesSource.clip.length; } + public static string GetKey(this AstroObject ao) + { + return ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString(); + } + public static CodeMatcher LogInstructions(this CodeMatcher matcher, string prefix) { matcher.InstructionEnumeration().LogInstructions(prefix); diff --git a/NewHorizons/Utility/OuterWilds/AstroObjectLocator.cs b/NewHorizons/Utility/OuterWilds/AstroObjectLocator.cs index 9e3a8a01..dd3c9564 100644 --- a/NewHorizons/Utility/OuterWilds/AstroObjectLocator.cs +++ b/NewHorizons/Utility/OuterWilds/AstroObjectLocator.cs @@ -65,7 +65,7 @@ namespace NewHorizons.Utility.OuterWilds public static void RegisterCustomAstroObject(AstroObject ao) { - var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString(); + var key = ao.GetKey(); if (_customAstroObjectDictionary.ContainsKey(key)) { @@ -81,7 +81,7 @@ namespace NewHorizons.Utility.OuterWilds public static void DeregisterCustomAstroObject(AstroObject ao) { - var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString(); + var key = ao.GetKey(); _customAstroObjectDictionary.Remove(key); } diff --git a/NewHorizons/manifest.json b/NewHorizons/manifest.json index eff475cf..3311a8fb 100644 --- a/NewHorizons/manifest.json +++ b/NewHorizons/manifest.json @@ -4,7 +4,7 @@ "author": "xen, Bwc9876, JohnCorby, MegaPiggy, and friends", "name": "New Horizons", "uniqueName": "xen.NewHorizons", - "version": "1.27.3", + "version": "1.27.4", "owmlVersion": "2.12.1", "dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ], "conflicts": [ "PacificEngine.OW_CommonResources" ], diff --git a/docs/src/content/docs/guides/details.md b/docs/src/content/docs/guides/details.md index faff0389..bb0ee020 100644 --- a/docs/src/content/docs/guides/details.md +++ b/docs/src/content/docs/guides/details.md @@ -20,12 +20,12 @@ You can use [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) to t ## Asset Bundles -There is an [old unity template](https://github.com/xen-42/outer-wilds-unity-template) and a [new one](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki#outer-wilds-unity-assets) +There is an [old unity template](https://github.com/xen-42/outer-wilds-unity-template) and a [new one](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki/Tools-%E2%80%90-Outer-Wilds-Unity-Assets-repository) The project contains ripped versions of all the game scripts, meaning you can put things like DirectionalForceVolumes in your Unity project to have artificial gravity volumes loaded right into the game.\ Either one works, but the new one has more tools and better versions of the scripts (in exchange for being invite-only). -Read [this guide](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki/Tutorials-%E2%80%90-Using-asset-bundles) on how to work with asset bundles in editor. +Read [this guide](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki/Tutorials-%E2%80%90-Using-AssetBundles) on how to work with asset bundles in editor. ## Importing a planet's surface from Unity diff --git a/docs/src/content/docs/guides/troubleshooting.md b/docs/src/content/docs/guides/troubleshooting.md index d4650d40..8f6b4592 100644 --- a/docs/src/content/docs/guides/troubleshooting.md +++ b/docs/src/content/docs/guides/troubleshooting.md @@ -19,5 +19,5 @@ which interact poorly with the fluid detector and can mess up the movement of th Either clear the .nhcache files or enable Debug mode to always regenerate the text cache. ## Prop placer is gone! -This is not a bug, actually. We removed prop placer because it was inconsistent and buggy, and no one in years cared enough to fix it. -Use the debug raycast button and Unity Explorer to place your props, or otherwise work in unity editor. +It has been moved to a [separate mod](https://outerwildsmods.com/mods/propplacer/). +Use it in addition to the debug raycast button and Unity Explorer to place your props, or otherwise work in unity editor.