Merge branch 'dev' into coloured-splashes

This commit is contained in:
xen-42 2024-10-04 22:17:30 -04:00
commit 1ca9b63b64
52 changed files with 1571 additions and 1653 deletions

View File

@ -1,9 +1,9 @@
ManifestFileVersion: 0 ManifestFileVersion: 0
CRC: 2245901288 CRC: 2356174904
Hashes: Hashes:
AssetFileHash: AssetFileHash:
serializedVersion: 2 serializedVersion: 2
Hash: e765e5fc418c1ed69586a3826e0cdea3 Hash: c9b4a60ca4efa0ba50065dea6e758ce7
TypeTreeHash: TypeTreeHash:
serializedVersion: 2 serializedVersion: 2
Hash: 65942a71d50cdc9f2387a8fa9383a3f8 Hash: 65942a71d50cdc9f2387a8fa9383a3f8

View File

@ -22,7 +22,7 @@ namespace NewHorizons.Builder.Atmosphere
sfv._priority = 0; sfv._priority = 0;
sfv._density = 1.2f; sfv._density = 1.2f;
sfv._fluidType = FluidVolume.Type.AIR; sfv._fluidType = FluidVolume.Type.AIR;
sfv._allowShipAutoroll = true; sfv._allowShipAutoroll = config.Atmosphere.allowShipAutoroll;
sfv._disableOnStart = false; sfv._disableOnStart = false;
if (config.Atmosphere.hasShockLayer) if (config.Atmosphere.hasShockLayer)

View File

@ -147,7 +147,7 @@ namespace NewHorizons.Builder.Atmosphere
fluidCLFV._priority = 1; fluidCLFV._priority = 1;
fluidCLFV._density = 1.2f; fluidCLFV._density = 1.2f;
fluidCLFV._fluidType = atmo.clouds.fluidType.ConvertToOW(FluidVolume.Type.CLOUD); fluidCLFV._fluidType = atmo.clouds.fluidType.ConvertToOW(FluidVolume.Type.CLOUD);
fluidCLFV._allowShipAutoroll = true; fluidCLFV._allowShipAutoroll = atmo.allowShipAutoroll;
fluidCLFV._disableOnStart = false; fluidCLFV._disableOnStart = false;
// Fix the rotations once the rest is done // Fix the rotations once the rest is done

View File

