mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Merge branch 'dev' into enum
This commit is contained in:
commit
0819658e28
@ -1,4 +1,3 @@
|
||||
using NewHorizons.Builder.General;
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.Handlers;
|
||||
@ -80,7 +79,7 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
else FixSectoredComponent(component, sector, isTorch);
|
||||
|
||||
FixComponent(component, go, prefab.name);
|
||||
FixComponent(component, go);
|
||||
}
|
||||
|
||||
prop.transform.position = detail.position == null ? go.transform.position : go.transform.TransformPoint(detail.position);
|
||||
@ -101,7 +100,6 @@ namespace NewHorizons.Builder.Props
|
||||
|
||||
prop.transform.localScale = detail.scale != 0 ? Vector3.one * detail.scale : prefab.transform.localScale;
|
||||
|
||||
if (!detail.keepLoaded) GroupsBuilder.Make(prop, sector);
|
||||
prop.SetActive(true);
|
||||
|
||||
if (prop == null) return null;
|
||||
@ -224,11 +222,11 @@ namespace NewHorizons.Builder.Props
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void FixComponent(Component component, GameObject planetGO, string prefab)
|
||||
private static void FixComponent(Component component, GameObject planetGO)
|
||||
{
|
||||
// Fix other components
|
||||
// I forget why this is here
|
||||
if (component is GhostIK || component is GhostEffects)
|
||||
if (component is GhostIK or GhostEffects)
|
||||
{
|
||||
Component.DestroyImmediate(component);
|
||||
return;
|
||||
@ -280,27 +278,40 @@ namespace NewHorizons.Builder.Props
|
||||
torchItem.mindSlideProjector._mindProjectorImageEffect = SearchUtilities.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
|
||||
}
|
||||
|
||||
// Fix a bunch of stuff when done loading
|
||||
Delay.RunWhen(() => Main.IsSystemReady, () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (component == null) return;
|
||||
if (component is Animator animator) animator.enabled = true;
|
||||
else if (component is Collider collider) collider.enabled = true;
|
||||
else if (component is Renderer renderer) renderer.enabled = true;
|
||||
else if (component is Shape shape) shape.enabled = true;
|
||||
else if (component is SectorCullGroup sectorCullGroup)
|
||||
if (component is Collider collider) collider.enabled = true;
|
||||
if (component is Renderer renderer) renderer.enabled = true;
|
||||
if (component is Shape shape) shape.enabled = true;
|
||||
|
||||
// fixes sector cull group deactivating renderers on map view enter and fast foward
|
||||
// TODO: does this actually work? what? how?
|
||||
if (component is SectorCullGroup sectorCullGroup)
|
||||
{
|
||||
sectorCullGroup._inMapView = false;
|
||||
sectorCullGroup._isFastForwarding = false;
|
||||
sectorCullGroup.SetVisible(sectorCullGroup.ShouldBeVisible(), true, false);
|
||||
}
|
||||
|
||||
// If it's not a moving anglerfish make sure the anim controller is regular
|
||||
else if (component is AnglerfishAnimController angler && angler.GetComponentInParent<AnglerfishController>() == null)
|
||||
if (component is AnglerfishAnimController && component.GetComponentInParent<AnglerfishController>() == null)
|
||||
component.gameObject.AddComponent<AnglerAnimFixer>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Has to happen after AnglerfishAnimController awake to remove the events it has set up.
|
||||
/// Otherwise results in the anglerfish 1) having its animations controlled by an actual fish 2) randomly having different animations on solarsystem load
|
||||
/// Can't do delay because it needs to work with scatter (copies a prefab made using MakeDetail).
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(AnglerfishAnimController))]
|
||||
private class AnglerAnimFixer : MonoBehaviour
|
||||
{
|
||||
Logger.LogVerbose("Enabling anglerfish animation");
|
||||
// Remove any reference to its angler
|
||||
private void Start()
|
||||
{
|
||||
var angler = GetComponent<AnglerfishAnimController>();
|
||||
|
||||
Logger.LogVerbose("Fixing anglerfish animation");
|
||||
|
||||
// Remove any event reference to its angler
|
||||
if (angler._anglerfishController)
|
||||
{
|
||||
angler._anglerfishController.OnChangeAnglerState -= angler.OnChangeAnglerState;
|
||||
@ -310,13 +321,9 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
angler.enabled = true;
|
||||
angler.OnChangeAnglerState(AnglerfishController.AnglerState.Lurking);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogWarning($"Exception when modifying component [{component.GetType().Name}] on [{planetGO.name}] for prop [{prefab}]:\n{e}");
|
||||
}
|
||||
});
|
||||
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,9 +4,11 @@ using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using static NewHorizons.External.Modules.PropModule;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
|
||||
namespace NewHorizons.Builder.Props
|
||||
{
|
||||
public static class ProjectionBuilder
|
||||
@ -89,18 +91,7 @@ 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<ImageUtilities.AsyncImageLoader>();
|
||||
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(slideReelObj, mod, info.slides, ref slideCollection);
|
||||
|
||||
// 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
|
||||
@ -113,13 +104,10 @@ namespace NewHorizons.Builder.Props
|
||||
slideCollection.slides[index]._image = ImageUtilities.Invert(tex);
|
||||
|
||||
// Track the first 15 to put on the slide reel object
|
||||
if (index < 15)
|
||||
if (index < textures.Length)
|
||||
{
|
||||
textures[index] = tex;
|
||||
displaySlidesLoaded++; // threading moment
|
||||
}
|
||||
|
||||
if (displaySlidesLoaded >= textures.Length)
|
||||
if (Interlocked.Increment(ref displaySlidesLoaded) == textures.Length)
|
||||
{
|
||||
// all textures required to build the reel's textures have been loaded
|
||||
var slidesBack = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Back").GetComponent<MeshRenderer>();
|
||||
@ -133,6 +121,7 @@ namespace NewHorizons.Builder.Props
|
||||
slidesFront.material.SetTexture(EmissionMap, reelTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Else when you put them down you can't pick them back up
|
||||
@ -191,18 +180,7 @@ namespace NewHorizons.Builder.Props
|
||||
int slidesCount = info.slides.Length;
|
||||
var slideCollection = new SlideCollection(slidesCount);
|
||||
|
||||
var imageLoader = projectorObj.AddComponent<ImageUtilities.AsyncImageLoader>();
|
||||
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 +234,7 @@ namespace NewHorizons.Builder.Props
|
||||
var slidesCount = slides.Length;
|
||||
var slideCollection = new SlideCollection(slidesCount);
|
||||
|
||||
|
||||
var imageLoader = g.AddComponent<ImageUtilities.AsyncImageLoader>();
|
||||
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,18 +296,7 @@ namespace NewHorizons.Builder.Props
|
||||
var slidesCount = slides.Length;
|
||||
var slideCollection = new SlideCollection(slidesCount);
|
||||
|
||||
var imageLoader = standingTorch.AddComponent<ImageUtilities.AsyncImageLoader>();
|
||||
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(standingTorch, mod, slides, ref slideCollection);
|
||||
|
||||
// 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
|
||||
@ -352,9 +307,8 @@ namespace NewHorizons.Builder.Props
|
||||
(Texture2D tex, int index) =>
|
||||
{
|
||||
slideCollection.slides[index]._image = tex;
|
||||
displaySlidesLoaded++; // threading moment
|
||||
|
||||
if (displaySlidesLoaded >= slides.Length)
|
||||
if (Interlocked.Increment(ref displaySlidesLoaded) == slides.Length)
|
||||
{
|
||||
mindSlideProjector.enabled = true;
|
||||
visionBeamEffect.SetActive(true);
|
||||
@ -378,6 +332,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<ImageUtilities.AsyncImageLoader>();
|
||||
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<SlideFunctionModule>();
|
||||
|
||||
@ -3,6 +3,8 @@ using NewHorizons.External.Modules;
|
||||
using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
using Random = UnityEngine.Random;
|
||||
@ -19,13 +21,20 @@ namespace NewHorizons.Builder.Props
|
||||
{
|
||||
var heightMap = config.HeightMap;
|
||||
|
||||
var makeFibonacciSphere = scatterInfo.Any(x => x.preventOverlap);
|
||||
|
||||
List<Vector3> points = new();
|
||||
|
||||
if (makeFibonacciSphere)
|
||||
{
|
||||
var area = 4f * Mathf.PI * radius * radius;
|
||||
|
||||
// To not use more than 0.5GB of RAM while doing this
|
||||
// Works up to planets with 575 radius before capping
|
||||
var numPoints = Math.Min((int)(area * 10), 41666666);
|
||||
|
||||
var points = RandomUtility.FibonacciSphere(numPoints);
|
||||
points = RandomUtility.FibonacciSphere(numPoints);
|
||||
}
|
||||
|
||||
Texture2D heightMapTexture = null;
|
||||
if (heightMap != null)
|
||||
@ -55,13 +64,29 @@ namespace NewHorizons.Builder.Props
|
||||
GameObject prefab;
|
||||
if (propInfo.assetBundle != null) prefab = AssetBundleUtilities.LoadPrefab(propInfo.assetBundle, propInfo.path, mod);
|
||||
else prefab = SearchUtilities.Find(propInfo.path);
|
||||
|
||||
// Run all the make detail stuff on it early and just copy it over and over instead
|
||||
var detailInfo = new PropModule.DetailInfo()
|
||||
{
|
||||
scale = propInfo.scale,
|
||||
keepLoaded = propInfo.keepLoaded
|
||||
};
|
||||
var scatterPrefab = DetailBuilder.Make(go, sector, prefab, detailInfo);
|
||||
|
||||
for (int i = 0; i < propInfo.count; i++)
|
||||
{
|
||||
// Failsafe
|
||||
Vector3 point;
|
||||
if (propInfo.preventOverlap)
|
||||
{
|
||||
if (points.Count == 0) break;
|
||||
|
||||
var randomInd = (int)Random.Range(0, points.Count - 1);
|
||||
var point = points[randomInd];
|
||||
var randomInd = Random.Range(0, points.Count - 1);
|
||||
point = points[randomInd];
|
||||
points.QuickRemoveAt(randomInd);
|
||||
}
|
||||
else
|
||||
{
|
||||
point = Random.onUnitSphere;
|
||||
}
|
||||
|
||||
var height = radius;
|
||||
if (heightMapTexture != null)
|
||||
@ -92,14 +117,11 @@ namespace NewHorizons.Builder.Props
|
||||
point = Quaternion.Euler(90, 0, 0) * point;
|
||||
}
|
||||
|
||||
var detailInfo = new PropModule.DetailInfo()
|
||||
{
|
||||
position = point.normalized * height,
|
||||
scale = propInfo.scale,
|
||||
keepLoaded = propInfo.keepLoaded,
|
||||
alignToNormal = true
|
||||
};
|
||||
var prop = DetailBuilder.Make(go, sector, prefab, detailInfo);
|
||||
var prop = scatterPrefab.InstantiateInactive();
|
||||
prop.transform.SetParent(sector?.transform ?? go.transform);
|
||||
prop.transform.localPosition = go.transform.TransformPoint(point * height);
|
||||
var up = go.transform.InverseTransformPoint(prop.transform.position).normalized;
|
||||
prop.transform.rotation = Quaternion.FromToRotation(Vector3.up, up);
|
||||
|
||||
if (propInfo.offset != null) prop.transform.localPosition += prop.transform.TransformVector(propInfo.offset);
|
||||
if (propInfo.rotation != null) prop.transform.rotation *= Quaternion.Euler(propInfo.rotation);
|
||||
@ -107,9 +129,10 @@ namespace NewHorizons.Builder.Props
|
||||
// Rotate around normal
|
||||
prop.transform.localRotation *= Quaternion.AngleAxis(Random.Range(0, 360), Vector3.up);
|
||||
|
||||
points.QuickRemoveAt(randomInd);
|
||||
if (points.Count == 0) return;
|
||||
}
|
||||
prop.SetActive(true);
|
||||
}
|
||||
|
||||
GameObject.Destroy(scatterPrefab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,11 @@ namespace NewHorizons.External.Configs
|
||||
[JsonObject]
|
||||
public class StarSystemConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// An override value for the far clip plane. Allows you to see farther.
|
||||
/// </summary>
|
||||
public float farClipPlaneOverride;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this system can be warped to via the warp drive. If you set factRequiredForWarp, this will be true.
|
||||
/// </summary>
|
||||
|
||||
5
NewHorizons/External/Modules/PropModule.cs
vendored
5
NewHorizons/External/Modules/PropModule.cs
vendored
@ -140,6 +140,11 @@ namespace NewHorizons.External.Modules
|
||||
/// </summary>
|
||||
public float? maxHeight;
|
||||
|
||||
/// <summary>
|
||||
/// Should we try to prevent overlap between the scattered details? True by default. If it's affecting load times turn it off.
|
||||
/// </summary>
|
||||
[DefaultValue(true)] public bool preventOverlap = true;
|
||||
|
||||
/// <summary>
|
||||
/// Should this detail stay loaded even if you're outside the sector (good for very large props)
|
||||
/// </summary>
|
||||
|
||||
@ -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<string, string>()
|
||||
{
|
||||
{ "platform", "All" },
|
||||
{ "type", "Scroll" },
|
||||
{ "scrollDuration", "214" },
|
||||
{ "spacing", "12" },
|
||||
{ "width", "1590" }
|
||||
{ "name", "Custom" },
|
||||
{ "credits-type", "Final Fast Krazy" }
|
||||
});
|
||||
|
||||
var titleLayout = MakeNode(doc, "layout", new Dictionary<string, string>()
|
||||
|
||||
@ -122,7 +122,7 @@ namespace NewHorizons
|
||||
_wasConfigured = true;
|
||||
}
|
||||
|
||||
public static void ResetConfigs(bool resetTranslation = true)
|
||||
public void ResetConfigs(bool resetTranslation = true)
|
||||
{
|
||||
BodyDict.Clear();
|
||||
SystemDict.Clear();
|
||||
@ -161,11 +161,15 @@ namespace NewHorizons
|
||||
}
|
||||
};
|
||||
|
||||
if (!resetTranslation) return;
|
||||
if (resetTranslation)
|
||||
{
|
||||
TranslationHandler.ClearTables();
|
||||
TextTranslation.Get().SetLanguage(TextTranslation.Get().GetLanguage());
|
||||
}
|
||||
|
||||
LoadTranslations(Instance.ModHelper.Manifest.ModFolderPath + "Assets/", this);
|
||||
}
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
@ -213,7 +217,6 @@ namespace NewHorizons
|
||||
OnStarSystemLoaded.AddListener(RichPresenceHandler.OnStarSystemLoaded);
|
||||
OnChangeStarSystem.AddListener(RichPresenceHandler.OnChangeStarSystem);
|
||||
|
||||
LoadTranslations(ModHelper.Manifest.ModFolderPath + "Assets/", this);
|
||||
LoadAddonManifest("Assets/addon-manifest.json", this);
|
||||
}
|
||||
|
||||
|
||||
@ -4,9 +4,7 @@ using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using UnityEngine;
|
||||
using static UnityEngine.InputSystem.InputRemoting;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
|
||||
namespace NewHorizons.OtherMods.MenuFramework
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
// [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;
|
||||
// }
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1395,6 +1395,11 @@
|
||||
"description": "The highest height that these objects will be placed at (only relevant if there's a heightmap)",
|
||||
"format": "float"
|
||||
},
|
||||
"preventOverlap": {
|
||||
"type": "boolean",
|
||||
"description": "Should we try to prevent overlap between the scattered details? True by default. If it's affecting load times turn it off.",
|
||||
"default": true
|
||||
},
|
||||
"keepLoaded": {
|
||||
"type": "boolean",
|
||||
"description": "Should this detail stay loaded even if you're outside the sector (good for very large props)"
|
||||
|
||||
@ -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.",
|
||||
|
||||
@ -31,7 +31,7 @@ namespace NewHorizons.Utility.DebugUtilities
|
||||
{
|
||||
Logger.Log("Begin reload of config files...");
|
||||
|
||||
Main.ResetConfigs();
|
||||
Main.Instance.ResetConfigs();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@ -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<string> pathsToLoad = new List<string>();
|
||||
public List<(int index, string path)> PathsToLoad { get; private set; } = new ();
|
||||
|
||||
public class ImageLoadedEvent : UnityEvent<Texture2D, int> { }
|
||||
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);
|
||||
foreach (var (index, path) in PathsToLoad)
|
||||
{
|
||||
StartCoroutine(DownloadTexture(pathsToLoad[i], i));
|
||||
StartCoroutine(DownloadTexture(path, index));
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
lock(_loadedTextures)
|
||||
{
|
||||
if (_loadedTextures.ContainsKey(url))
|
||||
{
|
||||
Logger.LogVerbose($"Already loaded image at path: {url}");
|
||||
Logger.LogVerbose($"Already loaded image {index}:{url}");
|
||||
var texture = _loadedTextures[url];
|
||||
imageLoadedEvent.Invoke(texture, index);
|
||||
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) // (uwr.result != UnityWebRequest.Result.Success)
|
||||
if (hasError)
|
||||
{
|
||||
Debug.Log(uwr.error);
|
||||
Logger.LogError($"Failed to load {index}:{url} - {uwr.error}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var texture = DownloadHandlerTexture.GetContent(uwr);
|
||||
|
||||
lock(_loadedTextures)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user