From e5b652ba22babd2b42d6c396ba5d3d617443cf99 Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 10 Sep 2022 20:00:09 -0400 Subject: [PATCH 1/7] Allow overriding far clip plane --- .../External/Configs/StarSystemConfig.cs | 5 ++++ NewHorizons/Patches/OWCameraPatch.cs | 27 +++++-------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/NewHorizons/External/Configs/StarSystemConfig.cs b/NewHorizons/External/Configs/StarSystemConfig.cs index ce311174..5d3963aa 100644 --- a/NewHorizons/External/Configs/StarSystemConfig.cs +++ b/NewHorizons/External/Configs/StarSystemConfig.cs @@ -14,6 +14,11 @@ namespace NewHorizons.External.Configs [JsonObject] public class StarSystemConfig { + /// + /// An override value for the far clip plane. Allows you to see farther. + /// + public float farClipPlaneOverride; + /// /// Whether this system can be warped to via the warp drive. If you set factRequiredForWarp, this will be true. /// diff --git a/NewHorizons/Patches/OWCameraPatch.cs b/NewHorizons/Patches/OWCameraPatch.cs index 863b56bd..ccdafafc 100644 --- a/NewHorizons/Patches/OWCameraPatch.cs +++ b/NewHorizons/Patches/OWCameraPatch.cs @@ -1,4 +1,4 @@ -using HarmonyLib; +using HarmonyLib; namespace NewHorizons.Patches { [HarmonyPatch] @@ -8,25 +8,12 @@ namespace NewHorizons.Patches [HarmonyPatch(typeof(OWCamera), nameof(OWCamera.Awake))] public static void OnOWCameraAwake(OWCamera __instance) { - // var oldDist = __instance.farClipPlane; - // var newDist = __instance.farClipPlane * 10f; - // if (__instance.useFarCamera) Mathf.Clamp(newDist, oldDist, 50000f); - // else newDist = Mathf.Clamp(newDist, oldDist, 10000000f); - // __instance.farClipPlane = newDist; - // __instance.farCameraDistance = newDist; - // __instance.mainCamera.farClipPlane = newDist; + if (Main.SystemDict.TryGetValue(Main.Instance.CurrentStarSystem, out var system) && system?.Config?.farClipPlaneOverride != 0f) + { + __instance.farClipPlane = system.Config.farClipPlaneOverride; + __instance.farCameraDistance = system.Config.farClipPlaneOverride; + __instance.mainCamera.farClipPlane = system.Config.farClipPlaneOverride; + } } - - // [HarmonyPrefix] - // [HarmonyPatch(typeof(OWCamera), nameof(OWCamera.RebuildSkybox))] - // public static bool OnOWCameraRebuildSkybox(OWCamera __instance) - // { - // __instance._skyboxCommandBuffer = new CommandBuffer(); - // __instance._skyboxCommandBuffer.name = "Skybox"; - // var camera = __instance._useFarCamera && !SystemInfo.usesReversedZBuffer ? __instance._farCamera : __instance._mainCamera; - // CameraEvent evt = CameraEvent.BeforeSkybox; - // camera.AddCommandBuffer(evt, __instance._skyboxCommandBuffer); - // return false; - // } } } From 7c54d20d63cda45965388e51eb85f61cf44ea24d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 11 Sep 2022 00:02:09 +0000 Subject: [PATCH 2/7] Updated Schemas --- NewHorizons/Schemas/star_system_schema.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NewHorizons/Schemas/star_system_schema.json b/NewHorizons/Schemas/star_system_schema.json index 032fb8f1..f1f8785e 100644 --- a/NewHorizons/Schemas/star_system_schema.json +++ b/NewHorizons/Schemas/star_system_schema.json @@ -5,6 +5,11 @@ "description": "Configuration for a specific star system", "additionalProperties": false, "properties": { + "farClipPlaneOverride": { + "type": "number", + "description": "An override value for the far clip plane. Allows you to see farther.", + "format": "float" + }, "canEnterViaWarpDrive": { "type": "boolean", "description": "Whether this system can be warped to via the warp drive. If you set factRequiredForWarp, this will be true.", From a31c62ba37f26d28285b9e91d140f664e3c90678 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Sat, 3 Sep 2022 23:00:00 -0400 Subject: [PATCH 3/7] Fix credits --- NewHorizons/Handlers/CreditsHandler.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/NewHorizons/Handlers/CreditsHandler.cs b/NewHorizons/Handlers/CreditsHandler.cs index 9d7e7405..f71a73ef 100644 --- a/NewHorizons/Handlers/CreditsHandler.cs +++ b/NewHorizons/Handlers/CreditsHandler.cs @@ -39,7 +39,7 @@ namespace NewHorizons.Handlers private static void AddCreditsSection(string sectionName, string[] entries, ref XmlDocument xml) { - var finalCredits = xml.SelectSingleNode("Credits/section"); + var finalCredits = xml.SelectSingleNode("Credits/section[@name='CreditsFinal']"); /* * Looks bad, would need more customization, complicated, messes up music timing, wont do for now @@ -134,11 +134,8 @@ namespace NewHorizons.Handlers { var rootSection = MakeNode(doc, "section", new Dictionary() { - { "platform", "All" }, - { "type", "Scroll" }, - { "scrollDuration", "214" }, - { "spacing", "12" }, - { "width", "1590" } + { "name", "Custom" }, + { "credits-type", "Final Fast Krazy" } }); var titleLayout = MakeNode(doc, "layout", new Dictionary() From d3e44d0e690e2540352c50d0cc8491aacbf7f0b7 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 13 Sep 2022 19:06:50 -0400 Subject: [PATCH 4/7] Add locks to async image loading, count how many have loaded, fix error log --- .../Builder/Props/ProjectionBuilder.cs | 8 +- NewHorizons/Utility/ImageUtilities.cs | 83 ++++++++++++------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index f6cb399d..fc14a3f0 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -95,7 +95,7 @@ namespace NewHorizons.Builder.Props var slide = new Slide(); var slideInfo = info.slides[i]; - imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); + imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide, mod); @@ -197,7 +197,7 @@ namespace NewHorizons.Builder.Props var slide = new Slide(); var slideInfo = info.slides[i]; - imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); + imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide, mod); @@ -263,7 +263,7 @@ namespace NewHorizons.Builder.Props var slide = new Slide(); var slideInfo = slides[i]; - imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); + imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide, mod); @@ -336,7 +336,7 @@ namespace NewHorizons.Builder.Props var slide = new Slide(); var slideInfo = slides[i]; - imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); + imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide, mod); diff --git a/NewHorizons/Utility/ImageUtilities.cs b/NewHorizons/Utility/ImageUtilities.cs index e875341f..fa8cd7d2 100644 --- a/NewHorizons/Utility/ImageUtilities.cs +++ b/NewHorizons/Utility/ImageUtilities.cs @@ -3,10 +3,10 @@ using System; using System.Collections; using System.Collections.Generic; using System.IO; +using System.Linq; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; -using UnityEngine.UIElements; namespace NewHorizons.Utility { @@ -128,7 +128,7 @@ namespace NewHorizons.Utility var texture = (new Texture2D(size * 4, size * 4, TextureFormat.ARGB32, false)); texture.name = "SlideReelAtlas"; - Color[] fillPixels = new Color[size * size * 4 * 4]; + var fillPixels = new Color[size * size * 4 * 4]; for (int xIndex = 0; xIndex < 4; xIndex++) { for (int yIndex = 0; yIndex < 4; yIndex++) @@ -276,8 +276,8 @@ namespace NewHorizons.Utility { var tex = (new Texture2D(1, 1, TextureFormat.ARGB32, false)); tex.name = "Clear"; - Color fillColor = Color.clear; - Color[] fillPixels = new Color[tex.width * tex.height]; + var fillColor = Color.clear; + var fillPixels = new Color[tex.width * tex.height]; for (int i = 0; i < fillPixels.Length; i++) { fillPixels[i] = fillColor; @@ -296,7 +296,7 @@ namespace NewHorizons.Utility { var tex = (new Texture2D(width, height, TextureFormat.ARGB32, false)); tex.name = src.name + "CanvasScaled"; - Color[] fillPixels = new Color[tex.width * tex.height]; + var fillPixels = new Color[tex.width * tex.height]; for (int i = 0; i < tex.width; i++) { for (int j = 0; j < tex.height; j++) @@ -339,14 +339,14 @@ namespace NewHorizons.Utility } public static Texture2D MakeSolidColorTexture(int width, int height, Color color) { - Color[] pixels = new Color[width*height]; + var pixels = new Color[width*height]; for(int i = 0; i < pixels.Length; i++) { pixels[i] = color; } - Texture2D newTexture = new Texture2D(width, height); + var newTexture = new Texture2D(width, height); newTexture.SetPixels(pixels); newTexture.Apply(); return newTexture; @@ -364,10 +364,15 @@ namespace NewHorizons.Utility // Modified from https://stackoverflow.com/a/69141085/9643841 public class AsyncImageLoader : MonoBehaviour { - public List pathsToLoad = new List(); + public List PathsToLoad { get; private set; } = new (); public class ImageLoadedEvent : UnityEvent { } - public ImageLoadedEvent imageLoadedEvent = new ImageLoadedEvent(); + public ImageLoadedEvent imageLoadedEvent = new (); + + private readonly object _lockObj = new(); + + public bool FinishedLoading { get; private set; } + private int _loadedCount = 0; // TODO: set up an optional “StartLoading” and “StartUnloading” condition on AsyncTextureLoader, // and make use of that for at least for projector stuff (require player to be in the same sector as the slides @@ -375,39 +380,59 @@ namespace NewHorizons.Utility void Start() { - for (int i = 0; i < pathsToLoad.Count; i++) + imageLoadedEvent.AddListener(OnImageLoaded); + for (int i = 0; i < PathsToLoad.Count; i++) { - StartCoroutine(DownloadTexture(pathsToLoad[i], i)); + StartCoroutine(DownloadTexture(PathsToLoad[i], i)); + } + } + + private void OnImageLoaded(Texture texture, int index) + { + lock (_lockObj) + { + _loadedCount++; + + if (_loadedCount >= PathsToLoad.Count) + { + Logger.LogVerbose($"Finished loading all textures for {gameObject.name} (one was {PathsToLoad.FirstOrDefault()}"); + FinishedLoading = true; + } } } IEnumerator DownloadTexture(string url, int index) { - if (_loadedTextures.ContainsKey(url)) + lock(_loadedTextures) { - Logger.LogVerbose($"Already loaded image at path: {url}"); - var texture = _loadedTextures[url]; - imageLoadedEvent.Invoke(texture, index); - yield break; + if (_loadedTextures.ContainsKey(url)) + { + Logger.LogVerbose($"Already loaded image {index}:{url}"); + var texture = _loadedTextures[url]; + imageLoadedEvent?.Invoke(texture, index); + yield break; + } } - using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url)) + using UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url); + + yield return uwr.SendWebRequest(); + + var hasError = uwr.error != null && uwr.error != ""; + + if (hasError) { - yield return uwr.SendWebRequest(); + Logger.LogError($"Failed to load {index}:{url} - {uwr.error}"); + } + else + { + var texture = DownloadHandlerTexture.GetContent(uwr); - var hasError = uwr.error != null && uwr.error != ""; - - if (hasError) // (uwr.result != UnityWebRequest.Result.Success) + lock(_loadedTextures) { - Debug.Log(uwr.error); - } - else - { - var texture = DownloadHandlerTexture.GetContent(uwr); - if (_loadedTextures.ContainsKey(url)) { - Logger.LogVerbose($"Already loaded image at path: {url}"); + Logger.LogVerbose($"Already loaded image {index}:{url}"); Destroy(texture); texture = _loadedTextures[url]; } @@ -416,7 +441,7 @@ namespace NewHorizons.Utility _loadedTextures.Add(url, texture); } - imageLoadedEvent.Invoke(texture, index); + imageLoadedEvent?.Invoke(texture, index); } } } From 13b714ac889a626872fd6420be6cf9ece40b7bd8 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 13 Sep 2022 19:12:43 -0400 Subject: [PATCH 5/7] Default to black frame if no path supplied for slide --- NewHorizons/Utility/ImageUtilities.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NewHorizons/Utility/ImageUtilities.cs b/NewHorizons/Utility/ImageUtilities.cs index fa8cd7d2..536eeb66 100644 --- a/NewHorizons/Utility/ImageUtilities.cs +++ b/NewHorizons/Utility/ImageUtilities.cs @@ -403,6 +403,12 @@ namespace NewHorizons.Utility IEnumerator DownloadTexture(string url, int index) { + if (string.IsNullOrEmpty(url)) + { + imageLoadedEvent?.Invoke(Texture2D.blackTexture, index); + yield break; + } + lock(_loadedTextures) { if (_loadedTextures.ContainsKey(url)) From 7c183d73335686f2dd77ffdffa0969b355a97d0d Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 13 Sep 2022 19:53:58 -0400 Subject: [PATCH 6/7] Fix up black images --- .../Builder/Props/ProjectionBuilder.cs | 81 ++++++++----------- NewHorizons/Utility/ImageUtilities.cs | 14 ++-- 2 files changed, 37 insertions(+), 58 deletions(-) diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index fc14a3f0..0f001728 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -2,8 +2,10 @@ using NewHorizons.External.Modules; using NewHorizons.Handlers; using NewHorizons.Utility; using OWML.Common; +using OWML.Common.Menus; using System; using System.Collections.Generic; +using System.IO; using UnityEngine; using static NewHorizons.External.Modules.PropModule; using Logger = NewHorizons.Utility.Logger; @@ -89,19 +91,8 @@ namespace NewHorizons.Builder.Props // The base game ones only have 15 slides max var textures = new Texture2D[slidesCount >= 15 ? 15 : slidesCount]; - var imageLoader = slideReelObj.AddComponent(); - for (int i = 0; i < slidesCount; i++) - { - var slide = new Slide(); - var slideInfo = info.slides[i]; + var imageLoader = AddAsyncLoader(slideReelObj, mod, info.slides, ref slideCollection); - imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); - - AddModules(slideInfo, ref slide, mod); - - slideCollection.slides[i] = slide; - } - // this variable just lets us track how many of the first 15 slides have been loaded. // this way as soon as the last one is loaded (due to async loading, this may be // slide 7, or slide 3, or whatever), we can build the slide reel texture. This allows us @@ -191,18 +182,7 @@ namespace NewHorizons.Builder.Props int slidesCount = info.slides.Length; var slideCollection = new SlideCollection(slidesCount); - var imageLoader = projectorObj.AddComponent(); - for (int i = 0; i < slidesCount; i++) - { - var slide = new Slide(); - var slideInfo = info.slides[i]; - - imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); - - AddModules(slideInfo, ref slide, mod); - - slideCollection.slides[i] = slide; - } + var imageLoader = AddAsyncLoader(projectorObj, mod, info.slides, ref slideCollection); imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index]._image = ImageUtilities.Invert(tex); }); slideCollectionContainer.slideCollection = slideCollection; @@ -256,19 +236,7 @@ namespace NewHorizons.Builder.Props var slidesCount = slides.Length; var slideCollection = new SlideCollection(slidesCount); - - var imageLoader = g.AddComponent(); - for (int i = 0; i < slidesCount; i++) - { - var slide = new Slide(); - var slideInfo = slides[i]; - - imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); - - AddModules(slideInfo, ref slide, mod); - - slideCollection.slides[i] = slide; - } + var imageLoader = AddAsyncLoader(g, mod, info.slides, ref slideCollection); imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index]._image = tex; }); // attach a component to store all the data for the slides that play when a vision torch scans this target @@ -330,19 +298,8 @@ namespace NewHorizons.Builder.Props var slidesCount = slides.Length; var slideCollection = new SlideCollection(slidesCount); - var imageLoader = standingTorch.AddComponent(); - for (int i = 0; i < slidesCount; i++) - { - var slide = new Slide(); - var slideInfo = slides[i]; + var imageLoader = AddAsyncLoader(standingTorch, mod, slides, ref slideCollection); - imageLoader.PathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); - - AddModules(slideInfo, ref slide, mod); - - slideCollection.slides[i] = slide; - } - // This variable just lets us track how many of the slides have been loaded. // This way as soon as the last one is loaded (due to async loading, this may be // slide 7, or slide 3, or whatever), we can enable the vision torch. This allows us @@ -378,6 +335,32 @@ namespace NewHorizons.Builder.Props return standingTorch; } + private static ImageUtilities.AsyncImageLoader AddAsyncLoader(GameObject gameObject, IModBehaviour mod, SlideInfo[] slides, ref SlideCollection slideCollection) + { + var imageLoader = gameObject.AddComponent(); + for (int i = 0; i < slides.Length; i++) + { + var slide = new Slide(); + var slideInfo = slides[i]; + + if (string.IsNullOrEmpty(slideInfo.imagePath)) + { + imageLoader.imageLoadedEvent?.Invoke(Texture2D.blackTexture, i); + } + else + { + // Don't use Path.Combine here else you break the Vision + imageLoader.PathsToLoad.Add((i, mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath)); + } + + AddModules(slideInfo, ref slide, mod); + + slideCollection.slides[i] = slide; + } + + return imageLoader; + } + private static void AddModules(PropModule.SlideInfo slideInfo, ref Slide slide, IModBehaviour mod) { var modules = new List(); diff --git a/NewHorizons/Utility/ImageUtilities.cs b/NewHorizons/Utility/ImageUtilities.cs index 536eeb66..1f6ae9d8 100644 --- a/NewHorizons/Utility/ImageUtilities.cs +++ b/NewHorizons/Utility/ImageUtilities.cs @@ -1,9 +1,11 @@ using OWML.Common; +using OWML.ModHelper; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Security.Policy; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; @@ -364,7 +366,7 @@ namespace NewHorizons.Utility // Modified from https://stackoverflow.com/a/69141085/9643841 public class AsyncImageLoader : MonoBehaviour { - public List PathsToLoad { get; private set; } = new (); + public List<(int index, string path)> PathsToLoad { get; private set; } = new (); public class ImageLoadedEvent : UnityEvent { } public ImageLoadedEvent imageLoadedEvent = new (); @@ -381,9 +383,9 @@ namespace NewHorizons.Utility void Start() { imageLoadedEvent.AddListener(OnImageLoaded); - for (int i = 0; i < PathsToLoad.Count; i++) + foreach (var (index, path) in PathsToLoad) { - StartCoroutine(DownloadTexture(PathsToLoad[i], i)); + StartCoroutine(DownloadTexture(path, index)); } } @@ -403,12 +405,6 @@ namespace NewHorizons.Utility IEnumerator DownloadTexture(string url, int index) { - if (string.IsNullOrEmpty(url)) - { - imageLoadedEvent?.Invoke(Texture2D.blackTexture, index); - yield break; - } - lock(_loadedTextures) { if (_loadedTextures.ContainsKey(url)) From 86957f2116b11b5dc233c5b075277d8079870e90 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 13 Sep 2022 20:00:08 -0400 Subject: [PATCH 7/7] Ok john --- NewHorizons/Patches/MapControllerPatches.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Patches/MapControllerPatches.cs b/NewHorizons/Patches/MapControllerPatches.cs index dd53f603..3c13673e 100644 --- a/NewHorizons/Patches/MapControllerPatches.cs +++ b/NewHorizons/Patches/MapControllerPatches.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using UnityEngine; using UnityEngine.SceneManagement; namespace NewHorizons.Patches @@ -10,11 +11,11 @@ namespace NewHorizons.Patches [HarmonyPatch(typeof(MapController), nameof(MapController.Awake))] public static void MapController_Awake(MapController __instance) { - __instance._maxPanDistance = Main.FurthestOrbit * 1.5f; + __instance._maxPanDistance = Mathf.Max(__instance._maxPanDistance, Main.FurthestOrbit * 1.5f); __instance._maxZoomDistance *= 6f; __instance._minPitchAngle = -90f; __instance._zoomSpeed *= 4f; - __instance._mapCamera.farClipPlane = Main.FurthestOrbit * 10f; + __instance._mapCamera.farClipPlane = Mathf.Max(__instance._mapCamera.farClipPlane, Main.FurthestOrbit * 10f); } [HarmonyPostfix]