@ -230,6 +230,7 @@ namespace NewHorizons.Builder.Body
if (config.fogTint != null) if (config.fogTint != null)
{ {
var color = config.fogTint.ToColor(); var color = config.fogTint.ToColor();
// Fog alpha has no impact: Must instead use fogDensity.
color.a = 1f; color.a = 1f;
fog.fogTint = color; fog.fogTint = color;
outerFogWarpVolume._fogColor = color; outerFogWarpVolume._fogColor = color;

View File

@ -96,6 +96,12 @@ namespace NewHorizons.Builder.Body
// We want to take the largest size I think // We want to take the largest size I think
var realSize = body.Config.Base.surfaceSize; var realSize = body.Config.Base.surfaceSize;
if (realSize <= 0)
{
// #941 handle proxy body edge case when all scales = 0
realSize = 1;
}
if (body.Config.HeightMap != null) if (body.Config.HeightMap != null)
{ {
HeightMapBuilder.Make(proxy, null, body.Config.HeightMap, body.Mod, 20); HeightMapBuilder.Make(proxy, null, body.Config.HeightMap, body.Mod, 20);

View File

@ -1,18 +1,17 @@
using NewHorizons.External.Configs;
using NewHorizons.Utility;
using NewHorizons.External.Modules.VariableSize;
using UnityEngine;
using System.Collections.Generic;
using NewHorizons.Components.SizeControllers;
using Color = UnityEngine.Color;
using NewHorizons.Components.Volumes;
using NewHorizons.Builder.Props; using NewHorizons.Builder.Props;
using NewHorizons.Utility.OWML;
using NewHorizons.Utility.OuterWilds;
using NewHorizons.External.SerializableData;
using NewHorizons.Builder.Volumes; using NewHorizons.Builder.Volumes;
using NewHorizons.Components.SizeControllers;
using NewHorizons.Components.Volumes;
using NewHorizons.External.Configs;
using NewHorizons.External.Modules.VariableSize;
using NewHorizons.External.SerializableData;
using NewHorizons.Utility;
using NewHorizons.Utility.OuterWilds;
using NewHorizons.Utility.OWML;
using System; using System;
using System.Collections.Generic;
using UnityEngine;
using Color = UnityEngine.Color;
namespace NewHorizons.Builder.Body namespace NewHorizons.Builder.Body
{ {
@ -88,7 +87,7 @@ namespace NewHorizons.Builder.Body
Vector3 localRotation = singularity?.rotation == null ? Vector3.zero : singularity.rotation; Vector3 localRotation = singularity?.rotation == null ? Vector3.zero : singularity.rotation;
GameObject newSingularity = MakeSingularity(go, sector, localPosition, localRotation, polarity, horizonRadius, distortRadius, GameObject newSingularity = MakeSingularity(go, sector, localPosition, localRotation, polarity, horizonRadius, distortRadius,
hasHazardVolume, singularity.targetStarSystem, singularity.curve, singularity.hasWarpEffects, singularity.renderQueueOverride, singularity.rename, singularity.parentPath, singularity.isRelativeToParent); hasHazardVolume, singularity.targetStarSystem, singularity.spawnPointID, singularity.curve, singularity.hasWarpEffects, singularity.renderQueueOverride, singularity.rename, singularity.parentPath, singularity.isRelativeToParent);
var uniqueID = string.IsNullOrEmpty(singularity.uniqueID) ? config.name : singularity.uniqueID; var uniqueID = string.IsNullOrEmpty(singularity.uniqueID) ? config.name : singularity.uniqueID;
@ -161,7 +160,7 @@ namespace NewHorizons.Builder.Body
} }
public static GameObject MakeSingularity(GameObject planetGO, Sector sector, Vector3 position, Vector3 rotation, bool polarity, float horizon, float distort, public static GameObject MakeSingularity(GameObject planetGO, Sector sector, Vector3 position, Vector3 rotation, bool polarity, float horizon, float distort,
bool hasDestructionVolume, string targetStarSystem = null, TimeValuePair[] curve = null, bool warpEffects = true, int renderQueue = 2985, string rename = null, string parentPath = null, bool isRelativeToParent = false) bool hasDestructionVolume, string targetStarSystem = null, string targetSpawnID = null, TimeValuePair[] curve = null, bool warpEffects = true, int renderQueue = 2985, string rename = null, string parentPath = null, bool isRelativeToParent = false)
{ {
// polarity true = black, false = white // polarity true = black, false = white
@ -233,6 +232,7 @@ namespace NewHorizons.Builder.Body
{ {
var wormholeVolume = destructionVolumeGO.AddComponent<BlackHoleWarpVolume>(); var wormholeVolume = destructionVolumeGO.AddComponent<BlackHoleWarpVolume>();
wormholeVolume.TargetSolarSystem = targetStarSystem; wormholeVolume.TargetSolarSystem = targetStarSystem;
wormholeVolume.TargetSpawnID = targetSpawnID;
} }
} }
else else

View File

@ -129,7 +129,7 @@ namespace NewHorizons.Builder.Body
fluidVolume._density = module.density; fluidVolume._density = module.density;
fluidVolume._layer = 5; fluidVolume._layer = 5;
fluidVolume._priority = 3; fluidVolume._priority = 3;
fluidVolume._allowShipAutoroll = true; fluidVolume._allowShipAutoroll = module.allowShipAutoroll;
fluidVolume._disableOnStart = false; fluidVolume._disableOnStart = false;
var fogGO = Object.Instantiate(_oceanFog, waterGO.transform); var fogGO = Object.Instantiate(_oceanFog, waterGO.transform);

View File

@ -8,6 +8,8 @@ namespace NewHorizons.Builder.General
{ {
public static class AstroObjectBuilder public static class AstroObjectBuilder
{ {
public static GameObject CenterOfUniverse { get; private set; }
public static NHAstroObject Make(GameObject body, AstroObject primaryBody, NewHorizonsBody nhBody, bool isVanilla) public static NHAstroObject Make(GameObject body, AstroObject primaryBody, NewHorizonsBody nhBody, bool isVanilla)
{ {
NHAstroObject astroObject = body.AddComponent<NHAstroObject>(); NHAstroObject astroObject = body.AddComponent<NHAstroObject>();
@ -17,7 +19,7 @@ namespace NewHorizons.Builder.General
astroObject.isVanilla = isVanilla; astroObject.isVanilla = isVanilla;
astroObject.HideDisplayName = !config.MapMarker.enabled; astroObject.HideDisplayName = !config.MapMarker.enabled;
astroObject.invulnerableToSun = config.Base.invulnerableToSun; astroObject.invulnerableToSun = !config.Base.hasFluidDetector;
if (config.Orbit != null) astroObject.SetOrbitalParametersFromConfig(config.Orbit); if (config.Orbit != null) astroObject.SetOrbitalParametersFromConfig(config.Orbit);
@ -62,6 +64,8 @@ namespace NewHorizons.Builder.General
if (config.Base.centerOfSolarSystem) if (config.Base.centerOfSolarSystem)
{ {
CenterOfUniverse = body;
NHLogger.Log($"Setting center of universe to {config.name}"); NHLogger.Log($"Setting center of universe to {config.name}");
Delay.RunWhen( Delay.RunWhen(

View File

@ -90,7 +90,7 @@ namespace NewHorizons.Builder.General
OWRB.RegisterAttachedForceDetector(forceDetector); OWRB.RegisterAttachedForceDetector(forceDetector);
// For falling into sun // For falling into sun
if (!config.Base.invulnerableToSun && config.Star == null && config.FocalPoint == null) if (config.Base.hasFluidDetector && config.Star == null && config.FocalPoint == null)
{ {
detectorGO.layer = Layer.AdvancedDetector; detectorGO.layer = Layer.AdvancedDetector;

View File

@ -4,6 +4,7 @@ using NewHorizons.Utility;
using NewHorizons.Utility.OuterWilds; using NewHorizons.Utility.OuterWilds;
using NewHorizons.Utility.OWML; using NewHorizons.Utility.OWML;
using System; using System;
using System.Collections;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
@ -13,17 +14,32 @@ namespace NewHorizons.Builder.General
public static class SpawnPointBuilder public static class SpawnPointBuilder
{ {
private static bool suitUpQueued = false; private static bool suitUpQueued = false;
// Ship
public static SpawnModule.ShipSpawnPoint ShipSpawnInfo { get; private set; }
public static SpawnPoint ShipSpawn { get; private set; } public static SpawnPoint ShipSpawn { get; private set; }
public static Vector3 ShipSpawnOffset { get; private set; } public static Vector3 ShipSpawnOffset { get; private set; }
// Player
public static SpawnModule.PlayerSpawnPoint PlayerSpawnInfo { get; private set; }
public static SpawnPoint PlayerSpawn { get; private set; }
public static void OverridePlayerSpawn(SpawnPoint newSpawn)
{
PlayerSpawn = newSpawn;
PlayerSpawnInfo = null;
}
public static SpawnPoint Make(GameObject planetGO, SpawnModule module, OWRigidbody owRigidBody) public static SpawnPoint Make(GameObject planetGO, SpawnModule module, OWRigidbody owRigidBody)
{ {
SpawnPoint playerSpawn = null; SpawnPoint playerSpawn = null;
// Make the spawn point even if it won't be used this loop // Make the spawn point even if it won't be used this loop
if (module.playerSpawn != null) if (module.playerSpawnPoints != null)
{ {
GameObject spawnGO = GeneralPropBuilder.MakeNew("PlayerSpawnPoint", planetGO, null, module.playerSpawn); foreach (var point in module.playerSpawnPoints)
{
GameObject spawnGO = GeneralPropBuilder.MakeNew("PlayerSpawnPoint", planetGO, null, point);
spawnGO.layer = Layer.PlayerSafetyCollider; spawnGO.layer = Layer.PlayerSafetyCollider;
playerSpawn = spawnGO.AddComponent<SpawnPoint>(); playerSpawn = spawnGO.AddComponent<SpawnPoint>();
@ -33,32 +49,57 @@ namespace NewHorizons.Builder.General
playerSpawn._triggerVolumes = new OWTriggerVolume[0]; playerSpawn._triggerVolumes = new OWTriggerVolume[0];
// This was a stupid hack to stop players getting stuck in the ground and now we have to keep it forever // This was a stupid hack to stop players getting stuck in the ground and now we have to keep it forever
spawnGO.transform.position += spawnGO.transform.TransformDirection(module.playerSpawn.offset ?? Vector3.up * 4f); spawnGO.transform.position += spawnGO.transform.TransformDirection(point.offset ?? Vector3.up * 4f);
if (PlayerSpawn == null || point.GetPriority() > PlayerSpawnInfo.GetPriority())
{
PlayerSpawn = playerSpawn;
PlayerSpawnInfo = point;
}
}
} }
if (module.shipSpawn != null) if (module.shipSpawnPoints != null)
{ {
var spawnGO = GeneralPropBuilder.MakeNew("ShipSpawnPoint", planetGO, null, module.shipSpawn); foreach (var point in module.shipSpawnPoints)
{
var spawnGO = GeneralPropBuilder.MakeNew("ShipSpawnPoint", planetGO, null, point);
spawnGO.SetActive(false); spawnGO.SetActive(false);
spawnGO.layer = Layer.PlayerSafetyCollider; spawnGO.layer = Layer.PlayerSafetyCollider;
ShipSpawn = spawnGO.AddComponent<SpawnPoint>(); var shipSpawn = spawnGO.AddComponent<SpawnPoint>();
ShipSpawn._isShipSpawn = true; shipSpawn._isShipSpawn = true;
ShipSpawn._attachedBody = owRigidBody; shipSpawn._attachedBody = owRigidBody;
ShipSpawn._spawnLocation = SpawnLocation.None; shipSpawn._spawnLocation = SpawnLocation.None;
// #601 we need to actually set the right trigger volumes here // #601 we need to actually set the right trigger volumes here
ShipSpawn._triggerVolumes = new OWTriggerVolume[0]; shipSpawn._triggerVolumes = new OWTriggerVolume[0];
ShipSpawnOffset = module.shipSpawn.offset ?? (module.shipSpawn.alignRadial.GetValueOrDefault() ? Vector3.up * 4 : Vector3.zero); var shipSpawnOffset = point.offset ?? (point.alignRadial.GetValueOrDefault() ? Vector3.up * 4 : Vector3.zero);
if (ShipSpawn == null || point.GetPriority() > ShipSpawnInfo.GetPriority())
{
ShipSpawn = shipSpawn;
ShipSpawnOffset = shipSpawnOffset;
ShipSpawnInfo = point;
}
spawnGO.SetActive(true); spawnGO.SetActive(true);
} }
}
if ((Main.Instance.IsWarpingFromVessel || (!Main.Instance.IsWarpingFromShip && (module.playerSpawn?.startWithSuit ?? false))) && !suitUpQueued) // Make sure to queue this up if any spawn point building is happening
if (!suitUpQueued)
{ {
suitUpQueued = true; suitUpQueued = true;
Delay.RunWhen(() => Main.IsSystemReady, SuitUp); Delay.RunWhen(() => Main.IsSystemReady, () =>
{
suitUpQueued = false;
if (Main.Instance.IsWarpingFromVessel || (!Main.Instance.IsWarpingFromShip && (PlayerSpawnInfo?.startWithSuit ?? false)))
{
SuitUp();
}
});
} }
NHLogger.Log($"Made spawnpoint on [{planetGO.name}]"); NHLogger.Log($"Made spawnpoint on [{planetGO.name}]");
@ -68,7 +109,6 @@ namespace NewHorizons.Builder.General
public static void SuitUp() public static void SuitUp()
{ {
suitUpQueued = false;
if (!Locator.GetPlayerController()._isWearingSuit) if (!Locator.GetPlayerController()._isWearingSuit)
{ {
Locator.GetPlayerSuit().SuitUp(false, true, true); Locator.GetPlayerSuit().SuitUp(false, true, true);
@ -87,8 +127,22 @@ namespace NewHorizons.Builder.General
handler.Method.Invoke(handler.Target, new object[] { command }); handler.Method.Invoke(handler.Target, new object[] { command });
} }
spv._interactVolume._listInteractions.First(x => x.promptText == UITextType.SuitUpPrompt).interactionEnabled = true; spv._interactVolume._listInteractions.First(x => x.promptText == UITextType.SuitUpPrompt).interactionEnabled = true;
// Fix Disappearing Signalscope UI #934 after warping to new system wearing suit
Delay.StartCoroutine(SignalScopeZoomCoroutine());
} }
} }
} }
private static IEnumerator SignalScopeZoomCoroutine()
{
while (!Locator.GetToolModeSwapper().GetSignalScope().InZoomMode())
{
yield return new WaitForEndOfFrame();
}
yield return null;
Locator.GetToolModeSwapper().GetSignalScope().ExitSignalscopeZoom();
Locator.GetToolModeSwapper().GetSignalScope().EnterSignalscopeZoom();
}
} }
} }

View File

@ -1,5 +1,6 @@
using NewHorizons.Builder.General; using NewHorizons.Builder.General;
using NewHorizons.Components; using NewHorizons.Components;
using NewHorizons.Components.Orbital;
using NewHorizons.Components.Props; using NewHorizons.Components.Props;
using NewHorizons.External.Modules.Props; using NewHorizons.External.Modules.Props;
using NewHorizons.Handlers; using NewHorizons.Handlers;
@ -67,6 +68,8 @@ namespace NewHorizons.Builder.Props
/// </summary> /// </summary>
public static GameObject Make(GameObject planetGO, Sector sector, IModBehaviour mod, DetailInfo info) public static GameObject Make(GameObject planetGO, Sector sector, IModBehaviour mod, DetailInfo info)
{ {
if (sector == null) info.keepLoaded = true;
if (info.assetBundle != null) if (info.assetBundle != null)
{ {
// Shouldn't happen // Shouldn't happen
@ -98,6 +101,8 @@ namespace NewHorizons.Builder.Props
{ {
if (prefab == null) return null; if (prefab == null) return null;
if (sector == null) detail.keepLoaded = true;
GameObject prop; GameObject prop;
bool isItem; bool isItem;
bool invalidComponentFound = false; bool invalidComponentFound = false;
@ -370,6 +375,12 @@ namespace NewHorizons.Builder.Props
// Fix anglerfish speed on orbiting planets // Fix anglerfish speed on orbiting planets
else if (component is AnglerfishController angler) else if (component is AnglerfishController angler)
{ {
if (planetGO?.GetComponent<NHAstroObject>() is NHAstroObject nhao && !nhao.invulnerableToSun)
{
// Has a fluid detector, will go gorp (#830)
NHLogger.LogWarning("Having an anglerfish on a planet that has a fluid detector can lead to things breaking!");
}
try try
{ {
angler._chaseSpeed += OWPhysics.CalculateOrbitVelocity(planetGO.GetAttachedOWRigidbody(), planetGO.GetComponent<AstroObject>().GetPrimaryBody().GetAttachedOWRigidbody()).magnitude; angler._chaseSpeed += OWPhysics.CalculateOrbitVelocity(planetGO.GetAttachedOWRigidbody(), planetGO.GetComponent<AstroObject>().GetPrimaryBody().GetAttachedOWRigidbody()).magnitude;

View File

@ -18,8 +18,9 @@ namespace NewHorizons.Builder.Props
{ {
public static class ProjectionBuilder public static class ProjectionBuilder
{ {
public const string INVERTED_SLIDE_CACHE_FOLDER = "SlideReelCache/Inverted"; public static string CurrentSlideReelFolder => "SlideReelCache_" + Main.Instance.CurrentStarSystem;
public const string ATLAS_SLIDE_CACHE_FOLDER = "SlideReelCache/Atlas"; public static string InvertedSlideReelCacheFolder => CurrentSlideReelFolder + "/Inverted";
public static string AtlasSlideReelCacheFolder => CurrentSlideReelFolder + "/Atlas";
public static GameObject SlideReelWholePrefab { get; private set; } public static GameObject SlideReelWholePrefab { get; private set; }
public static GameObject SlideReelWholePristinePrefab { get; private set; } public static GameObject SlideReelWholePristinePrefab { get; private set; }
@ -45,7 +46,7 @@ namespace NewHorizons.Builder.Props
private static bool _isInit; private static bool _isInit;
public static bool CacheExists(IModBehaviour mod) => Directory.Exists(Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ATLAS_SLIDE_CACHE_FOLDER)); public static bool CacheExists(IModBehaviour mod) => Directory.Exists(Path.Combine(mod.ModHelper.Manifest.ModFolderPath, AtlasSlideReelCacheFolder));
internal static void InitPrefabs() internal static void InitPrefabs()
{ {
@ -521,7 +522,7 @@ namespace NewHorizons.Builder.Props
{ {
NHLogger.LogVerbose($"The atlas cache for slide reel containing [{slides.FirstOrDefault(x => !string.IsNullOrEmpty(x.imagePath))?.imagePath}] is {atlasKey}"); NHLogger.LogVerbose($"The atlas cache for slide reel containing [{slides.FirstOrDefault(x => !string.IsNullOrEmpty(x.imagePath))?.imagePath}] is {atlasKey}");
// Load the atlas texture used to draw onto the physical slide reel object // Load the atlas texture used to draw onto the physical slide reel object
atlasImageLoader.PathsToLoad.Add((0, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ATLAS_SLIDE_CACHE_FOLDER, $"{atlasKey}.png"))); atlasImageLoader.PathsToLoad.Add((0, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, AtlasSlideReelCacheFolder, $"{atlasKey}.png")));
} }
for (int i = 0; i < slides.Length; i++) for (int i = 0; i < slides.Length; i++)
@ -548,7 +549,7 @@ namespace NewHorizons.Builder.Props
if (useInvertedCache && cacheExists) if (useInvertedCache && cacheExists)
{ {
// Load the inverted images used when displaying slide reels to a screen // Load the inverted images used when displaying slide reels to a screen
invertedImageLoader.PathsToLoad.Add((i, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, INVERTED_SLIDE_CACHE_FOLDER, slideInfo.imagePath))); invertedImageLoader.PathsToLoad.Add((i, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, InvertedSlideReelCacheFolder, slideInfo.imagePath)));
} }
else else
{ {

View File

@ -1,3 +1,4 @@
using NewHorizons.Utility.OWML;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
@ -37,7 +38,6 @@ namespace NewHorizons.Builder.Props.TranslatorText
) )
.ToArray(); .ToArray();
return BuildSpiralGameObject(_points, mesh, goName); return BuildSpiralGameObject(_points, mesh, goName);
} }
@ -67,15 +67,52 @@ namespace NewHorizons.Builder.Props.TranslatorText
public struct SpiralProfile { public struct SpiralProfile {
// all of the Vector2 params here refer to a range of valid values // all of the Vector2 params here refer to a range of valid values
public string profileName; public string profileName;
/// <summary>
/// What is this
/// </summary>
public Vector2 a; public Vector2 a;
/// <summary>
/// What is this
/// </summary>
public Vector2 b; public Vector2 b;
/// <summary>
/// What is this
/// </summary>
public Vector2 startS; public Vector2 startS;
/// <summary>
/// What is this
/// </summary>
public Vector2 endS; public Vector2 endS;
/// <summary>
/// What is this
/// </summary>
public Vector2 skeletonScale; public Vector2 skeletonScale;
/// <summary>
/// What is this
/// </summary>
public int numSkeletonPoints; public int numSkeletonPoints;
/// <summary>
/// What is this
/// </summary>
public float uvScale; public float uvScale;
public float innerWidth; // width at the tip
public float outerWidth; // width at the base /// <summary>
/// Width at tip
/// </summary>
public float innerWidth;
/// <summary>
/// Width at base
/// </summary>
public float outerWidth;
public Material material; public Material material;
} }
@ -119,8 +156,6 @@ namespace NewHorizons.Builder.Props.TranslatorText
innerWidth = 0.75f, innerWidth = 0.75f,
outerWidth = 0.75f, outerWidth = 0.75f,
uvScale = 1f/1.8505f, uvScale = 1f/1.8505f,
}; };

View File

@ -583,7 +583,12 @@ namespace NewHorizons.Builder.Props.TranslatorText
case NomaiTextArcInfo.NomaiTextArcType.Stranger when _ghostArcMaterial != null: case NomaiTextArcInfo.NomaiTextArcType.Stranger when _ghostArcMaterial != null:
profile = NomaiTextArcBuilder.strangerSpiralProfile; profile = NomaiTextArcBuilder.strangerSpiralProfile;
mat = _ghostArcMaterial; mat = _ghostArcMaterial;
overrideMesh = MeshUtilities.RectangleMeshFromCorners(new Vector3[]{ new Vector3(-0.9f, 0.0f, 0.0f), new Vector3(0.9f, 0.0f, 0.0f), new Vector3(-0.9f, 2.0f, 0.0f), new Vector3(0.9f, 2.0f, 0.0f) }); overrideMesh = MeshUtilities.RectangleMeshFromCorners(new Vector3[]{
new Vector3(-0.9f, 0.0f, 0.0f),
new Vector3(0.9f, 0.0f, 0.0f),
new Vector3(-0.9f, 2.0f, 0.0f),
new Vector3(0.9f, 2.0f, 0.0f)
});
overrideColor = new Color(0.0158f, 1.0f, 0.5601f, 1f); overrideColor = new Color(0.0158f, 1.0f, 0.5601f, 1f);
break; break;
case NomaiTextArcInfo.NomaiTextArcType.Adult: case NomaiTextArcInfo.NomaiTextArcType.Adult:
@ -603,6 +608,19 @@ namespace NewHorizons.Builder.Props.TranslatorText
else arc = NomaiTextArcArranger.CreateSpiral(profile, conversationZone).gameObject; else arc = NomaiTextArcArranger.CreateSpiral(profile, conversationZone).gameObject;
} }
// Hardcoded stranger point fix
if (type == NomaiTextArcInfo.NomaiTextArcType.Stranger)
{
Delay.FireOnNextUpdate(() =>
{
var text = arc.GetComponent<NomaiTextLine>();
for (int i = 0; i < text._points.Length; i++)
{
text._points[i] = new Vector3(0f, 2f * i / text._points.Length, 0f);
}
});
}
if (mat != null) arc.GetComponent<MeshRenderer>().sharedMaterial = mat; if (mat != null) arc.GetComponent<MeshRenderer>().sharedMaterial = mat;
arc.transform.parent = conversationZone.transform; arc.transform.parent = conversationZone.transform;

View File

@ -11,6 +11,7 @@ namespace NewHorizons.Builder.Volumes
var volume = VolumeBuilder.Make<WarpVolume>(planetGO, sector, info); var volume = VolumeBuilder.Make<WarpVolume>(planetGO, sector, info);
volume.TargetSolarSystem = info.targetStarSystem; volume.TargetSolarSystem = info.targetStarSystem;
volume.TargetSpawnID = info.spawnPointID;
return volume; return volume;
} }

View File

@ -211,7 +211,7 @@ namespace NewHorizons.Components.ShipLog
{ {
if (_starSystemCards.Count == 0) if (_starSystemCards.Count == 0)
{ {
NHLogger.LogWarning("Showing star chart mode when there are no avaialble systems"); NHLogger.LogWarning("Showing star chart mode when there are no available systems");
return; return;
} }

View File

@ -1,8 +1,11 @@
using NewHorizons.Handlers;
namespace NewHorizons.Components.Volumes namespace NewHorizons.Components.Volumes
{ {
public class BlackHoleWarpVolume : BlackHoleDestructionVolume public class BlackHoleWarpVolume : BlackHoleDestructionVolume
{ {
public string TargetSolarSystem { get; set; } public string TargetSolarSystem { get; set; }
public string TargetSpawnID { get; set; }
public override void Awake() public override void Awake()
{ {
@ -19,6 +22,7 @@ namespace NewHorizons.Components.Volumes
{ {
Locator.GetPlayerAudioController().PlayOneShotInternal(AudioType.BH_BlackHoleEmission); Locator.GetPlayerAudioController().PlayOneShotInternal(AudioType.BH_BlackHoleEmission);
Main.Instance.ChangeCurrentStarSystem(TargetSolarSystem, PlayerState.AtFlightConsole()); Main.Instance.ChangeCurrentStarSystem(TargetSolarSystem, PlayerState.AtFlightConsole());
PlayerSpawnHandler.TargetSpawnID = TargetSpawnID;
} }
} }
} }

View File

@ -1,3 +1,4 @@
using NewHorizons.Handlers;
using UnityEngine; using UnityEngine;
namespace NewHorizons.Components.Volumes namespace NewHorizons.Components.Volumes
@ -5,6 +6,7 @@ namespace NewHorizons.Components.Volumes
internal class WarpVolume : BaseVolume internal class WarpVolume : BaseVolume
{ {
public string TargetSolarSystem; public string TargetSolarSystem;
public string TargetSpawnID;
public override void OnTriggerVolumeEntry(GameObject hitObj) public override void OnTriggerVolumeEntry(GameObject hitObj)
{ {
@ -13,6 +15,7 @@ namespace NewHorizons.Components.Volumes
if (Main.Instance.CurrentStarSystem != TargetSolarSystem) // Otherwise it really breaks idk why if (Main.Instance.CurrentStarSystem != TargetSolarSystem) // Otherwise it really breaks idk why
{ {
Main.Instance.ChangeCurrentStarSystem(TargetSolarSystem, PlayerState.AtFlightConsole()); Main.Instance.ChangeCurrentStarSystem(TargetSolarSystem, PlayerState.AtFlightConsole());
PlayerSpawnHandler.TargetSpawnID = TargetSpawnID;
} }
} }
} }

View File

@ -41,6 +41,7 @@ namespace NewHorizons.External.Configs
/// <summary> /// <summary>
/// The path to the addons subtitle for the main menu. /// The path to the addons subtitle for the main menu.
/// Defaults to "subtitle.png". /// Defaults to "subtitle.png".
/// The dimensions of the Echoes of the Eye subtitle is 669 x 67, so aim for that size
/// </summary> /// </summary>
public string subtitlePath = "subtitle.png"; public string subtitlePath = "subtitle.png";
} }

View File

@ -11,9 +11,7 @@ using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using UnityEngine;
namespace NewHorizons.External.Configs namespace NewHorizons.External.Configs
{ {
@ -25,9 +23,8 @@ namespace NewHorizons.External.Configs
{ {
#region Fields #region Fields
/// <summary> /// <summary>
/// Unique name of your planet /// Unique name of your planet. If not specified, the file name (without the extension) is used.
/// </summary> /// </summary>
[Required]
public string name; public string name;
/// <summary> /// <summary>
@ -281,7 +278,7 @@ namespace NewHorizons.External.Configs
} }
// Stars and focal points shouldnt be destroyed by stars // Stars and focal points shouldnt be destroyed by stars
if (Star != null || FocalPoint != null) Base.invulnerableToSun = true; if (Star != null || FocalPoint != null) Base.hasFluidDetector = false;
} }
public void Migrate() public void Migrate()
@ -543,6 +540,22 @@ namespace NewHorizons.External.Configs
}; };
} }
// Spawn points are now a list
if (Spawn != null && Spawn.playerSpawn != null && Spawn.playerSpawnPoints == null)
{
Spawn.playerSpawnPoints = new SpawnModule.PlayerSpawnPoint[] { Spawn.playerSpawn };
}
if (Spawn != null && Spawn.shipSpawn != null && Spawn.shipSpawnPoints == null)
{
Spawn.shipSpawnPoints = new SpawnModule.ShipSpawnPoint[] { Spawn.shipSpawn };
}
// Because these guys put TWO spawn points
if (starSystem == "2walker2.OogaBooga" && name == "The Campground")
{
Spawn.playerSpawnPoints[0].isDefault = true;
}
// Remote dialogue trigger reorganized to use GeneralPointPropInfo // Remote dialogue trigger reorganized to use GeneralPointPropInfo
if (Props?.dialogue != null) if (Props?.dialogue != null)
{ {
@ -664,6 +677,11 @@ namespace NewHorizons.External.Configs
if (destructionVolume.onlyAffectsPlayerAndShip) destructionVolume.onlyAffectsPlayerRelatedBodies = true; if (destructionVolume.onlyAffectsPlayerAndShip) destructionVolume.onlyAffectsPlayerRelatedBodies = true;
} }
} }
if (Base.invulnerableToSun)
{
Base.hasFluidDetector = false;
}
} }
#endregion #endregion
} }

View File

@ -16,6 +16,11 @@ namespace NewHorizons.External.Configs
[JsonObject] [JsonObject]
public class StarSystemConfig public class StarSystemConfig
{ {
/// <summary>
/// Unique name of your system. If not specified, the file name (without the extension) is used.
/// </summary>
public string name;
/// <summary> /// <summary>
/// In this system should the player be able to rotate their map camera freely or be stuck above the plane of the solar system? /// In this system should the player be able to rotate their map camera freely or be stuck above the plane of the solar system?
/// </summary> /// </summary>

View File

@ -107,6 +107,12 @@ namespace NewHorizons.External.Modules
/// </summary> /// </summary>
[DefaultValue(300f)] public float maxShockSpeed = 300f; [DefaultValue(300f)] public float maxShockSpeed = 300f;
/// <summary>
/// Will the ship automatically try to orient itself to face upwards while in this volume?
/// </summary>
[DefaultValue(true)]
public bool allowShipAutoroll = true;
[JsonObject] [JsonObject]
public class CloudInfo public class CloudInfo
{ {

View File

@ -37,9 +37,11 @@ namespace NewHorizons.External.Modules
public float groundSize; public float groundSize;
/// <summary> /// <summary>
/// Can this planet survive entering a star? /// Is this planet able to detect fluid volumes? Disabling this means that entering a star or lava volume will not destroy this planet
/// May have adverse effects if anglerfish are added to this planet, disable this if you want those to work (they have fluid volumes in their mouths)
/// </summary> /// </summary>
public bool invulnerableToSun; [DefaultValue(true)]
public bool hasFluidDetector = true;
/// <summary> /// <summary>
/// Do we show the minimap when walking around this planet? /// Do we show the minimap when walking around this planet?
@ -58,6 +60,8 @@ namespace NewHorizons.External.Modules
/// <summary> /// <summary>
/// A scale height used for a number of things. Should be the approximate radius of the body. /// A scale height used for a number of things. Should be the approximate radius of the body.
///
/// Affected settings include: Base sector size, proxy body scaling, surface gravity
/// </summary> /// </summary>
public float surfaceSize; public float surfaceSize;
@ -82,6 +86,9 @@ namespace NewHorizons.External.Modules
#region Obsolete #region Obsolete
[Obsolete("invulnerableToSun is deprecated, please use hasFluidDetector instead")]
public bool invulnerableToSun;
[Obsolete("IsSatellite is deprecated, please use ShowMinimap instead")] [Obsolete("IsSatellite is deprecated, please use ShowMinimap instead")]
public bool isSatellite; public bool isSatellite;

View File

@ -41,11 +41,12 @@ namespace NewHorizons.External.Modules
/// <summary> /// <summary>
/// The color of the fog inside this dimension. /// The color of the fog inside this dimension.
/// Leave blank for the default grayish color: (84, 83, 73) /// Leave blank for the default grayish color: (84, 83, 73)
/// The alpha value has no effect of the fog: Use fogDensity instead!
/// </summary> /// </summary>
public MColor fogTint; public MColor fogTint;
/// <summary> /// <summary>
/// The density of the fog inside this dimension. The default is 6. /// The density of the fog inside this dimension. The default is 6. If you want no fog, set this to 0.
/// </summary> /// </summary>
[DefaultValue(6f)] public float fogDensity = 6f; [DefaultValue(6f)] public float fogDensity = 6f;

View File

@ -56,6 +56,7 @@ namespace NewHorizons.External.Modules.Props
/// <summary> /// <summary>
/// Should this detail stay loaded (visible and collideable) even if you're outside the sector (good for very large props)? /// Should this detail stay loaded (visible and collideable) even if you're outside the sector (good for very large props)?
/// Also makes this detail visible on the map. /// Also makes this detail visible on the map.
/// Keeping many props loaded is bad for performance so use this only when it's actually relevant
/// Most logic/behavior scripts will still only work inside the sector, as most of those scripts break if a sector is not provided. /// Most logic/behavior scripts will still only work inside the sector, as most of those scripts break if a sector is not provided.
/// </summary> /// </summary>
public bool keepLoaded; public bool keepLoaded;

View File

@ -1,4 +1,6 @@
using NewHorizons.Builder.General;
using NewHorizons.External.SerializableData; using NewHorizons.External.SerializableData;
using NewHorizons.Handlers;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
@ -9,12 +11,20 @@ namespace NewHorizons.External.Modules
{ {
/// <summary> /// <summary>
/// If you want the player to spawn on the new body, set a value for this. /// If you want the player to spawn on the new body, set a value for this.
/// Different spawns can be unlocked with persistent conditions and facts
/// </summary> /// </summary>
public PlayerSpawnPoint playerSpawn; public PlayerSpawnPoint[] playerSpawnPoints;
/// <summary> /// <summary>
/// Required for the system to be accessible by warp drive. /// Required for the system to be accessible by warp drive.
/// Different spawns can be unlocked with persistent conditions and facts
/// </summary> /// </summary>
public ShipSpawnPoint[] shipSpawnPoints;
[Obsolete("Use playerSpawnPoints instead")]
public PlayerSpawnPoint playerSpawn;
[Obsolete("Use shipSpawnPoints instead")]
public ShipSpawnPoint shipSpawn; public ShipSpawnPoint shipSpawn;
[Obsolete("playerSpawnPoint is deprecated. Use playerSpawn.position instead")] public MVector3 playerSpawnPoint; [Obsolete("playerSpawnPoint is deprecated. Use playerSpawn.position instead")] public MVector3 playerSpawnPoint;
@ -30,6 +40,56 @@ namespace NewHorizons.External.Modules
/// Offsets the player/ship by this local vector when spawning. Used to prevent spawning in the floor. Optional: defaults to (0, 4, 0). /// Offsets the player/ship by this local vector when spawning. Used to prevent spawning in the floor. Optional: defaults to (0, 4, 0).
/// </summary> /// </summary>
public MVector3 offset; public MVector3 offset;
/// <summary>
/// Whether this planet's spawn point is the one the player/ship will initially spawn at, if multiple spawn points exist.
/// Do not use at the same time as makeDefaultIfFactRevealed or makeDefaultIfPersistentCondition
/// Spawns unlocked with this have lowest priority
/// </summary>
public bool isDefault;
/// <summary>
/// If the given ship log fact is revealed, this spawn point will be used
/// Do not use at the same time as isDefault or makeDefaultIfPersistentCondition
/// Spawns unlocked with this have highest priority
/// </summary>
public string makeDefaultIfFactRevealed;
/// <summary>
/// If the given persistent condition is true, this spawn point will be used
/// Do not use at the same time as isDefault or makeDefaultIfFactRevealed
/// Spawns unlocked with this have second highest priority
/// </summary>
public string makeDefaultIfPersistentCondition;
/// <summary>
/// ID used to have a black hole or warp volume bring the player to this spawn specifically
/// </summary>
public string id;
public int GetPriority()
{
if (!string.IsNullOrEmpty(id) && !string.IsNullOrEmpty(PlayerSpawnHandler.TargetSpawnID) && id == PlayerSpawnHandler.TargetSpawnID)
{
return 3;
}
if (!string.IsNullOrEmpty(makeDefaultIfFactRevealed) && ShipLogHandler.KnowsFact(makeDefaultIfFactRevealed))
{
return 2;
}
if (!string.IsNullOrEmpty(makeDefaultIfPersistentCondition) && PlayerData.GetPersistentCondition(makeDefaultIfPersistentCondition))
{
return 1;
}
if (isDefault)
{
return 0;
}
else
{
return -1;
}
}
} }
[JsonObject] [JsonObject]
@ -39,12 +99,6 @@ namespace NewHorizons.External.Modules
/// If you spawn on a planet with no oxygen, you probably want to set this to true ;;) /// If you spawn on a planet with no oxygen, you probably want to set this to true ;;)
/// </summary> /// </summary>
public bool startWithSuit; public bool startWithSuit;
/// <summary>
/// Whether this planet's spawn point is the one the player will initially spawn at, if multiple spawn points exist.
/// </summary>
public bool isDefault;
} }
[JsonObject] [JsonObject]

View File

@ -54,6 +54,12 @@ namespace NewHorizons.External.Modules.VariableSize
/// </summary> /// </summary>
public string targetStarSystem; public string targetStarSystem;
/// <summary>
/// If this is a black hole loading a new star system, set the ID of the spawn point you want to use
/// Otherwise, will use the default spawn
/// </summary>
public string spawnPointID;
/// <summary> /// <summary>
/// Type of singularity (white hole or black hole) /// Type of singularity (white hole or black hole)
/// </summary> /// </summary>

View File

@ -26,5 +26,11 @@ namespace NewHorizons.External.Modules.VariableSize
/// Tint of the water /// Tint of the water
/// </summary> /// </summary>
public MColor tint; public MColor tint;
/// <summary>
/// Will the ship automatically try to orient itself to face upwards while in this volume?
/// </summary>
[DefaultValue(true)]
public bool allowShipAutoroll = true;
} }
} }

View File

@ -10,5 +10,11 @@ namespace NewHorizons.External.Modules.Volumes.VolumeInfos
/// The star system that entering this volume will send you to. /// The star system that entering this volume will send you to.
/// </summary> /// </summary>
[DefaultValue("SolarSystem")] public string targetStarSystem; [DefaultValue("SolarSystem")] public string targetStarSystem;
/// <summary>
/// ID assigned to a spawn point in the other system that the player will be sent to
/// Uses the default spawn if not set
/// </summary>
public string spawnPointID;
} }
} }

View File

@ -3,6 +3,7 @@ using NewHorizons.Utility.Files;
using NewHorizons.Utility.OWML; using NewHorizons.Utility.OWML;
using OWML.Common; using OWML.Common;
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
@ -16,6 +17,12 @@ namespace NewHorizons.External
Mod = mod; Mod = mod;
RelativePath = relativePath; RelativePath = relativePath;
// Fall back to file name if name not given
if (!string.IsNullOrEmpty(relativePath) && string.IsNullOrEmpty(config.name))
{
config.name = Path.GetFileNameWithoutExtension(relativePath);
}
Migrate(); Migrate();
} }
@ -99,12 +106,6 @@ namespace NewHorizons.External
} }
} }
} }
// Because these guys put TWO spawn points
if (Mod.ModHelper.Manifest.UniqueName == "2walker2.Evacuation" && Config.name == "The Campground")
{
Config.Spawn.playerSpawn.isDefault = true;
}
} }
#endregion #endregion

