mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Make slide reels work on ship log projector
This commit is contained in:
parent
25fd6cd761
commit
daef166a39
@ -140,8 +140,6 @@ namespace NewHorizons.Builder.Props
|
|||||||
|
|
||||||
var toDestroy = slideReelObj.GetComponent<SlideCollectionContainer>();
|
var toDestroy = slideReelObj.GetComponent<SlideCollectionContainer>();
|
||||||
var slideCollectionContainer = slideReelObj.AddComponent<NHSlideCollectionContainer>();
|
var slideCollectionContainer = slideReelObj.AddComponent<NHSlideCollectionContainer>();
|
||||||
slideCollectionContainer.slidePaths = info.slides.Select(x => x.imagePath).ToArray();
|
|
||||||
slideCollectionContainer.mod = mod;
|
|
||||||
slideReel._slideCollectionContainer = slideCollectionContainer;
|
slideReel._slideCollectionContainer = slideCollectionContainer;
|
||||||
Component.DestroyImmediate(toDestroy);
|
Component.DestroyImmediate(toDestroy);
|
||||||
|
|
||||||
@ -152,7 +150,7 @@ namespace NewHorizons.Builder.Props
|
|||||||
|
|
||||||
// Now we replace the slides
|
// Now we replace the slides
|
||||||
int slidesCount = info.slides.Length;
|
int slidesCount = info.slides.Length;
|
||||||
var slideCollection = new SlideCollection(slidesCount);
|
SlideCollection slideCollection = new NHSlideCollection(slidesCount, mod, info.slides.Select(x => x.imagePath).ToArray());
|
||||||
slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null
|
slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null
|
||||||
|
|
||||||
// We can fit 16 slides max into an atlas
|
// We can fit 16 slides max into an atlas
|
||||||
|
|||||||
@ -1,16 +1,31 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using NewHorizons.Builder.Props;
|
||||||
|
using NewHorizons.Utility;
|
||||||
using NewHorizons.Utility.Files;
|
using NewHorizons.Utility.Files;
|
||||||
|
using NewHorizons.Utility.OWML;
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
namespace NewHorizons.Components.EOTE;
|
namespace NewHorizons.Components.EOTE;
|
||||||
|
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
public class NHSlideCollection : SlideCollection
|
public class NHSlideCollection : SlideCollection
|
||||||
{
|
{
|
||||||
|
|
||||||
public string[] slidePaths;
|
public string[] slidePaths;
|
||||||
public IModBehaviour mod;
|
public IModBehaviour mod;
|
||||||
|
private HashSet<string> _pathsBeingLoaded = new();
|
||||||
|
public static Dictionary<string, HashSet<NHSlideCollection>> _slidesRequiringPath = new();
|
||||||
|
|
||||||
|
private ShipLogSlideProjector _shipLogSlideProjector;
|
||||||
|
|
||||||
|
static NHSlideCollection()
|
||||||
|
{
|
||||||
|
SceneManager.sceneUnloaded += (_) => _slidesRequiringPath.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public NHSlideCollection(int startArrSize, IModBehaviour mod, string[] slidePaths) : base(startArrSize)
|
public NHSlideCollection(int startArrSize, IModBehaviour mod, string[] slidePaths) : base(startArrSize)
|
||||||
{
|
{
|
||||||
@ -18,7 +33,6 @@ public class NHSlideCollection : SlideCollection
|
|||||||
this.slidePaths = slidePaths;
|
this.slidePaths = slidePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(SlideCollection), nameof(SlideCollection.RequestStreamSlides))]
|
[HarmonyPatch(typeof(SlideCollection), nameof(SlideCollection.RequestStreamSlides))]
|
||||||
public static bool SlideCollection_RequestStreamSlides(SlideCollection __instance, int[] slideIndices)
|
public static bool SlideCollection_RequestStreamSlides(SlideCollection __instance, int[] slideIndices)
|
||||||
@ -27,7 +41,25 @@ public class NHSlideCollection : SlideCollection
|
|||||||
{
|
{
|
||||||
foreach (var id in slideIndices)
|
foreach (var id in slideIndices)
|
||||||
{
|
{
|
||||||
collection.slides[id]._image = ImageUtilities.GetTexture(collection.mod, collection.slidePaths[id]);
|
collection.LoadSlide(id);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(SlideCollection), nameof(SlideCollection.RequestRelease))]
|
||||||
|
public static bool SlideCollection_RequestRelease(SlideCollection __instance, int[] slideIndices)
|
||||||
|
{
|
||||||
|
if (__instance is NHSlideCollection collection)
|
||||||
|
{
|
||||||
|
foreach (var id in slideIndices)
|
||||||
|
{
|
||||||
|
collection.UnloadSlide(id);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -43,7 +75,7 @@ public class NHSlideCollection : SlideCollection
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollection collection)
|
if (__instance is NHSlideCollection collection)
|
||||||
{
|
{
|
||||||
__result = ImageUtilities.IsTextureLoaded(collection.mod, collection.slidePaths[streamIdx]);
|
__result = collection.IsSlideLoaded(streamIdx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -58,7 +90,7 @@ public class NHSlideCollection : SlideCollection
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollection collection)
|
if (__instance is NHSlideCollection collection)
|
||||||
{
|
{
|
||||||
__result = ImageUtilities.GetTexture(collection.mod, collection.slidePaths[id]);
|
__result = collection.LoadSlide(id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -66,5 +98,97 @@ public class NHSlideCollection : SlideCollection
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
public Texture LoadSlide(int index)
|
||||||
|
{
|
||||||
|
Texture LoadSlideInt(int index)
|
||||||
|
{
|
||||||
|
var wrappedIndex = (index + slides.Length) % slides.Length;
|
||||||
|
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.InvertedSlideReelCacheFolder, slidePaths[wrappedIndex]);
|
||||||
|
|
||||||
|
// We are the first slide collection container to try and load this image
|
||||||
|
var key = ImageUtilities.GetKey(mod, path);
|
||||||
|
if (!_slidesRequiringPath.ContainsKey(key))
|
||||||
|
{
|
||||||
|
// Something else has loaded this image i.e., AutoProjector or Vision torch. We want to ensure we do not delete it
|
||||||
|
if (ImageUtilities.IsTextureLoaded(mod, path))
|
||||||
|
{
|
||||||
|
_slidesRequiringPath[key] = new() { null };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_slidesRequiringPath[key] = new();
|
||||||
|
}
|
||||||
|
_slidesRequiringPath[key].Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImageUtilities.IsTextureLoaded(mod, path))
|
||||||
|
{
|
||||||
|
var texture = ImageUtilities.GetTexture(mod, path);
|
||||||
|
slides[wrappedIndex]._image = texture;
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
else if (!_pathsBeingLoaded.Contains(path))
|
||||||
|
{
|
||||||
|
var loader = new SlideReelAsyncImageLoader();
|
||||||
|
loader.PathsToLoad.Add((wrappedIndex, path));
|
||||||
|
loader.Start(true, false);
|
||||||
|
loader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) =>
|
||||||
|
{
|
||||||
|
slides[wrappedIndex]._image = tex;
|
||||||
|
_pathsBeingLoaded.Remove(path);
|
||||||
|
if (_shipLogSlideProjector == null)
|
||||||
|
{
|
||||||
|
_shipLogSlideProjector = GameObject.FindObjectOfType<ShipLogSlideProjector>();
|
||||||
|
}
|
||||||
|
if (_shipLogSlideProjector != null)
|
||||||
|
{
|
||||||
|
_shipLogSlideProjector._slideDirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NHLogger.LogVerbose("No ship log slide reel projector exists");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_pathsBeingLoaded.Add(path);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// It is being loaded so we just wait
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var texture = LoadSlideInt(index);
|
||||||
|
LoadSlideInt(index - 1);
|
||||||
|
LoadSlideInt(index + 1);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSlideLoaded(int index)
|
||||||
|
{
|
||||||
|
var wrappedIndex = (index + slides.Length) % slides.Length;
|
||||||
|
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.InvertedSlideReelCacheFolder, slidePaths[wrappedIndex]);
|
||||||
|
return ImageUtilities.IsTextureLoaded(mod, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnloadSlide(int index)
|
||||||
|
{
|
||||||
|
var wrappedIndex = (index + slides.Length) % slides.Length;
|
||||||
|
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.InvertedSlideReelCacheFolder, slidePaths[wrappedIndex]);
|
||||||
|
|
||||||
|
// Only unload textures that we were the ones to load in
|
||||||
|
if (ImageUtilities.IsTextureLoaded(mod, path))
|
||||||
|
{
|
||||||
|
var key = ImageUtilities.GetKey(mod, path);
|
||||||
|
_slidesRequiringPath[key].Remove(this);
|
||||||
|
if (!_slidesRequiringPath[key].Any())
|
||||||
|
{
|
||||||
|
NHLogger.LogVerbose($"Slide reel deleting {key} since nobody is using it anymore");
|
||||||
|
ImageUtilities.DeleteTexture(mod, path, ImageUtilities.GetTexture(mod, path));
|
||||||
|
slides[wrappedIndex]._image = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,7 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using NewHorizons.Builder.Props;
|
|
||||||
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
|
||||||
using NewHorizons.Utility.Files;
|
|
||||||
using NewHorizons.Utility.OWML;
|
|
||||||
using OWML.Common;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
|
|
||||||
namespace NewHorizons.Components.EOTE;
|
namespace NewHorizons.Components.EOTE;
|
||||||
|
|
||||||
@ -18,16 +10,6 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
{
|
{
|
||||||
public string[] conditionsToSet;
|
public string[] conditionsToSet;
|
||||||
public string[] persistentConditionsToSet;
|
public string[] persistentConditionsToSet;
|
||||||
public string[] slidePaths;
|
|
||||||
public IModBehaviour mod;
|
|
||||||
|
|
||||||
private HashSet<string> _pathsBeingLoaded = new();
|
|
||||||
|
|
||||||
public static Dictionary<string, HashSet<NHSlideCollectionContainer>> _slidesRequiringPath = new();
|
|
||||||
static NHSlideCollectionContainer()
|
|
||||||
{
|
|
||||||
SceneManager.sceneUnloaded += (_) => _slidesRequiringPath.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(SlideCollectionContainer), nameof(SlideCollectionContainer.Initialize))]
|
[HarmonyPatch(typeof(SlideCollectionContainer), nameof(SlideCollectionContainer.Initialize))]
|
||||||
@ -87,7 +69,7 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollectionContainer container)
|
if (__instance is NHSlideCollectionContainer container)
|
||||||
{
|
{
|
||||||
__result = container.IsSlideLoaded(container.slideIndex + 1);
|
__result = (container.slideCollection as NHSlideCollection).IsSlideLoaded(container.slideIndex + 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -103,7 +85,7 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollectionContainer container)
|
if (__instance is NHSlideCollectionContainer container)
|
||||||
{
|
{
|
||||||
__result = container.IsSlideLoaded(container.slideIndex - 1);
|
__result = (container.slideCollection as NHSlideCollection).IsSlideLoaded(container.slideIndex - 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -118,9 +100,9 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollectionContainer container)
|
if (__instance is NHSlideCollectionContainer container)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < container.slidePaths.Length; i++)
|
for (int i = 0; i < (container.slideCollection as NHSlideCollection).slidePaths.Length; i++)
|
||||||
{
|
{
|
||||||
container.UnloadSlide(i);
|
(container.slideCollection as NHSlideCollection).UnloadSlide(i);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -136,7 +118,7 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollectionContainer container)
|
if (__instance is NHSlideCollectionContainer container)
|
||||||
{
|
{
|
||||||
__result = container.LoadSlide(id);
|
__result = (container.slideCollection as NHSlideCollection).LoadSlide(id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -151,7 +133,7 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollectionContainer container)
|
if (__instance is NHSlideCollectionContainer container)
|
||||||
{
|
{
|
||||||
container.LoadSlide(__instance._currentSlideIndex);
|
(container.slideCollection as NHSlideCollection).LoadSlide(__instance._currentSlideIndex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -166,7 +148,7 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
{
|
{
|
||||||
if (__instance is NHSlideCollectionContainer container)
|
if (__instance is NHSlideCollectionContainer container)
|
||||||
{
|
{
|
||||||
__result = container.slidePaths != null && container.slidePaths.Any();
|
__result = (container.slideCollection as NHSlideCollection).slidePaths != null && (container.slideCollection as NHSlideCollection).slidePaths.Any();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -174,85 +156,4 @@ public class NHSlideCollectionContainer : SlideCollectionContainer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Texture LoadSlide(int index)
|
|
||||||
{
|
|
||||||
Texture LoadSlideInt(int index)
|
|
||||||
{
|
|
||||||
var wrappedIndex = (index + this.slideCollection.slides.Length) % this.slideCollection.slides.Length;
|
|
||||||
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.InvertedSlideReelCacheFolder, slidePaths[wrappedIndex]);
|
|
||||||
|
|
||||||
// We are the first slide collection container to try and load this image
|
|
||||||
var key = ImageUtilities.GetKey(mod, path);
|
|
||||||
if (!_slidesRequiringPath.ContainsKey(key))
|
|
||||||
{
|
|
||||||
// Something else has loaded this image i.e., AutoProjector or Vision torch. We want to ensure we do not delete it
|
|
||||||
if (ImageUtilities.IsTextureLoaded(mod, path))
|
|
||||||
{
|
|
||||||
_slidesRequiringPath[key] = new() { null };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_slidesRequiringPath[key] = new();
|
|
||||||
}
|
|
||||||
_slidesRequiringPath[key].Add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImageUtilities.IsTextureLoaded(mod, path))
|
|
||||||
{
|
|
||||||
var texture = ImageUtilities.GetTexture(mod, path);
|
|
||||||
this.slideCollection.slides[wrappedIndex]._image = texture;
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
else if (!_pathsBeingLoaded.Contains(path))
|
|
||||||
{
|
|
||||||
var loader = new SlideReelAsyncImageLoader();
|
|
||||||
loader.PathsToLoad.Add((wrappedIndex, path));
|
|
||||||
loader.Start(true, false);
|
|
||||||
loader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) =>
|
|
||||||
{
|
|
||||||
slideCollection.slides[wrappedIndex]._image = tex;
|
|
||||||
_pathsBeingLoaded.Remove(path);
|
|
||||||
});
|
|
||||||
_pathsBeingLoaded.Add(path);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// It is being loaded so we just wait
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var texture = LoadSlideInt(index);
|
|
||||||
LoadSlideInt(index - 1);
|
|
||||||
LoadSlideInt(index + 1);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsSlideLoaded(int index)
|
|
||||||
{
|
|
||||||
var wrappedIndex = (index + this.slideCollection.slides.Length) % this.slideCollection.slides.Length;
|
|
||||||
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.InvertedSlideReelCacheFolder, slidePaths[wrappedIndex]);
|
|
||||||
return ImageUtilities.IsTextureLoaded(mod, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnloadSlide(int index)
|
|
||||||
{
|
|
||||||
var wrappedIndex = (index + this.slideCollection.slides.Length) % this.slideCollection.slides.Length;
|
|
||||||
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.InvertedSlideReelCacheFolder, slidePaths[wrappedIndex]);
|
|
||||||
|
|
||||||
// Only unload textures that we were the ones to load in
|
|
||||||
if (ImageUtilities.IsTextureLoaded(mod, path))
|
|
||||||
{
|
|
||||||
var key = ImageUtilities.GetKey(mod, path);
|
|
||||||
_slidesRequiringPath[key].Remove(this);
|
|
||||||
if (!_slidesRequiringPath[key].Any())
|
|
||||||
{
|
|
||||||
NHLogger.LogVerbose($"Slide reel deleting {key} since nobody is using it anymore");
|
|
||||||
ImageUtilities.DeleteTexture(mod, path, ImageUtilities.GetTexture(mod, path));
|
|
||||||
slideCollection.slides[wrappedIndex]._image = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using NewHorizons.Components.EOTE;
|
||||||
|
|
||||||
|
namespace NewHorizons.Patches.ShipLogPatches;
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
public static class ShipLogSlideReelPatches
|
||||||
|
{
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ShipLogSlideProjector), nameof(ShipLogSlideProjector.CheckStreamingTexturesAvailable))]
|
||||||
|
public static bool ShipLogSlideProjector_CheckStreamingTexturesAvailable(ShipLogSlideProjector __instance, ref bool __result)
|
||||||
|
{
|
||||||
|
if (__instance._collectionIndex >= 0 && __instance._collectionIndex < __instance._slideCollections.Count &&
|
||||||
|
__instance._slideCollections[__instance._collectionIndex] is NHSlideCollection)
|
||||||
|
{
|
||||||
|
__result = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user