diff --git a/NewHorizons/External/Configs/StarSystemConfig.cs b/NewHorizons/External/Configs/StarSystemConfig.cs index 196bc7b6..9e6b902c 100644 --- a/NewHorizons/External/Configs/StarSystemConfig.cs +++ b/NewHorizons/External/Configs/StarSystemConfig.cs @@ -4,6 +4,8 @@ namespace NewHorizons.External.Configs { public class StarSystemConfig { + public string subtitle; + [DefaultValue(true)] public bool canEnterViaWarpDrive = true; [DefaultValue(true)] public bool enableTimeLoop = true; [DefaultValue(true)] public bool destroyStockPlanets = true; diff --git a/NewHorizons/Handlers/SubtitlesHandler.cs b/NewHorizons/Handlers/SubtitlesHandler.cs new file mode 100644 index 00000000..26cdf081 --- /dev/null +++ b/NewHorizons/Handlers/SubtitlesHandler.cs @@ -0,0 +1,118 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using NewHorizons.Utility; +using OWML.Common; + +namespace NewHorizons.Handlers +{ + class SubtitlesHandler : MonoBehaviour + { + public static int SUBTITLE_HEIGHT = 97; + public static int SUBTITLE_WIDTH = 669; // nice + + Graphic graphic; + Image image; + + public float fadeSpeed = 0.005f; + float fade = 1; + bool fadingAway = true; + + static List possibleSubtitles = new List(); + static bool eoteSubtitleHasBeenInserted = false; + int subtitleIndex; + + System.Random randomizer; + + static readonly int PAUSE_TIMER_MAX = 50; + int pauseTimer = PAUSE_TIMER_MAX; + + public void Start() + { + randomizer = new System.Random(); + + GetComponent().alpha = 1; + graphic = GetComponent(); + image = GetComponent(); + + graphic.enabled = true; + image.enabled = true; + + if (!Main.HasDLC) image.sprite = null; // Just in case. I don't know how not having the dlc changes the subtitle game object + + if (!eoteSubtitleHasBeenInserted) + { + if (image.sprite != null) possibleSubtitles.Insert(0, image.sprite); // ensure that the Echoes of the Eye subtitle always appears first + eoteSubtitleHasBeenInserted = true; + } + } + + public static void AddSubtitle(IModBehaviour mod, string filepath) + { + var tex = ImageUtilities.GetTexture(mod, filepath); + if (tex == null) return; + + // var sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f); + var sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, SUBTITLE_HEIGHT), new Vector2(0.5f, 0.5f), 100.0f); + AddSubtitle(sprite); + } + + public static void AddSubtitle(Sprite sprite) + { + possibleSubtitles.Add(sprite); + } + + public void Update() + { + if (image.sprite == null) image.sprite = possibleSubtitles[0]; + + // don't fade transition subtitles if there's only one subtitle + if (possibleSubtitles.Count <= 1) return; + + if (pauseTimer > 0) + { + pauseTimer--; + return; + } + + if (fadingAway) + { + fade -= fadeSpeed; + + if (fade <= 0) + { + fade = 0; + ChangeSubtitle(); + fadingAway = false; + } + } + else + { + fade += fadeSpeed; + + if (fade >= 1) + { + fade = 1; + fadingAway = true; + pauseTimer = PAUSE_TIMER_MAX; + } + } + + graphic.color = new Color(1, 1, 1, fade); + } + + public void ChangeSubtitle() + { + // to pick a new random subtitle without requiring retries, we generate a random offset less than the length of the possible subtitles array + // we then add that offset to the current index, modulo NUMBER_OF_POSSIBLE_SUBTITLES + // since the offset can never be NUMBER_OF_POSSIBLE_SUBTITLES, it will never wrap all the way back around to the initial subtitleIndex + + // note, this makes the code more confusing, but Random.Next(min, max) generates a random number on the range [min, max) + // that is, the below code will generate numbers up to and including Count-1, not Count. + var newIndexOffset = randomizer.Next(1, possibleSubtitles.Count); + subtitleIndex = (subtitleIndex + newIndexOffset) % possibleSubtitles.Count; + + image.sprite = possibleSubtitles[subtitleIndex]; + } + } +} diff --git a/NewHorizons/Handlers/TitleSceneHandler.cs b/NewHorizons/Handlers/TitleSceneHandler.cs index f0e82aa0..9a28229b 100644 --- a/NewHorizons/Handlers/TitleSceneHandler.cs +++ b/NewHorizons/Handlers/TitleSceneHandler.cs @@ -11,6 +11,20 @@ namespace NewHorizons.Handlers { public static class TitleSceneHandler { + public static void InitSubtitles() + { + GameObject subtitleContainer = GameObject.Find("TitleMenu/TitleCanvas/TitleLayoutGroup/Logo_EchoesOfTheEye"); + + if (subtitleContainer == null) + { + Logger.LogError("No subtitle container found! Failed to load subtitles."); + return; + } + + subtitleContainer.SetActive(true); + subtitleContainer.AddComponent(); + } + public static void DisplayBodyOnTitleScreen(List bodies) { //Try loading one planet why not diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index a1203e28..9a45ac13 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -199,6 +199,7 @@ namespace NewHorizons if (scene.name == "TitleScreen" && _useCustomTitleScreen) { TitleSceneHandler.DisplayBodyOnTitleScreen(BodyDict.Values.ToList().SelectMany(x => x).ToList()); + TitleSceneHandler.InitSubtitles(); } if (scene.name == "EyeOfTheUniverse" && IsWarping) @@ -313,6 +314,11 @@ namespace NewHorizons if (name != "SolarSystem") SetDefaultSystem(name); } + if (starSystemConfig.subtitle != null) + { + SubtitlesHandler.AddSubtitle(mod, starSystemConfig.subtitle); + } + var system = new NewHorizonsSystem(name, starSystemConfig, mod); SystemDict[name] = system; }