View File

@ -1,5 +1,4 @@
using NewHorizons.External.Configs; using NewHorizons.External.Configs;
using NewHorizons.External.Modules;
using OWML.Common; using OWML.Common;
using System.Linq; using System.Linq;
@ -9,10 +8,9 @@ namespace NewHorizons.External
{ {
public string UniqueID; public string UniqueID;
public string RelativePath; public string RelativePath;
public SpawnModule Spawn = null;
public SpawnPoint SpawnPoint = null;
public StarSystemConfig Config; public StarSystemConfig Config;
public IModBehaviour Mod; public IModBehaviour Mod;
public bool HasShipSpawn;
public NewHorizonsSystem(string uniqueID, StarSystemConfig config, string relativePath, IModBehaviour mod) public NewHorizonsSystem(string uniqueID, StarSystemConfig config, string relativePath, IModBehaviour mod)
{ {

View File

@ -425,8 +425,8 @@ namespace NewHorizons.Handlers
if (defaultPrimaryToSun) if (defaultPrimaryToSun)
{ {
NHLogger.LogError($"Couldn't find {body.Config.Orbit.primaryBody}, defaulting to center of solar system"); NHLogger.LogError($"Couldn't find {body.Config.Orbit.primaryBody}, defaulting to center of solar system");
// TODO: Make this work in other systems. We tried using Locator.GetCenterOfUniverse before but that doesn't work since its too early now // Fix #933 not defaulting primary body
primaryBody = SearchUtilities.Find("Sun_Body")?.GetComponent<AstroObject>(); primaryBody = (SearchUtilities.Find("Sun_Body") ?? AstroObjectBuilder.CenterOfUniverse)?.GetComponent<AstroObject>();
} }
else else
{ {
@ -506,13 +506,6 @@ namespace NewHorizons.Handlers
{ {
NHLogger.LogVerbose($"Making spawn point on {body.Config.name}"); NHLogger.LogVerbose($"Making spawn point on {body.Config.name}");
var spawnPoint = SpawnPointBuilder.Make(go, body.Config.Spawn, owRigidBody); var spawnPoint = SpawnPointBuilder.Make(go, body.Config.Spawn, owRigidBody);
var isVanillaSystem = body.Config.starSystem == "SolarSystem" || body.Config.starSystem == "EyeOfTheUniverse";
var needsSpawnPoint = Main.SystemDict[body.Config.starSystem].SpawnPoint == null || isVanillaSystem;
var isDefaultSpawn = body.Config.Spawn.playerSpawn?.isDefault ?? true; // Backwards compat
if (needsSpawnPoint || isDefaultSpawn)
{
Main.SystemDict[body.Config.starSystem].SpawnPoint = spawnPoint;
}
} }
if (body.Config.Orbit.showOrbitLine && !body.Config.Orbit.isStatic) if (body.Config.Orbit.showOrbitLine && !body.Config.Orbit.isStatic)

View File

@ -9,6 +9,11 @@ namespace NewHorizons.Handlers
{ {
public static class PlayerSpawnHandler public static class PlayerSpawnHandler
{ {
/// <summary>
/// Set during the previous loop, force the player to spawn here
/// </summary>
public static string TargetSpawnID { get; set; }
public static void SetUpPlayerSpawn() public static void SetUpPlayerSpawn()
{ {
if (UsingCustomSpawn()) if (UsingCustomSpawn())
@ -146,6 +151,9 @@ namespace NewHorizons.Handlers
FixPlayerVelocity(); FixPlayerVelocity();
InvulnerabilityHandler.MakeInvulnerable(false); InvulnerabilityHandler.MakeInvulnerable(false);
// Done spawning
TargetSpawnID = null;
} }
private static void FixPlayerVelocity(bool recenter = true) private static void FixPlayerVelocity(bool recenter = true)
@ -200,8 +208,8 @@ namespace NewHorizons.Handlers
return vector; return vector;
} }
public static bool UsingCustomSpawn() => Main.SystemDict[Main.Instance.CurrentStarSystem].SpawnPoint != null; public static bool UsingCustomSpawn() => SpawnPointBuilder.PlayerSpawn != null;
public static PlayerSpawner GetPlayerSpawner() => GameObject.FindObjectOfType<PlayerSpawner>(); public static PlayerSpawner GetPlayerSpawner() => GameObject.FindObjectOfType<PlayerSpawner>();
public static SpawnPoint GetDefaultSpawn() => Main.SystemDict[Main.Instance.CurrentStarSystem].SpawnPoint ?? GetPlayerSpawner().GetSpawnPoint(SpawnLocation.TimberHearth); public static SpawnPoint GetDefaultSpawn() => SpawnPointBuilder.PlayerSpawn ?? GetPlayerSpawner().GetSpawnPoint(SpawnLocation.TimberHearth);
} }
} }

View File

@ -114,10 +114,8 @@ namespace NewHorizons.Handlers
public static bool KnowsFact(string fact) public static bool KnowsFact(string fact)
{ {
// Works normally in the main system, else check save data directly // Use save data directly so stuff works between systems
var shipLogManager = Locator.GetShipLogManager(); return PlayerData.GetShipLogFactSave(fact)?.revealOrder > -1;
if (Main.Instance.CurrentStarSystem == "SolarSystem" && shipLogManager != null) return shipLogManager.IsFactRevealed(fact);
else return PlayerData.GetShipLogFactSave(fact)?.revealOrder > -1;
} }
} }
} }

