diff --git a/NewHorizons/Builder/Props/BrambleNodeBuilder.cs b/NewHorizons/Builder/Props/BrambleNodeBuilder.cs index 3e5437e7..2aa1075e 100644 --- a/NewHorizons/Builder/Props/BrambleNodeBuilder.cs +++ b/NewHorizons/Builder/Props/BrambleNodeBuilder.cs @@ -33,12 +33,17 @@ namespace NewHorizons.Builder.Props private static GameObject _brambleSeedPrefab; private static GameObject _brambleNodePrefab; + private static HashSet _nhFogWarpVolumes = new(); + + public static bool IsNHFogWarpVolume(FogWarpVolume volume) => _nhFogWarpVolumes.Contains(volume); + public static void Init(PlanetConfig[] dimensionConfigs) { _unpairedNodes.Clear(); _propagatedSignals.Clear(); namedNodes.Clear(); builtBrambleNodes.Clear(); + _nhFogWarpVolumes.Clear(); PropagateSignals(dimensionConfigs); } @@ -190,6 +195,12 @@ namespace NewHorizons.Builder.Props collider.enabled = true; } + // We track all the fog warp volumes that NH created so we can only effect those in patches, this way we leave base game stuff alone. + foreach (var fogWarpVolume in brambleNode.GetComponentsInChildren(true).Append(brambleNode.GetComponent())) + { + _nhFogWarpVolumes.Add(fogWarpVolume); + } + var innerFogWarpVolume = brambleNode.GetComponent(); var outerFogWarpVolume = GetOuterFogWarpVolumeFromAstroObject(go); var fogLight = brambleNode.GetComponent(); @@ -239,6 +250,12 @@ namespace NewHorizons.Builder.Props foreach(Transform child in brambleNode.transform) { child.localScale = Vector3.one * config.scale; + + // The fog on bramble seeds has a specific scale we need to copy over + if (child.name == "VolumetricFogSphere (2)") + { + child.localScale *= 6.3809f; + } } innerFogWarpVolume._warpRadius *= config.scale; innerFogWarpVolume._exitRadius *= config.scale; diff --git a/NewHorizons/Components/Volumes/NHInnerFogWarpVolume.cs b/NewHorizons/Components/Volumes/NHInnerFogWarpVolume.cs deleted file mode 100644 index 70d74979..00000000 --- a/NewHorizons/Components/Volumes/NHInnerFogWarpVolume.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace NewHorizons.Components.Volumes -{ - public class NHInnerFogWarpVolume : InnerFogWarpVolume - { - public override bool IsProbeOnly() => _exitRadius <= 6; - public override float GetFogThickness() => _exitRadius; - } -} diff --git a/NewHorizons/Handlers/SubtitlesHandler.cs b/NewHorizons/Handlers/SubtitlesHandler.cs index de283b54..7207a8a5 100644 --- a/NewHorizons/Handlers/SubtitlesHandler.cs +++ b/NewHorizons/Handlers/SubtitlesHandler.cs @@ -14,9 +14,6 @@ namespace NewHorizons.Handlers public static int SUBTITLE_HEIGHT = 97; public static int SUBTITLE_WIDTH = 669; // nice - public Graphic graphic; - public Image image; - public float fadeSpeed = 0.005f; public float fade = 1; public bool fadingAway = true; @@ -29,13 +26,27 @@ namespace NewHorizons.Handlers public static readonly int PAUSE_TIMER_MAX = 50; public int pauseTimer = PAUSE_TIMER_MAX; + private Image _subtitleDisplay; + private Graphic _graphic; + + private static List<(IModBehaviour mod, string filePath)> _additionalSubtitles = new(); + + public static void RegisterAdditionalSubtitle(IModBehaviour mod, string filePath) + { + _additionalSubtitles.Add((mod, filePath)); + } + public void CheckForEOTE() { if (!eoteSubtitleHasBeenInserted) { if (Main.HasDLC) { - if (eoteSprite != null) possibleSubtitles.Insert(0, eoteSprite); // ensure that the Echoes of the Eye subtitle always appears first + if (eoteSprite != null) + { + // Don't make it appear first actually because we have mods to display! + possibleSubtitles.Add(eoteSprite); + } eoteSubtitleHasBeenInserted = true; } } @@ -43,18 +54,25 @@ namespace NewHorizons.Handlers public void Start() { + // We preserve the current image to add it to our custom subtitle + // We also need this element to preserve its size GetComponent().alpha = 1; - graphic = GetComponent(); - image = GetComponent(); - - graphic.enabled = true; - image.enabled = true; - + var image = GetComponent(); eoteSprite = image.sprite; + image.sprite = null; + image.enabled = false; + var layout = GetComponent(); + layout.minHeight = SUBTITLE_HEIGHT; CheckForEOTE(); - image.sprite = null; // Just in case. I don't know how not having the dlc changes the subtitle game object + // We add our subtitles as a child object so that their sizing doesnt shift the layout of the main menu + _subtitleDisplay = new GameObject().AddComponent(); + _subtitleDisplay.transform.parent = transform; + _subtitleDisplay.transform.localPosition = new Vector3(0, 0, 0); + _subtitleDisplay.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); + _graphic = _subtitleDisplay.gameObject.GetAddComponent(); + _subtitleDisplay.gameObject.GetAddComponent().minWidth = SUBTITLE_WIDTH; AddSubtitles(); } @@ -73,6 +91,10 @@ namespace NewHorizons.Handlers AddSubtitle(mod, "subtitle.png"); } } + foreach (var pair in _additionalSubtitles) + { + AddSubtitle(pair.mod, pair.filePath); + } } public void AddSubtitle(IModBehaviour mod, string filepath) @@ -82,7 +104,7 @@ namespace NewHorizons.Handlers var tex = ImageUtilities.GetTexture(mod, filepath, false); if (tex == null) return; - var sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, SUBTITLE_HEIGHT), new Vector2(0.5f, 0.5f), 100.0f); + var sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, Mathf.Max(SUBTITLE_HEIGHT, tex.height)), new Vector2(0.5f, 0.5f), 100.0f); AddSubtitle(sprite); } @@ -95,12 +117,25 @@ namespace NewHorizons.Handlers { CheckForEOTE(); - if (possibleSubtitles.Count == 0) return; + if (possibleSubtitles.Count == 0) + { + return; + } - if (image.sprite == null) image.sprite = possibleSubtitles[0]; + _subtitleDisplay.transform.localPosition = new Vector3(0, -36, 0); + + if (_subtitleDisplay.sprite == null) + { + _subtitleDisplay.sprite = possibleSubtitles[0]; + // Always call this in case we stop changing subtitles after + ChangeSubtitle(); + } // don't fade transition subtitles if there's only one subtitle - if (possibleSubtitles.Count <= 1) return; + if (possibleSubtitles.Count <= 1) + { + return; + } if (pauseTimer > 0) { @@ -111,7 +146,7 @@ namespace NewHorizons.Handlers if (fadingAway) { fade -= fadeSpeed; - + if (fade <= 0) { fade = 0; @@ -122,7 +157,7 @@ namespace NewHorizons.Handlers else { fade += fadeSpeed; - + if (fade >= 1) { fade = 1; @@ -131,14 +166,16 @@ namespace NewHorizons.Handlers } } - graphic.color = new Color(1, 1, 1, fade); + _graphic.color = new Color(1, 1, 1, fade); } public void ChangeSubtitle() { subtitleIndex = (subtitleIndex + 1) % possibleSubtitles.Count; - - image.sprite = possibleSubtitles[subtitleIndex]; + + _subtitleDisplay.sprite = possibleSubtitles[subtitleIndex]; + var ratio = SUBTITLE_WIDTH / _subtitleDisplay.sprite.texture.width; + _subtitleDisplay.rectTransform.sizeDelta = new Vector2(_subtitleDisplay.sprite.texture.width, _subtitleDisplay.sprite.texture.height) * ratio; } } } diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index 22132568..4dfd2d1f 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -207,5 +207,13 @@ namespace NewHorizons /// string GetTranslationForOtherText(string text); #endregion + + /// + /// Registers a subtitle for the main menu. + /// Call this once before the main menu finishes loading + /// + /// + /// + void AddSubtitle(IModBehaviour mod, string filePath); } } diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index a96673d5..6a165fa2 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -336,5 +336,7 @@ namespace NewHorizons public string GetTranslationForUI(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.UI); public string GetTranslationForOtherText(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.OTHER); + + public void AddSubtitle(IModBehaviour mod, string filePath) => SubtitlesHandler.RegisterAdditionalSubtitle(mod, filePath); } } diff --git a/NewHorizons/Patches/VolumePatches/FogWarpVolumePatches.cs b/NewHorizons/Patches/VolumePatches/FogWarpVolumePatches.cs index f63bad81..41f3e652 100644 --- a/NewHorizons/Patches/VolumePatches/FogWarpVolumePatches.cs +++ b/NewHorizons/Patches/VolumePatches/FogWarpVolumePatches.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using NewHorizons.Builder.Props; using UnityEngine; namespace NewHorizons.Patches.VolumePatches @@ -8,20 +9,38 @@ namespace NewHorizons.Patches.VolumePatches { [HarmonyPrefix] [HarmonyPatch(typeof(SphericalFogWarpVolume), nameof(SphericalFogWarpVolume.IsProbeOnly))] - public static bool SphericalFogWarpVolume_IsProbeOnly(SphericalFogWarpVolume __instance, out bool __result) + public static bool SphericalFogWarpVolume_IsProbeOnly(SphericalFogWarpVolume __instance, ref bool __result) { - __result = Mathf.Approximately(__instance._exitRadius / __instance._warpRadius, 2f); // Check the ratio between these to determine if seed, instead of just < 10 + // Do not affect base game volumes + if (!BrambleNodeBuilder.IsNHFogWarpVolume(__instance)) + { + return true; + } + + // Check the ratio between these to determine if seed, instead of just < 10 + __result = Mathf.Approximately(__instance._exitRadius / __instance._warpRadius, 2f); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(FogWarpVolume), nameof(FogWarpVolume.GetFogThickness))] - public static bool FogWarpVolume_GetFogThickness(FogWarpVolume __instance, out float __result) + public static bool FogWarpVolume_GetFogThickness(FogWarpVolume __instance, ref float __result) { - if (__instance is InnerFogWarpVolume sph) __result = sph._exitRadius; - else __result = 50; // 50f is hardcoded as the return value in the base game + // Do not affect base game volumes + if (!BrambleNodeBuilder.IsNHFogWarpVolume(__instance)) + { + return true; + } - return false; + if (__instance is InnerFogWarpVolume sph) + { + __result = sph._exitRadius; + return false; + } + else + { + return true; + } } } }