mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Slide reel conditions + some wyrm things (#984)
## Minor features - Added `persistentConditionsToSet` and `conditionsToSet` to slide reels. Now instead of just revealing ship logs at the end of a slide reel/vision, you can set persistent and dialogue conditions. ## Improvements - Static body shiplogs are now automatically arranged by their distance to the primary (previously only considered semi-major axis) - Will register a planet config as invalid if the planet is listed as its own primary orbital body (nonsense) (fixes #983)
This commit is contained in:
commit
7c3a8096cf
@ -1,4 +1,5 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Components.EOTE;
|
||||
using NewHorizons.External.Modules.Props;
|
||||
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
||||
using NewHorizons.Handlers;
|
||||
@ -137,7 +138,10 @@ namespace NewHorizons.Builder.Props
|
||||
slideReel.SetSector(sector);
|
||||
slideReel.SetVisible(true);
|
||||
|
||||
var slideCollectionContainer = slideReelObj.GetRequiredComponent<SlideCollectionContainer>();
|
||||
var toDestroy = slideReelObj.GetComponent<SlideCollectionContainer>();
|
||||
var slideCollectionContainer = slideReelObj.AddComponent<NHSlideCollectionContainer>();
|
||||
slideReel._slideCollectionContainer = slideCollectionContainer;
|
||||
Component.DestroyImmediate(toDestroy);
|
||||
|
||||
foreach (var renderer in slideReelObj.GetComponentsInChildren<Renderer>())
|
||||
{
|
||||
@ -342,7 +346,10 @@ namespace NewHorizons.Builder.Props
|
||||
var autoProjector = projectorObj.GetComponent<AutoSlideProjector>();
|
||||
autoProjector._sector = sector;
|
||||
|
||||
var slideCollectionContainer = autoProjector.GetRequiredComponent<SlideCollectionContainer>();
|
||||
var toDestroy = autoProjector.GetComponent<SlideCollectionContainer>();
|
||||
var slideCollectionContainer = autoProjector.gameObject.AddComponent<NHSlideCollectionContainer>();
|
||||
autoProjector._slideCollectionItem = slideCollectionContainer;
|
||||
Component.DestroyImmediate(toDestroy);
|
||||
|
||||
// Now we replace the slides
|
||||
int slidesCount = info.slides.Length;
|
||||
@ -419,7 +426,7 @@ namespace NewHorizons.Builder.Props
|
||||
|
||||
// attach a component to store all the data for the slides that play when a vision torch scans this target
|
||||
var target = g.AddComponent<VisionTorchTarget>();
|
||||
var slideCollectionContainer = g.AddComponent<SlideCollectionContainer>();
|
||||
var slideCollectionContainer = g.AddComponent<NHSlideCollectionContainer>();
|
||||
slideCollectionContainer.slideCollection = slideCollection;
|
||||
target.slideCollection = g.AddComponent<MindSlideCollection>();
|
||||
target.slideCollection._slideCollectionContainer = slideCollectionContainer;
|
||||
@ -486,7 +493,7 @@ namespace NewHorizons.Builder.Props
|
||||
);
|
||||
|
||||
// Set up the containers for the slides
|
||||
var slideCollectionContainer = standingTorch.AddComponent<SlideCollectionContainer>();
|
||||
var slideCollectionContainer = standingTorch.AddComponent<NHSlideCollectionContainer>();
|
||||
slideCollectionContainer.slideCollection = slideCollection;
|
||||
|
||||
var mindSlideCollection = standingTorch.AddComponent<MindSlideCollection>();
|
||||
@ -658,12 +665,15 @@ namespace NewHorizons.Builder.Props
|
||||
Slide.WriteModules(modules, ref slide._modulesList, ref slide._modulesData, ref slide.lengths);
|
||||
}
|
||||
|
||||
private static void LinkShipLogFacts(ProjectionInfo info, SlideCollectionContainer slideCollectionContainer)
|
||||
private static void LinkShipLogFacts(ProjectionInfo info, NHSlideCollectionContainer slideCollectionContainer)
|
||||
{
|
||||
// Idk why but it wants reveals to be comma delimited not a list
|
||||
if (info.reveals != null) slideCollectionContainer._shipLogOnComplete = string.Join(",", info.reveals);
|
||||
// Don't use null value, NRE in SlideCollectionContainer.Initialize
|
||||
slideCollectionContainer._playWithShipLogFacts = info.playWithShipLogFacts ?? Array.Empty<string>();
|
||||
|
||||
slideCollectionContainer.conditionsToSet = info.conditionsToSet;
|
||||
slideCollectionContainer.persistentConditionsToSet = info.persistentConditionsToSet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -440,6 +440,11 @@ namespace NewHorizons.Builder.ShipLog
|
||||
|
||||
private static MapModeObject ConstructPrimaryNode(List<NewHorizonsBody> bodies)
|
||||
{
|
||||
float DistanceFromPrimary(NewHorizonsBody body)
|
||||
{
|
||||
return Mathf.Max(body.Config.Orbit.semiMajorAxis, body.Config.Orbit.staticPosition?.Length() ?? 0f);
|
||||
}
|
||||
|
||||
foreach (NewHorizonsBody body in bodies.Where(b => b.Config.Base.centerOfSolarSystem))
|
||||
{
|
||||
bodies.Sort((b, o) => b.Config.Orbit.semiMajorAxis.CompareTo(o.Config.Orbit.semiMajorAxis));
|
||||
|
||||
62
NewHorizons/Components/EOTE/NHSlideCollectionContainer.cs
Normal file
62
NewHorizons/Components/EOTE/NHSlideCollectionContainer.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using HarmonyLib;
|
||||
|
||||
namespace NewHorizons.Components.EOTE;
|
||||
|
||||
[HarmonyPatch(typeof(SlideCollectionContainer))]
|
||||
public class NHSlideCollectionContainer : SlideCollectionContainer
|
||||
{
|
||||
public string[] conditionsToSet;
|
||||
public string[] persistentConditionsToSet;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SlideCollectionContainer), nameof(SlideCollectionContainer.Initialize))]
|
||||
public static bool SlideCollectionContainer_Initialize(SlideCollectionContainer __instance)
|
||||
{
|
||||
if (__instance is NHSlideCollectionContainer)
|
||||
{
|
||||
if (__instance._initialized)
|
||||
return false;
|
||||
__instance.SetupReadFlags();
|
||||
__instance.RegisterPerSlideCompletion();
|
||||
if (__instance.streamingTexturesAvailable)
|
||||
__instance.SetupStreaming();
|
||||
__instance.BuildMusicRangesIndex();
|
||||
__instance._changeSlidesAllowed = true;
|
||||
__instance._initialized = true;
|
||||
__instance._slideCollection.isVision = __instance._owningItem == null;
|
||||
foreach (var factID in __instance._playWithShipLogFacts)
|
||||
{
|
||||
var fact = Locator.GetShipLogManager().GetFact(factID);
|
||||
fact?.RegisterSlideCollection(__instance._slideCollection);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(SlideCollectionContainer), nameof(SlideCollectionContainer.SetReadFlag))]
|
||||
public static void SlideCollectionContainer_SetReadFlag(SlideCollectionContainer __instance)
|
||||
{
|
||||
if (__instance is NHSlideCollectionContainer container)
|
||||
{
|
||||
if (container._unreadSlideIndices.Count == 0)
|
||||
{
|
||||
if (container.conditionsToSet != null)
|
||||
{
|
||||
foreach (var condition in container.conditionsToSet)
|
||||
{
|
||||
DialogueConditionManager.SharedInstance.SetConditionState(condition, true);
|
||||
}
|
||||
}
|
||||
if (container.persistentConditionsToSet != null)
|
||||
{
|
||||
foreach (var condition in container.persistentConditionsToSet)
|
||||
{
|
||||
PlayerData.SetPersistentCondition(condition, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
NewHorizons/External/Configs/PlanetConfig.cs
vendored
8
NewHorizons/External/Configs/PlanetConfig.cs
vendored
@ -287,6 +287,14 @@ namespace NewHorizons.External.Configs
|
||||
|
||||
// Disable map marker for dream dimensions
|
||||
if (Dream != null && Dream.inDreamWorld) MapMarker.enabled = false;
|
||||
|
||||
// User error #983
|
||||
// This will not catch if they wrote the two names slightly differently but oh well don't be stupid
|
||||
// Ideally we should just check for loops in PlanetGraph
|
||||
if (Orbit.primaryBody == name)
|
||||
{
|
||||
throw new Exception($"You set {name} to orbit itself, that is invalid. The planet will not load.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
|
||||
@ -48,6 +48,16 @@ namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
||||
/// </summary>
|
||||
public string[] reveals;
|
||||
|
||||
/// <summary>
|
||||
/// The dialogue conditions to set after finishing this slide reel.
|
||||
/// </summary>
|
||||
public string[] conditionsToSet;
|
||||
|
||||
/// <summary>
|
||||
/// The persistent conditions to set after finishing this slide reel.
|
||||
/// </summary>
|
||||
public string[] persistentConditionsToSet;
|
||||
|
||||
/// <summary>
|
||||
/// The ship log facts that make the reel play when they are displayed in the computer (by selecting entries or arrows).
|
||||
/// You should probably include facts from `reveals` here.
|
||||
|
||||
@ -27,6 +27,8 @@ namespace NewHorizons.External.SerializableData
|
||||
return new Vector3(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public float Length() => Mathf.Sqrt(x * x + y * y + z * z);
|
||||
|
||||
public override string ToString() => $"{x}, {y}, {z}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
using HarmonyLib;
|
||||
|
||||
namespace NewHorizons.Patches.ShipLogPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(SlideCollectionContainer))]
|
||||
public static class SlideCollectionContainerPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SlideCollectionContainer), nameof(SlideCollectionContainer.Initialize))]
|
||||
public static bool SlideCollectionContainer_Initialize(SlideCollectionContainer __instance)
|
||||
{
|
||||
if (__instance._initialized)
|
||||
return false;
|
||||
__instance.SetupReadFlags();
|
||||
__instance.RegisterPerSlideCompletion();
|
||||
if (__instance.streamingTexturesAvailable)
|
||||
__instance.SetupStreaming();
|
||||
__instance.BuildMusicRangesIndex();
|
||||
__instance._changeSlidesAllowed = true;
|
||||
__instance._initialized = true;
|
||||
__instance._slideCollection.isVision = __instance._owningItem == null;
|
||||
foreach (var factID in __instance._playWithShipLogFacts)
|
||||
{
|
||||
var fact = Locator.GetShipLogManager().GetFact(factID);
|
||||
fact?.RegisterSlideCollection(__instance._slideCollection);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2263,6 +2263,20 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"conditionsToSet": {
|
||||
"type": "array",
|
||||
"description": "The dialogue conditions to set after finishing this slide reel.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"persistentConditionsToSet": {
|
||||
"type": "array",
|
||||
"description": "The persistent conditions to set after finishing this slide reel.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"playWithShipLogFacts": {
|
||||
"type": "array",
|
||||
"description": "The ship log facts that make the reel play when they are displayed in the computer (by selecting entries or arrows).\nYou should probably include facts from `reveals` here.\nIf you only specify a rumor fact, then it would only play in its ship log entry if this has revealed only\nrumor facts because an entry with revealed explore facts doesn't display rumor facts.",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user