View File

@ -130,7 +130,7 @@ namespace NewHorizons.Handlers
var canWarpTo = false; var canWarpTo = false;
if (system.Equals("SolarSystem")) canWarpTo = true; if (system.Equals("SolarSystem")) canWarpTo = true;
else if (system.Equals("EyeOfTheUniverse")) canWarpTo = false; else if (system.Equals("EyeOfTheUniverse")) canWarpTo = false;
else if (config.Spawn?.shipSpawn != null) canWarpTo = true; else if (config.HasShipSpawn) canWarpTo = true;
var canEnterViaWarpDrive = Main.SystemDict[system].Config.canEnterViaWarpDrive || system == "SolarSystem"; var canEnterViaWarpDrive = Main.SystemDict[system].Config.canEnterViaWarpDrive || system == "SolarSystem";
@ -156,15 +156,20 @@ namespace NewHorizons.Handlers
_canExitViaWarpDrive = true; _canExitViaWarpDrive = true;
if (!Main.HasWarpDrive) if (!Main.HasWarpDrive)
{ {
Main.Instance.EnableWarpDrive(); var flagActuallyAddedACard = false;
// Add all cards that now work // Add all cards that now work
foreach (var starSystem in Main.SystemDict.Keys) foreach (var starSystem in Main.SystemDict.Keys)
{ {
if (CanWarpToSystem(starSystem)) if (CanWarpToSystem(starSystem))
{ {
ShipLogStarChartMode.AddSystemCard(starSystem); ShipLogStarChartMode.AddSystemCard(starSystem);
flagActuallyAddedACard = true;
} }
} }
if (flagActuallyAddedACard)
{
Main.Instance.EnableWarpDrive();
}
} }
else else
{ {

View File

@ -1,3 +1,4 @@
using NewHorizons.Utility;
using NewHorizons.Utility.Files; using NewHorizons.Utility.Files;
using NewHorizons.Utility.OWML; using NewHorizons.Utility.OWML;
using OWML.Common; using OWML.Common;
@ -31,6 +32,8 @@ namespace NewHorizons.Handlers
private static List<(IModBehaviour mod, string filePath)> _additionalSubtitles = new(); private static List<(IModBehaviour mod, string filePath)> _additionalSubtitles = new();
private CanvasGroup _titleCanvasGroup;
public static void RegisterAdditionalSubtitle(IModBehaviour mod, string filePath) public static void RegisterAdditionalSubtitle(IModBehaviour mod, string filePath)
{ {
_additionalSubtitles.Add((mod, filePath)); _additionalSubtitles.Add((mod, filePath));
@ -64,6 +67,8 @@ namespace NewHorizons.Handlers
var layout = GetComponent<LayoutElement>(); var layout = GetComponent<LayoutElement>();
layout.minHeight = SUBTITLE_HEIGHT; layout.minHeight = SUBTITLE_HEIGHT;
_titleCanvasGroup = SearchUtilities.Find("TitleCanvas").GetComponent<CanvasGroup>();
CheckForEOTE(); CheckForEOTE();
// We add our subtitles as a child object so that their sizing doesnt shift the layout of the main menu // We add our subtitles as a child object so that their sizing doesnt shift the layout of the main menu
@ -104,7 +109,7 @@ namespace NewHorizons.Handlers
var tex = ImageUtilities.GetTexture(mod, filepath, false); var tex = ImageUtilities.GetTexture(mod, filepath, false);
if (tex == null) return; if (tex == null) return;
var sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, Mathf.Max(SUBTITLE_HEIGHT, tex.height)), new Vector2(0.5f, 0.5f), 100.0f); var sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f);
AddSubtitle(sprite); AddSubtitle(sprite);
} }
@ -137,6 +142,12 @@ namespace NewHorizons.Handlers
return; return;
} }
// Fix subtitles start cycling before the main menu is visible #844
if (_titleCanvasGroup.alpha < 1)
{
return;
}
if (pauseTimer > 0) if (pauseTimer > 0)
{ {
pauseTimer--; pauseTimer--;

View File

@ -1,3 +1,4 @@
using NewHorizons.Builder.General;
using NewHorizons.Builder.Props; using NewHorizons.Builder.Props;
using NewHorizons.Components; using NewHorizons.Components;
using NewHorizons.Components.EyeOfTheUniverse; using NewHorizons.Components.EyeOfTheUniverse;
@ -240,7 +241,7 @@ namespace NewHorizons.Handlers
VesselSpawnPoint spawnPoint = vesselObject.GetComponentInChildren<VesselSpawnPoint>(true); VesselSpawnPoint spawnPoint = vesselObject.GetComponentInChildren<VesselSpawnPoint>(true);
if (ShouldSpawnAtVessel()) if (ShouldSpawnAtVessel())
{ {
system.SpawnPoint = spawnPoint; SpawnPointBuilder.OverridePlayerSpawn(spawnPoint);
} }
vesselObject.SetActive(true); vesselObject.SetActive(true);

View File

@ -214,5 +214,12 @@ namespace NewHorizons
/// <param name="mod"></param> /// <param name="mod"></param>
/// <param name="filePath"></param> /// <param name="filePath"></param>
void AddSubtitle(IModBehaviour mod, string filePath); void AddSubtitle(IModBehaviour mod, string filePath);
/// <summary>
/// Whatever system the player is warping to next, they will spawn at the spawn point with this ID
/// Gets reset after warping. Is also overriden by entering a system-changing black hole or warp volume by their `spawnPointID`
/// </summary>
/// <param name="id"></param>
void SetNextSpawnID(string id);
} }
} }

View File

@ -173,7 +173,7 @@ namespace NewHorizons
BodyDict["SolarSystem"] = new List<NewHorizonsBody>(); BodyDict["SolarSystem"] = new List<NewHorizonsBody>();
BodyDict["EyeOfTheUniverse"] = new List<NewHorizonsBody>(); // Keep this empty tho fr BodyDict["EyeOfTheUniverse"] = new List<NewHorizonsBody>(); // Keep this empty tho fr
SystemDict["SolarSystem"] = new NewHorizonsSystem("SolarSystem", new StarSystemConfig(), "", Instance) SystemDict["SolarSystem"] = new NewHorizonsSystem("SolarSystem", new StarSystemConfig() { name = "SolarSystem" }, "", Instance)
{ {
Config = Config =
{ {
@ -189,7 +189,7 @@ namespace NewHorizons
} }
} }
}; };
SystemDict["EyeOfTheUniverse"] = new NewHorizonsSystem("EyeOfTheUniverse", new StarSystemConfig(), "", Instance) SystemDict["EyeOfTheUniverse"] = new NewHorizonsSystem("EyeOfTheUniverse", new StarSystemConfig() { name = "EyeOfTheUniverse" }, "", Instance)
{ {
Config = Config =
{ {
@ -677,8 +677,15 @@ namespace NewHorizons
} }
#region Load #region Load
public void LoadStarSystemConfig(string starSystemName, StarSystemConfig starSystemConfig, string relativePath, IModBehaviour mod) public void LoadStarSystemConfig(StarSystemConfig starSystemConfig, string relativePath, IModBehaviour mod)
{ {
if (string.IsNullOrEmpty(starSystemConfig.name))
{
starSystemConfig.name = Path.GetFileNameWithoutExtension(relativePath);
}
var starSystemName = starSystemConfig.name;
starSystemConfig.Migrate(); starSystemConfig.Migrate();
starSystemConfig.FixCoordinates(); starSystemConfig.FixCoordinates();
@ -748,13 +755,12 @@ namespace NewHorizons
foreach (var file in systemFiles) foreach (var file in systemFiles)
{ {
var starSystemName = Path.GetFileNameWithoutExtension(file);
NHLogger.LogVerbose($"Loading system {starSystemName}");
var relativePath = file.Replace(folder, ""); var relativePath = file.Replace(folder, "");
NHLogger.LogVerbose($"Loading system {Path.GetFileNameWithoutExtension(relativePath)}");
var starSystemConfig = mod.ModHelper.Storage.Load<StarSystemConfig>(relativePath, false); var starSystemConfig = mod.ModHelper.Storage.Load<StarSystemConfig>(relativePath, false);
LoadStarSystemConfig(starSystemName, starSystemConfig, relativePath, mod); LoadStarSystemConfig(starSystemConfig, relativePath, mod);
} }
} }
if (Directory.Exists(planetsFolder)) if (Directory.Exists(planetsFolder))
@ -783,9 +789,6 @@ namespace NewHorizons
if (body != null) if (body != null)
{ {
// Wanna track the spawn point of each system
if (body.Config.Spawn != null) SystemDict[body.Config.starSystem].Spawn = body.Config.Spawn;
// Add the new planet to the planet dictionary // Add the new planet to the planet dictionary
if (!BodyDict.ContainsKey(body.Config.starSystem)) BodyDict[body.Config.starSystem] = new List<NewHorizonsBody>(); if (!BodyDict.ContainsKey(body.Config.starSystem)) BodyDict[body.Config.starSystem] = new List<NewHorizonsBody>();
BodyDict[body.Config.starSystem].Add(body); BodyDict[body.Config.starSystem].Add(body);
@ -903,11 +906,7 @@ namespace NewHorizons
{ {
if (!SystemDict.ContainsKey(config.starSystem)) if (!SystemDict.ContainsKey(config.starSystem))
{ {
// Since we didn't load it earlier there shouldn't be a star system config var starSystemConfig = new StarSystemConfig() { name = config.starSystem };
var starSystemConfig = mod.ModHelper.Storage.Load<StarSystemConfig>(Path.Combine("systems", config.starSystem + ".json"), false);
if (starSystemConfig == null) starSystemConfig = new StarSystemConfig();
else NHLogger.LogWarning($"Loaded system config for {config.starSystem}. Why wasn't this loaded earlier?");
starSystemConfig.Migrate(); starSystemConfig.Migrate();
starSystemConfig.FixCoordinates(); starSystemConfig.FixCoordinates();
@ -922,6 +921,12 @@ namespace NewHorizons
config.Validate(); config.Validate();
config.Migrate(); config.Migrate();
// Check if this system can be warped to
if (config.Spawn?.shipSpawnPoints?.Any() ?? false)
{
SystemDict[config.starSystem].HasShipSpawn = true;
}
return new NewHorizonsBody(config, mod, relativePath); return new NewHorizonsBody(config, mod, relativePath);
} }
@ -1069,7 +1074,7 @@ namespace NewHorizons
{ {
IsWarpingFromVessel = true; IsWarpingFromVessel = true;
} }
else if (BodyDict.TryGetValue(DefaultSystemOverride, out var bodies) && bodies.Any(x => x.Config?.Spawn?.shipSpawn != null)) else if (BodyDict.TryGetValue(DefaultSystemOverride, out var bodies) && bodies.Any(x => x.Config?.Spawn?.shipSpawnPoints?.Any() ?? false))
{ {
IsWarpingFromShip = true; IsWarpingFromShip = true;
} }

View File

@ -261,7 +261,8 @@ namespace NewHorizons
public void DefineStarSystem(string name, string config, IModBehaviour mod) public void DefineStarSystem(string name, string config, IModBehaviour mod)
{ {
var starSystemConfig = JsonConvert.DeserializeObject<StarSystemConfig>(config); var starSystemConfig = JsonConvert.DeserializeObject<StarSystemConfig>(config);
Main.Instance.LoadStarSystemConfig(name, starSystemConfig, null, mod); starSystemConfig.name = name;
Main.Instance.LoadStarSystemConfig(starSystemConfig, null, mod);
} }
public (CharacterDialogueTree, RemoteDialogueTrigger) CreateDialogueFromXML(string textAssetID, string xml, string dialogueInfo, GameObject planetGO) public (CharacterDialogueTree, RemoteDialogueTrigger) CreateDialogueFromXML(string textAssetID, string xml, string dialogueInfo, GameObject planetGO)
@ -312,6 +313,7 @@ namespace NewHorizons
var system = new StarSystemConfig() var system = new StarSystemConfig()
{ {
name = starSystem,
entryPositions = entryPositions? entryPositions = entryPositions?
.Select((pair) => new EntryPositionInfo() { id = pair.Key, position = pair.Value }) .Select((pair) => new EntryPositionInfo() { id = pair.Key, position = pair.Value })
.ToArray(), .ToArray(),
@ -320,7 +322,7 @@ namespace NewHorizons
.ToArray() .ToArray()
}; };
Main.Instance.LoadStarSystemConfig(starSystem, system, null, mod); Main.Instance.LoadStarSystemConfig(system, null, mod);
RumorModeBuilder.AddShipLogXML(GameObject.FindObjectOfType<ShipLogManager>(), xml, body); RumorModeBuilder.AddShipLogXML(GameObject.FindObjectOfType<ShipLogManager>(), xml, body);
} }
@ -340,5 +342,7 @@ namespace NewHorizons
public string GetTranslationForOtherText(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.OTHER); public string GetTranslationForOtherText(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.OTHER);
public void AddSubtitle(IModBehaviour mod, string filePath) => SubtitlesHandler.RegisterAdditionalSubtitle(mod, filePath); public void AddSubtitle(IModBehaviour mod, string filePath) => SubtitlesHandler.RegisterAdditionalSubtitle(mod, filePath);
public void SetNextSpawnID(string id) => PlayerSpawnHandler.TargetSpawnID = id;
} }
} }

View File

@ -36,7 +36,7 @@
}, },
"subtitlePath": { "subtitlePath": {
"type": "string", "type": "string",
"description": "The path to the addons subtitle for the main menu.\nDefaults to \"subtitle.png\"." "description": "The path to the addons subtitle for the main menu.\nDefaults to \"subtitle.png\".\nThe dimensions of the Echoes of the Eye subtitle is 669 x 67, so aim for that size"
}, },
"$schema": { "$schema": {
"type": "string", "type": "string",

View File

@ -4,14 +4,10 @@
"type": "object", "type": "object",
"description": "Describes a celestial body to generate", "description": "Describes a celestial body to generate",
"additionalProperties": false, "additionalProperties": false,
"required": [
"name"
],
"properties": { "properties": {
"name": { "name": {
"type": "string", "type": "string",
"description": "Unique name of your planet", "description": "Unique name of your planet. If not specified, the file name (without the extension) is used."
"minLength": 1
}, },
"starSystem": { "starSystem": {
"type": "string", "type": "string",
@ -409,6 +405,11 @@
"description": "Maximum speed that your ship can go in the atmosphere where flames will appear at their brightest.", "description": "Maximum speed that your ship can go in the atmosphere where flames will appear at their brightest.",
"format": "float", "format": "float",
"default": 300.0 "default": 300.0
},
"allowShipAutoroll": {
"type": "boolean",
"description": "Will the ship automatically try to orient itself to face upwards while in this volume?",
"default": true
} }
} }
}, },
@ -547,9 +548,10 @@
"description": "Radius of a simple sphere used as the ground for the planet. If you want to use more complex terrain, leave this as\n0.", "description": "Radius of a simple sphere used as the ground for the planet. If you want to use more complex terrain, leave this as\n0.",
"format": "float" "format": "float"
}, },
"invulnerableToSun": { "hasFluidDetector": {
"type": "boolean", "type": "boolean",
"description": "Can this planet survive entering a star?" "description": "Is this planet able to detect fluid volumes? Disabling this means that entering a star or lava volume will not destroy this planet\nMay have adverse effects if anglerfish are added to this planet, disable this if you want those to work (they have fluid volumes in their mouths)",
"default": true
}, },
"showMinimap": { "showMinimap": {
"type": "boolean", "type": "boolean",
@ -568,7 +570,7 @@
}, },
"surfaceSize": { "surfaceSize": {
"type": "number", "type": "number",
"description": "A scale height used for a number of things. Should be the approximate radius of the body.", "description": "A scale height used for a number of things. Should be the approximate radius of the body.\n\nAffected settings include: Base sector size, proxy body scaling, surface gravity",
"format": "float" "format": "float"
}, },
"gravityVolumePriority": { "gravityVolumePriority": {
@ -621,12 +623,12 @@
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"fogTint": { "fogTint": {
"description": "The color of the fog inside this dimension. \nLeave blank for the default grayish color: (84, 83, 73)", "description": "The color of the fog inside this dimension. \nLeave blank for the default grayish color: (84, 83, 73)\nThe alpha value has no effect of the fog: Use fogDensity instead!",
"$ref": "#/definitions/MColor" "$ref": "#/definitions/MColor"
}, },
"fogDensity": { "fogDensity": {
"type": "number", "type": "number",
"description": "The density of the fog inside this dimension. The default is 6.", "description": "The density of the fog inside this dimension. The default is 6. If you want no fog, set this to 0.",
"format": "float", "format": "float",
"default": 6.0 "default": 6.0
}, },
@ -1118,7 +1120,6 @@
"type": "number", "type": "number",
"description": "The semi-major axis of the ellipse that is the body's orbit. For a circular orbit this is the radius.", "description": "The semi-major axis of the ellipse that is the body's orbit. For a circular orbit this is the radius.",
"format": "float", "format": "float",
"default": 5000.0,
"minimum": 0.0 "minimum": 0.0
}, },
"inclination": { "inclination": {
@ -1362,7 +1363,7 @@
}, },
"keepLoaded": { "keepLoaded": {
"type": "boolean", "type": "boolean",
"description": "Should this detail stay loaded (visible and collideable) even if you're outside the sector (good for very large props)?\nAlso makes this detail visible on the map.\nMost logic/behavior scripts will still only work inside the sector, as most of those scripts break if a sector is not provided." "description": "Should this detail stay loaded (visible and collideable) even if you're outside the sector (good for very large props)?\nAlso makes this detail visible on the map.\nKeeping many props loaded is bad for performance so use this only when it's actually relevant\nMost logic/behavior scripts will still only work inside the sector, as most of those scripts break if a sector is not provided."
}, },
"hasPhysics": { "hasPhysics": {
"type": "boolean", "type": "boolean",
@ -2721,6 +2722,10 @@
"type": "string", "type": "string",
"description": "If you want a black hole to load a new star system scene, put its name here." "description": "If you want a black hole to load a new star system scene, put its name here."
}, },
"spawnPointID": {
"type": "string",
"description": "If this is a black hole loading a new star system, set the ID of the spawn point you want to use\nOtherwise, will use the default spawn"
},
"type": { "type": {
"description": "Type of singularity (white hole or black hole)", "description": "Type of singularity (white hole or black hole)",
"$ref": "#/definitions/SingularityType" "$ref": "#/definitions/SingularityType"
@ -3618,15 +3623,21 @@
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"playerSpawn": { "playerSpawnPoints": {
"description": "If you want the player to spawn on the new body, set a value for this.", "type": "array",
"description": "If you want the player to spawn on the new body, set a value for this.\nDifferent spawns can be unlocked with persistent conditions and facts",
"items": {
"$ref": "#/definitions/PlayerSpawnPoint" "$ref": "#/definitions/PlayerSpawnPoint"
}
}, },
"shipSpawn": { "shipSpawnPoints": {
"description": "Required for the system to be accessible by warp drive.", "type": "array",
"description": "Required for the system to be accessible by warp drive.\nDifferent spawns can be unlocked with persistent conditions and facts",
"items": {
"$ref": "#/definitions/ShipSpawnPoint" "$ref": "#/definitions/ShipSpawnPoint"
} }
} }
}
}, },
"PlayerSpawnPoint": { "PlayerSpawnPoint": {
"type": "object", "type": "object",
@ -3636,6 +3647,22 @@
"description": "Offsets the player/ship by this local vector when spawning. Used to prevent spawning in the floor. Optional: defaults to (0, 4, 0).", "description": "Offsets the player/ship by this local vector when spawning. Used to prevent spawning in the floor. Optional: defaults to (0, 4, 0).",
"$ref": "#/definitions/MVector3" "$ref": "#/definitions/MVector3"
}, },
"isDefault": {
"type": "boolean",
"description": "Whether this planet's spawn point is the one the player/ship will initially spawn at, if multiple spawn points exist.\nDo not use at the same time as makeDefaultIfFactRevealed or makeDefaultIfPersistentCondition\nSpawns unlocked with this have lowest priority"
},
"makeDefaultIfFactRevealed": {
"type": "string",
"description": "If the given ship log fact is revealed, this spawn point will be used\nDo not use at the same time as isDefault or makeDefaultIfPersistentCondition\nSpawns unlocked with this have highest priority"
},
"makeDefaultIfPersistentCondition": {
"type": "string",
"description": "If the given persistent condition is true, this spawn point will be used\nDo not use at the same time as isDefault or makeDefaultIfFactRevealed\nSpawns unlocked with this have second highest priority"
},
"id": {
"type": "string",
"description": "ID used to have a black hole or warp volume bring the player to this spawn specifically"
},
"rotation": { "rotation": {
"description": "Rotation of the object", "description": "Rotation of the object",
"$ref": "#/definitions/MVector3" "$ref": "#/definitions/MVector3"
@ -3666,10 +3693,6 @@
"startWithSuit": { "startWithSuit": {
"type": "boolean", "type": "boolean",
"description": "If you spawn on a planet with no oxygen, you probably want to set this to true ;;)" "description": "If you spawn on a planet with no oxygen, you probably want to set this to true ;;)"
},
"isDefault": {
"type": "boolean",
"description": "Whether this planet's spawn point is the one the player will initially spawn at, if multiple spawn points exist."
} }
} }
}, },
@ -3681,6 +3704,22 @@
"description": "Offsets the player/ship by this local vector when spawning. Used to prevent spawning in the floor. Optional: defaults to (0, 4, 0).", "description": "Offsets the player/ship by this local vector when spawning. Used to prevent spawning in the floor. Optional: defaults to (0, 4, 0).",
"$ref": "#/definitions/MVector3" "$ref": "#/definitions/MVector3"
}, },
"isDefault": {
"type": "boolean",
"description": "Whether this planet's spawn point is the one the player/ship will initially spawn at, if multiple spawn points exist.\nDo not use at the same time as makeDefaultIfFactRevealed or makeDefaultIfPersistentCondition\nSpawns unlocked with this have lowest priority"
},
"makeDefaultIfFactRevealed": {
"type": "string",
"description": "If the given ship log fact is revealed, this spawn point will be used\nDo not use at the same time as isDefault or makeDefaultIfPersistentCondition\nSpawns unlocked with this have highest priority"
},
"makeDefaultIfPersistentCondition": {
"type": "string",
"description": "If the given persistent condition is true, this spawn point will be used\nDo not use at the same time as isDefault or makeDefaultIfFactRevealed\nSpawns unlocked with this have second highest priority"
},
"id": {
"type": "string",
"description": "ID used to have a black hole or warp volume bring the player to this spawn specifically"
},
"rotation": { "rotation": {
"description": "Rotation of the object", "description": "Rotation of the object",
"$ref": "#/definitions/MVector3" "$ref": "#/definitions/MVector3"
@ -3907,6 +3946,11 @@
"tint": { "tint": {
"description": "Tint of the water", "description": "Tint of the water",
"$ref": "#/definitions/MColor" "$ref": "#/definitions/MColor"
},
"allowShipAutoroll": {
"type": "boolean",
"description": "Will the ship automatically try to orient itself to face upwards while in this volume?",
"default": true
} }
} }
}, },
@ -5162,6 +5206,10 @@
"type": "string", "type": "string",
"description": "The star system that entering this volume will send you to.", "description": "The star system that entering this volume will send you to.",
"default": "SolarSystem" "default": "SolarSystem"
},
"spawnPointID": {
"type": "string",
"description": "ID assigned to a spawn point in the other system that the player will be sent to\nUses the default spawn if not set"
} }
} }
}, },

View File

@ -81,7 +81,7 @@
<xs:element name="AltPhotoCondition" type="xs:string" minOccurs="0" maxOccurs="1"> <xs:element name="AltPhotoCondition" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation> <xs:annotation>
<xs:documentation> <xs:documentation>
If this fact is revealed, show the Alt picture If this fact is revealed, show the Alt picture. Alt photos use the same file name as default but suffixed with "_alt"
</xs:documentation> </xs:documentation>
</xs:annotation> </xs:annotation>
</xs:element> </xs:element>

View File

@ -5,6 +5,10 @@
"description": "Configuration for a specific star system", "description": "Configuration for a specific star system",
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"name": {
"type": "string",
"description": "Unique name of your system. If not specified, the file name (without the extension) is used."
},
"freeMapAngle": { "freeMapAngle": {
"type": "boolean", "type": "boolean",
"description": "In this system should the player be able to rotate their map camera freely or be stuck above the plane of the solar system?" "description": "In this system should the player be able to rotate their map camera freely or be stuck above the plane of the solar system?"

View File

@ -124,7 +124,7 @@ namespace NewHorizons.Utility.Files
// Not sure why we check if the originalPath is null but it did that before so // Not sure why we check if the originalPath is null but it did that before so
if (!string.IsNullOrEmpty(originalPath)) if (!string.IsNullOrEmpty(originalPath))
{ {
cachedPath = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.INVERTED_SLIDE_CACHE_FOLDER, originalPath.Replace(mod.ModHelper.Manifest.ModFolderPath, "")); cachedPath = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.InvertedSlideReelCacheFolder, originalPath.Replace(mod.ModHelper.Manifest.ModFolderPath, ""));
key = GetKey(cachedPath); key = GetKey(cachedPath);
} }
@ -226,7 +226,7 @@ namespace NewHorizons.Utility.Files
// Since doing this is expensive we cache the results to the disk // Since doing this is expensive we cache the results to the disk
// Preloading cached values is done in ProjectionBuilder // Preloading cached values is done in ProjectionBuilder
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.ATLAS_SLIDE_CACHE_FOLDER, $"{uniqueSlideReelID}.png"); var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ProjectionBuilder.AtlasSlideReelCacheFolder, $"{uniqueSlideReelID}.png");
NHLogger.LogVerbose($"Caching atlas image to {path}"); NHLogger.LogVerbose($"Caching atlas image to {path}");
Directory.CreateDirectory(Path.GetDirectoryName(path)); Directory.CreateDirectory(Path.GetDirectoryName(path));
File.WriteAllBytes(path, texture.EncodeToPNG()); File.WriteAllBytes(path, texture.EncodeToPNG());

View File

@ -1,3 +1,4 @@
using NewHorizons.Builder.Props;
using NewHorizons.Utility.OWML; using NewHorizons.Utility.OWML;
using System; using System;
using System.Collections; using System.Collections;
@ -115,7 +116,7 @@ public class SlideReelAsyncImageLoader
if (hasError) if (hasError)
{ {
NHLogger.LogError($"Failed to load {index}:{url} - {uwr.error}"); NHLogger.LogError($"Failed to load {index}:{url} - {uwr.error}");
if (url.Contains("SlideReelCache")) if (url.Contains(ProjectionBuilder.CurrentSlideReelFolder))
{ {
NHLogger.LogError("Missing image in SlideReelCache: If you are a dev, try deleting the folder so that New Horizons can regenerate the cache. If you are a player: do that and then complain to the mod dev."); NHLogger.LogError("Missing image in SlideReelCache: If you are a dev, try deleting the folder so that New Horizons can regenerate the cache. If you are a player: do that and then complain to the mod dev.");
} }

View File

@ -1,10 +1,10 @@
{ {
"$schema": "https://raw.githubusercontent.com/amazingalek/owml/master/schemas/manifest_schema.json", "$schema": "https://raw.githubusercontent.com/amazingalek/owml/master/schemas/manifest_schema.json",
"filename": "NewHorizons.dll", "filename": "NewHorizons.dll",
"author": "xen, Bwc9876, JohnCorby, MegaPiggy, Clay, Trifid, and friends", "author": "xen, Bwc9876, JohnCorby, MegaPiggy, Trifid, and friends",
"name": "New Horizons", "name": "New Horizons",
"uniqueName": "xen.NewHorizons", "uniqueName": "xen.NewHorizons",
"version": "1.22.7", "version": "1.22.8",
"owmlVersion": "2.12.1", "owmlVersion": "2.12.1",
"dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ], "dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
"conflicts": [ "PacificEngine.OW_CommonResources" ], "conflicts": [ "PacificEngine.OW_CommonResources" ],

View File

@ -81,7 +81,6 @@ public static class SchemaExporter
switch (_title) switch (_title)
{ {
case "Celestial Body Schema": case "Celestial Body Schema":
schema.Definitions["OrbitModule"].Properties["semiMajorAxis"].Default = 5000f;
schema.Definitions["NomaiTextType"].Enumeration.Remove("cairn"); schema.Definitions["NomaiTextType"].Enumeration.Remove("cairn");
schema.Definitions["NomaiTextType"].EnumerationNames.Remove("Cairn"); schema.Definitions["NomaiTextType"].EnumerationNames.Remove("Cairn");
schema.Definitions["NomaiTextType"].Enumeration.Remove("cairnVariant"); schema.Definitions["NomaiTextType"].Enumeration.Remove("cairnVariant");

View File

@ -12,18 +12,18 @@
"format": "prettier --write ." "format": "prettier --write ."
}, },
"dependencies": { "dependencies": {
"@astrojs/starlight": "^0.19.1", "@astrojs/starlight": "^0.24.2",
"astro": "4.4.1", "astro": "4.10.2",
"rehype-external-links": "^3.0.0", "rehype-external-links": "^3.0.0",
"sharp": "^0.33.2" "sharp": "^0.33.4"
}, },
"devDependencies": { "devDependencies": {
"@apidevtools/json-schema-ref-parser": "^11.1.0", "@apidevtools/json-schema-ref-parser": "^11.6.4",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"fast-xml-parser": "^4.3.4", "fast-xml-parser": "^4.4.0",
"prettier": "^3.2.5", "prettier": "^3.3.2",
"prettier-plugin-astro": "^0.13.0", "prettier-plugin-astro": "^0.14.0",
"xml-js": "^1.6.11" "xml-js": "^1.6.11"
} }
} }

2559
docs/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
---
title: Troubleshooting
description: A guide to troubleshooting common issues with mods
---
## My slide reels aren't updating when I change them
Certain images (such as slide reels) get modified by New Horizons before usage, to save on resources NH will cache
the modified version of these images on the file system to be recalled later for easier access. If you are changing
an image you'll need to clear the cache located in the `SlideReelsCache` folder of your mod's directory to see changes. To do this simply delete the folder and restart the game.
## My planet is flying away at light speed and also I have anglerfish
Be sure to disable `hasFluidDetector` (previous had to enable `invulnerableToSun`). The anglerfish have fluid volumes in their mouths for killing you
which interact poorly with the fluid detector and can mess up the movement of the planet.
## My Nomai text isn't updating
Either clear the .nhcache files or enable Debug mode to always regenerate the text cache.