From 3f92573c4ce0f206ec0dd10b4b98fc76a7adb0e0 Mon Sep 17 00:00:00 2001 From: xen-42 Date: Fri, 4 Oct 2024 12:33:01 -0400 Subject: [PATCH 01/10] Allow making multiple spawns and choosing which with fact or persistent condition --- .../Builder/General/SpawnPointBuilder.cs | 18 +++++--- NewHorizons/External/Modules/SpawnModule.cs | 41 ++++++++++++++++--- NewHorizons/Handlers/PlanetCreationHandler.cs | 2 +- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/NewHorizons/Builder/General/SpawnPointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs index cc7feddf..bce32058 100644 --- a/NewHorizons/Builder/General/SpawnPointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -42,15 +42,21 @@ namespace NewHorizons.Builder.General spawnGO.SetActive(false); spawnGO.layer = Layer.PlayerSafetyCollider; - ShipSpawn = spawnGO.AddComponent(); - ShipSpawn._isShipSpawn = true; - ShipSpawn._attachedBody = owRigidBody; - ShipSpawn._spawnLocation = SpawnLocation.None; + var shipSpawn = spawnGO.AddComponent(); + shipSpawn._isShipSpawn = true; + shipSpawn._attachedBody = owRigidBody; + shipSpawn._spawnLocation = SpawnLocation.None; // #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 = module.shipSpawn.offset ?? (module.shipSpawn.alignRadial.GetValueOrDefault() ? Vector3.up * 4 : Vector3.zero); + + if (ShipSpawn == null || module.shipSpawn.IsDefault()) + { + ShipSpawn = shipSpawn; + ShipSpawnOffset = shipSpawnOffset; + } spawnGO.SetActive(true); } diff --git a/NewHorizons/External/Modules/SpawnModule.cs b/NewHorizons/External/Modules/SpawnModule.cs index f8af3fa1..8b70bb3c 100644 --- a/NewHorizons/External/Modules/SpawnModule.cs +++ b/NewHorizons/External/Modules/SpawnModule.cs @@ -1,4 +1,5 @@ using NewHorizons.External.SerializableData; +using NewHorizons.Handlers; using Newtonsoft.Json; using System; @@ -30,6 +31,40 @@ 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). /// public MVector3 offset; + + /// + /// 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 + /// + public bool isDefault; + + /// + /// 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 + /// + public string makeDefaultIfFactRevealed; + + /// + /// If the given persistent condition is true, this spawn point will be used + /// Do not use at the same time as isDefault or makeDefaultIfFactRevealed + /// + public string makeDefaultIfPersistentCondition; + + public bool IsDefault() + { + if (!string.IsNullOrEmpty(makeDefaultIfFactRevealed) && ShipLogHandler.KnowsFact(makeDefaultIfFactRevealed)) + { + return true; + } + if (!string.IsNullOrEmpty(makeDefaultIfPersistentCondition) && PlayerData.GetPersistentCondition(makeDefaultIfPersistentCondition)) + { + return true; + } + else + { + return isDefault; + } + } } [JsonObject] @@ -39,12 +74,6 @@ namespace NewHorizons.External.Modules /// If you spawn on a planet with no oxygen, you probably want to set this to true ;;) /// public bool startWithSuit; - /// - /// Whether this planet's spawn point is the one the player will initially spawn at, if multiple spawn points exist. - /// - public bool isDefault; - - } [JsonObject] diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index fda247e7..fe68519f 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -504,7 +504,7 @@ namespace NewHorizons.Handlers 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 + var isDefaultSpawn = body.Config.Spawn.playerSpawn?.IsDefault() ?? true; // Backwards compat if (needsSpawnPoint || isDefaultSpawn) { Main.SystemDict[body.Config.starSystem].SpawnPoint = spawnPoint; From 25aceb676d15c6ece43d9550f2e5cdbe4aba0bb3 Mon Sep 17 00:00:00 2001 From: xen-42 Date: Fri, 4 Oct 2024 12:47:22 -0400 Subject: [PATCH 02/10] Should actually work now with priorities --- .../Builder/General/SpawnPointBuilder.cs | 22 ++++++++++++++++++- NewHorizons/External/Modules/SpawnModule.cs | 15 +++++++++---- NewHorizons/External/NewHorizonsSystem.cs | 4 +--- NewHorizons/Handlers/PlanetCreationHandler.cs | 7 ------ NewHorizons/Handlers/PlayerSpawnHandler.cs | 4 ++-- NewHorizons/Handlers/StarChartHandler.cs | 2 +- NewHorizons/Handlers/VesselWarpHandler.cs | 3 ++- NewHorizons/Main.cs | 9 +++++--- 8 files changed, 44 insertions(+), 22 deletions(-) diff --git a/NewHorizons/Builder/General/SpawnPointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs index bce32058..c04cf8cf 100644 --- a/NewHorizons/Builder/General/SpawnPointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -13,9 +13,22 @@ namespace NewHorizons.Builder.General public static class SpawnPointBuilder { private static bool suitUpQueued = false; + + // Ship + public static SpawnModule.ShipSpawnPoint ShipSpawnInfo { get; private set; } public static SpawnPoint ShipSpawn { 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) { SpawnPoint playerSpawn = null; @@ -34,6 +47,12 @@ namespace NewHorizons.Builder.General // 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); + + if (PlayerSpawn == null || module.playerSpawn.GetPriority() > PlayerSpawnInfo.GetPriority()) + { + PlayerSpawn = playerSpawn; + PlayerSpawnInfo = module.playerSpawn; + } } if (module.shipSpawn != null) @@ -52,10 +71,11 @@ namespace NewHorizons.Builder.General var shipSpawnOffset = module.shipSpawn.offset ?? (module.shipSpawn.alignRadial.GetValueOrDefault() ? Vector3.up * 4 : Vector3.zero); - if (ShipSpawn == null || module.shipSpawn.IsDefault()) + if (ShipSpawn == null || module.shipSpawn.GetPriority() > ShipSpawnInfo.GetPriority()) { ShipSpawn = shipSpawn; ShipSpawnOffset = shipSpawnOffset; + ShipSpawnInfo = module.shipSpawn; } spawnGO.SetActive(true); diff --git a/NewHorizons/External/Modules/SpawnModule.cs b/NewHorizons/External/Modules/SpawnModule.cs index 8b70bb3c..1105ca06 100644 --- a/NewHorizons/External/Modules/SpawnModule.cs +++ b/NewHorizons/External/Modules/SpawnModule.cs @@ -35,34 +35,41 @@ namespace NewHorizons.External.Modules /// /// 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 /// public bool isDefault; /// /// 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 /// public string makeDefaultIfFactRevealed; /// /// 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 /// public string makeDefaultIfPersistentCondition; - public bool IsDefault() + public int GetPriority() { if (!string.IsNullOrEmpty(makeDefaultIfFactRevealed) && ShipLogHandler.KnowsFact(makeDefaultIfFactRevealed)) { - return true; + return 2; } if (!string.IsNullOrEmpty(makeDefaultIfPersistentCondition) && PlayerData.GetPersistentCondition(makeDefaultIfPersistentCondition)) { - return true; + return 1; + } + if (isDefault) + { + return 0; } else { - return isDefault; + return -1; } } } diff --git a/NewHorizons/External/NewHorizonsSystem.cs b/NewHorizons/External/NewHorizonsSystem.cs index 07f1ba08..f4928f17 100644 --- a/NewHorizons/External/NewHorizonsSystem.cs +++ b/NewHorizons/External/NewHorizonsSystem.cs @@ -1,5 +1,4 @@ using NewHorizons.External.Configs; -using NewHorizons.External.Modules; using OWML.Common; using System.Linq; @@ -9,10 +8,9 @@ namespace NewHorizons.External { public string UniqueID; public string RelativePath; - public SpawnModule Spawn = null; - public SpawnPoint SpawnPoint = null; public StarSystemConfig Config; public IModBehaviour Mod; + public bool HasShipSpawn; public NewHorizonsSystem(string uniqueID, StarSystemConfig config, string relativePath, IModBehaviour mod) { diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index fe68519f..44d083c4 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -502,13 +502,6 @@ namespace NewHorizons.Handlers { NHLogger.LogVerbose($"Making spawn point on {body.Config.name}"); 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) diff --git a/NewHorizons/Handlers/PlayerSpawnHandler.cs b/NewHorizons/Handlers/PlayerSpawnHandler.cs index dd4f4f27..af78874a 100644 --- a/NewHorizons/Handlers/PlayerSpawnHandler.cs +++ b/NewHorizons/Handlers/PlayerSpawnHandler.cs @@ -200,8 +200,8 @@ namespace NewHorizons.Handlers 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(); - public static SpawnPoint GetDefaultSpawn() => Main.SystemDict[Main.Instance.CurrentStarSystem].SpawnPoint ?? GetPlayerSpawner().GetSpawnPoint(SpawnLocation.TimberHearth); + public static SpawnPoint GetDefaultSpawn() => SpawnPointBuilder.PlayerSpawn ?? GetPlayerSpawner().GetSpawnPoint(SpawnLocation.TimberHearth); } } diff --git a/NewHorizons/Handlers/StarChartHandler.cs b/NewHorizons/Handlers/StarChartHandler.cs index d063abcc..3435fd19 100644 --- a/NewHorizons/Handlers/StarChartHandler.cs +++ b/NewHorizons/Handlers/StarChartHandler.cs @@ -130,7 +130,7 @@ namespace NewHorizons.Handlers var canWarpTo = false; if (system.Equals("SolarSystem")) canWarpTo = true; 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"; diff --git a/NewHorizons/Handlers/VesselWarpHandler.cs b/NewHorizons/Handlers/VesselWarpHandler.cs index 26195e5c..bac8fdf7 100644 --- a/NewHorizons/Handlers/VesselWarpHandler.cs +++ b/NewHorizons/Handlers/VesselWarpHandler.cs @@ -1,3 +1,4 @@ +using NewHorizons.Builder.General; using NewHorizons.Builder.Props; using NewHorizons.Components; using NewHorizons.Components.EyeOfTheUniverse; @@ -240,7 +241,7 @@ namespace NewHorizons.Handlers VesselSpawnPoint spawnPoint = vesselObject.GetComponentInChildren(true); if (ShouldSpawnAtVessel()) { - system.SpawnPoint = spawnPoint; + SpawnPointBuilder.OverridePlayerSpawn(spawnPoint); } vesselObject.SetActive(true); diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index f8f18718..0eb502ab 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -789,9 +789,6 @@ namespace NewHorizons 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 if (!BodyDict.ContainsKey(body.Config.starSystem)) BodyDict[body.Config.starSystem] = new List(); BodyDict[body.Config.starSystem].Add(body); @@ -924,6 +921,12 @@ namespace NewHorizons config.Validate(); config.Migrate(); + // Check if this system can be warped to + if (config.Spawn?.shipSpawn != null) + { + SystemDict[config.starSystem].HasShipSpawn = true; + } + return new NewHorizonsBody(config, mod, relativePath); } From 9fe2845900c9485399c251a8101f6c09ad3ba6a8 Mon Sep 17 00:00:00 2001 From: Ben C Date: Fri, 4 Oct 2024 16:48:58 +0000 Subject: [PATCH 03/10] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 6582e215..75aee4e0 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -3631,6 +3631,18 @@ "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" }, + "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" + }, "rotation": { "description": "Rotation of the object", "$ref": "#/definitions/MVector3" @@ -3661,10 +3673,6 @@ "startWithSuit": { "type": "boolean", "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." } } }, @@ -3676,6 +3684,18 @@ "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" }, + "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" + }, "rotation": { "description": "Rotation of the object", "$ref": "#/definitions/MVector3" From be97d815ae2bbba1839a02a2845834e5b7701559 Mon Sep 17 00:00:00 2001 From: xen-42 Date: Fri, 4 Oct 2024 13:17:55 -0400 Subject: [PATCH 04/10] Allow multiple spawn points --- .../Builder/General/SpawnPointBuilder.cs | 91 +++++++++++-------- NewHorizons/External/Configs/PlanetConfig.cs | 17 ++++ NewHorizons/External/Modules/SpawnModule.cs | 10 +- NewHorizons/External/NewHorizonBody.cs | 6 -- NewHorizons/Main.cs | 4 +- 5 files changed, 80 insertions(+), 48 deletions(-) diff --git a/NewHorizons/Builder/General/SpawnPointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs index c04cf8cf..b047a69b 100644 --- a/NewHorizons/Builder/General/SpawnPointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -34,57 +34,70 @@ namespace NewHorizons.Builder.General SpawnPoint playerSpawn = null; // 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); - spawnGO.layer = Layer.PlayerSafetyCollider; - - playerSpawn = spawnGO.AddComponent(); - playerSpawn._attachedBody = owRigidBody; - playerSpawn._spawnLocation = SpawnLocation.None; - // #601 we need to actually set the right trigger volumes here - 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 - spawnGO.transform.position += spawnGO.transform.TransformDirection(module.playerSpawn.offset ?? Vector3.up * 4f); - - if (PlayerSpawn == null || module.playerSpawn.GetPriority() > PlayerSpawnInfo.GetPriority()) + foreach (var point in module.playerSpawnPoints) { - PlayerSpawn = playerSpawn; - PlayerSpawnInfo = module.playerSpawn; + GameObject spawnGO = GeneralPropBuilder.MakeNew("PlayerSpawnPoint", planetGO, null, point); + spawnGO.layer = Layer.PlayerSafetyCollider; + + playerSpawn = spawnGO.AddComponent(); + playerSpawn._attachedBody = owRigidBody; + playerSpawn._spawnLocation = SpawnLocation.None; + // #601 we need to actually set the right trigger volumes here + 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 + 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); - spawnGO.SetActive(false); - spawnGO.layer = Layer.PlayerSafetyCollider; - - var shipSpawn = spawnGO.AddComponent(); - shipSpawn._isShipSpawn = true; - shipSpawn._attachedBody = owRigidBody; - shipSpawn._spawnLocation = SpawnLocation.None; - - // #601 we need to actually set the right trigger volumes here - shipSpawn._triggerVolumes = new OWTriggerVolume[0]; - - var shipSpawnOffset = module.shipSpawn.offset ?? (module.shipSpawn.alignRadial.GetValueOrDefault() ? Vector3.up * 4 : Vector3.zero); - - if (ShipSpawn == null || module.shipSpawn.GetPriority() > ShipSpawnInfo.GetPriority()) + foreach (var point in module.shipSpawnPoints) { - ShipSpawn = shipSpawn; - ShipSpawnOffset = shipSpawnOffset; - ShipSpawnInfo = module.shipSpawn; - } + var spawnGO = GeneralPropBuilder.MakeNew("ShipSpawnPoint", planetGO, null, point); + spawnGO.SetActive(false); + spawnGO.layer = Layer.PlayerSafetyCollider; - spawnGO.SetActive(true); + var shipSpawn = spawnGO.AddComponent(); + shipSpawn._isShipSpawn = true; + shipSpawn._attachedBody = owRigidBody; + shipSpawn._spawnLocation = SpawnLocation.None; + + // #601 we need to actually set the right trigger volumes here + shipSpawn._triggerVolumes = new OWTriggerVolume[0]; + + 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); + } } - 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; - Delay.RunWhen(() => Main.IsSystemReady, SuitUp); + Delay.RunWhen(() => Main.IsSystemReady, () => + { + if (Main.Instance.IsWarpingFromVessel || (!Main.Instance.IsWarpingFromShip && (PlayerSpawnInfo?.startWithSuit ?? false))) + { + SuitUp(); + } + }); } NHLogger.Log($"Made spawnpoint on [{planetGO.name}]"); diff --git a/NewHorizons/External/Configs/PlanetConfig.cs b/NewHorizons/External/Configs/PlanetConfig.cs index f1828c7d..f64b7b13 100644 --- a/NewHorizons/External/Configs/PlanetConfig.cs +++ b/NewHorizons/External/Configs/PlanetConfig.cs @@ -1,3 +1,4 @@ +using Epic.OnlineServices; using NewHorizons.External.Modules; using NewHorizons.External.Modules.Props; using NewHorizons.External.Modules.Props.Audio; @@ -540,6 +541,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 if (Props?.dialogue != null) { diff --git a/NewHorizons/External/Modules/SpawnModule.cs b/NewHorizons/External/Modules/SpawnModule.cs index 1105ca06..ddfeadcf 100644 --- a/NewHorizons/External/Modules/SpawnModule.cs +++ b/NewHorizons/External/Modules/SpawnModule.cs @@ -10,12 +10,20 @@ namespace NewHorizons.External.Modules { /// /// 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 /// - public PlayerSpawnPoint playerSpawn; + public PlayerSpawnPoint[] playerSpawnPoints; /// /// Required for the system to be accessible by warp drive. + /// Different spawns can be unlocked with persistent conditions and facts /// + public ShipSpawnPoint[] shipSpawnPoints; + + [Obsolete("Use playerSpawnPoints instead")] + public PlayerSpawnPoint playerSpawn; + + [Obsolete("Use shipSpawnPoints instead")] public ShipSpawnPoint shipSpawn; [Obsolete("playerSpawnPoint is deprecated. Use playerSpawn.position instead")] public MVector3 playerSpawnPoint; diff --git a/NewHorizons/External/NewHorizonBody.cs b/NewHorizons/External/NewHorizonBody.cs index a38af522..14da7b49 100644 --- a/NewHorizons/External/NewHorizonBody.cs +++ b/NewHorizons/External/NewHorizonBody.cs @@ -106,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 diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 0eb502ab..7b540e69 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -922,7 +922,7 @@ namespace NewHorizons config.Migrate(); // Check if this system can be warped to - if (config.Spawn?.shipSpawn != null) + if (config.Spawn?.shipSpawnPoints?.Any() ?? false) { SystemDict[config.starSystem].HasShipSpawn = true; } @@ -1074,7 +1074,7 @@ namespace NewHorizons { 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; } From 609b7bfd095276a6ae43f1e7dd27d5ba7c819254 Mon Sep 17 00:00:00 2001 From: Ben C Date: Fri, 4 Oct 2024 17:19:12 +0000 Subject: [PATCH 05/10] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 75aee4e0..16ed48c3 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -3613,13 +3613,19 @@ "type": "object", "additionalProperties": false, "properties": { - "playerSpawn": { - "description": "If you want the player to spawn on the new body, set a value for this.", - "$ref": "#/definitions/PlayerSpawnPoint" + "playerSpawnPoints": { + "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" + } }, - "shipSpawn": { - "description": "Required for the system to be accessible by warp drive.", - "$ref": "#/definitions/ShipSpawnPoint" + "shipSpawnPoints": { + "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" + } } } }, From 918b093ea32f094ceaf3db96452d4a53620da223 Mon Sep 17 00:00:00 2001 From: xen-42 Date: Fri, 4 Oct 2024 13:25:31 -0400 Subject: [PATCH 06/10] Use save data directly for checking facts --- NewHorizons/Handlers/ShipLogHandler.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/NewHorizons/Handlers/ShipLogHandler.cs b/NewHorizons/Handlers/ShipLogHandler.cs index 84cbb203..7f9a6e14 100644 --- a/NewHorizons/Handlers/ShipLogHandler.cs +++ b/NewHorizons/Handlers/ShipLogHandler.cs @@ -114,10 +114,8 @@ namespace NewHorizons.Handlers public static bool KnowsFact(string fact) { - // Works normally in the main system, else check save data directly - var shipLogManager = Locator.GetShipLogManager(); - if (Main.Instance.CurrentStarSystem == "SolarSystem" && shipLogManager != null) return shipLogManager.IsFactRevealed(fact); - else return PlayerData.GetShipLogFactSave(fact)?.revealOrder > -1; + // Use save data directly so stuff works between systems + return PlayerData.GetShipLogFactSave(fact)?.revealOrder > -1; } } } From d2f88ed9adb08f4a70bf6b983c6ab64006c877c5 Mon Sep 17 00:00:00 2001 From: xen-42 Date: Fri, 4 Oct 2024 13:46:06 -0400 Subject: [PATCH 07/10] After enabling exiting via warp drive, only enable if we actually have a system --- NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs | 2 +- NewHorizons/Handlers/StarChartHandler.cs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs b/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs index 86d6cfa8..cc5636eb 100644 --- a/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs +++ b/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs @@ -211,7 +211,7 @@ namespace NewHorizons.Components.ShipLog { 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; } diff --git a/NewHorizons/Handlers/StarChartHandler.cs b/NewHorizons/Handlers/StarChartHandler.cs index 3435fd19..27844c5b 100644 --- a/NewHorizons/Handlers/StarChartHandler.cs +++ b/NewHorizons/Handlers/StarChartHandler.cs @@ -156,15 +156,20 @@ namespace NewHorizons.Handlers _canExitViaWarpDrive = true; if (!Main.HasWarpDrive) { - Main.Instance.EnableWarpDrive(); + var flagActuallyAddedACard = false; // Add all cards that now work foreach (var starSystem in Main.SystemDict.Keys) { if (CanWarpToSystem(starSystem)) { ShipLogStarChartMode.AddSystemCard(starSystem); + flagActuallyAddedACard = true; } } + if (flagActuallyAddedACard) + { + Main.Instance.EnableWarpDrive(); + } } else { From 4a80fa70761d1929c79eae910ac33e38ff26f39c Mon Sep 17 00:00:00 2001 From: xen-42 Date: Fri, 4 Oct 2024 15:04:50 -0400 Subject: [PATCH 08/10] Allow system change volumes to specify custom targets #917 --- .../Builder/Body/SingularityBuilder.cs | 28 +++++++++---------- .../Builder/General/SpawnPointBuilder.cs | 2 +- .../Volumes/ChangeStarSystemVolumeBuilder.cs | 1 + .../Components/Volumes/BlackHoleWarpVolume.cs | 4 +++ NewHorizons/Components/Volumes/WarpVolume.cs | 3 ++ NewHorizons/External/Modules/SpawnModule.cs | 10 +++++++ .../Modules/VariableSize/SingularityModule.cs | 6 ++++ .../VolumeInfos/ChangeStarSystemVolumeInfo.cs | 6 ++++ NewHorizons/Handlers/PlayerSpawnHandler.cs | 8 ++++++ 9 files changed, 53 insertions(+), 15 deletions(-) diff --git a/NewHorizons/Builder/Body/SingularityBuilder.cs b/NewHorizons/Builder/Body/SingularityBuilder.cs index a961c9d5..eb8863c8 100644 --- a/NewHorizons/Builder/Body/SingularityBuilder.cs +++ b/NewHorizons/Builder/Body/SingularityBuilder.cs @@ -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.Utility.OWML; -using NewHorizons.Utility.OuterWilds; -using NewHorizons.External.SerializableData; 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.Collections.Generic; +using UnityEngine; +using Color = UnityEngine.Color; namespace NewHorizons.Builder.Body { @@ -88,7 +87,7 @@ namespace NewHorizons.Builder.Body Vector3 localRotation = singularity?.rotation == null ? Vector3.zero : singularity.rotation; 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; @@ -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, - 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 @@ -233,6 +232,7 @@ namespace NewHorizons.Builder.Body { var wormholeVolume = destructionVolumeGO.AddComponent(); wormholeVolume.TargetSolarSystem = targetStarSystem; + wormholeVolume.TargetSpawnID = targetSpawnID; } } else diff --git a/NewHorizons/Builder/General/SpawnPointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs index f5ad5728..0e1eee40 100644 --- a/NewHorizons/Builder/General/SpawnPointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -94,6 +94,7 @@ namespace NewHorizons.Builder.General suitUpQueued = true; Delay.RunWhen(() => Main.IsSystemReady, () => { + suitUpQueued = false; if (Main.Instance.IsWarpingFromVessel || (!Main.Instance.IsWarpingFromShip && (PlayerSpawnInfo?.startWithSuit ?? false))) { SuitUp(); @@ -108,7 +109,6 @@ namespace NewHorizons.Builder.General public static void SuitUp() { - suitUpQueued = false; if (!Locator.GetPlayerController()._isWearingSuit) { Locator.GetPlayerSuit().SuitUp(false, true, true); diff --git a/NewHorizons/Builder/Volumes/ChangeStarSystemVolumeBuilder.cs b/NewHorizons/Builder/Volumes/ChangeStarSystemVolumeBuilder.cs index c3b8c5db..5557da98 100644 --- a/NewHorizons/Builder/Volumes/ChangeStarSystemVolumeBuilder.cs +++ b/NewHorizons/Builder/Volumes/ChangeStarSystemVolumeBuilder.cs @@ -11,6 +11,7 @@ namespace NewHorizons.Builder.Volumes var volume = VolumeBuilder.Make(planetGO, sector, info); volume.TargetSolarSystem = info.targetStarSystem; + volume.TargetSpawnID = info.spawnPointID; return volume; } diff --git a/NewHorizons/Components/Volumes/BlackHoleWarpVolume.cs b/NewHorizons/Components/Volumes/BlackHoleWarpVolume.cs index bd99fee5..941bff2b 100644 --- a/NewHorizons/Components/Volumes/BlackHoleWarpVolume.cs +++ b/NewHorizons/Components/Volumes/BlackHoleWarpVolume.cs @@ -1,8 +1,11 @@ +using NewHorizons.Handlers; + namespace NewHorizons.Components.Volumes { public class BlackHoleWarpVolume : BlackHoleDestructionVolume { public string TargetSolarSystem { get; set; } + public string TargetSpawnID { get; set; } public override void Awake() { @@ -19,6 +22,7 @@ namespace NewHorizons.Components.Volumes { Locator.GetPlayerAudioController().PlayOneShotInternal(AudioType.BH_BlackHoleEmission); Main.Instance.ChangeCurrentStarSystem(TargetSolarSystem, PlayerState.AtFlightConsole()); + PlayerSpawnHandler.TargetSpawnID = TargetSpawnID; } } } diff --git a/NewHorizons/Components/Volumes/WarpVolume.cs b/NewHorizons/Components/Volumes/WarpVolume.cs index fa07d6e4..25892833 100644 --- a/NewHorizons/Components/Volumes/WarpVolume.cs +++ b/NewHorizons/Components/Volumes/WarpVolume.cs @@ -1,3 +1,4 @@ +using NewHorizons.Handlers; using UnityEngine; namespace NewHorizons.Components.Volumes @@ -5,6 +6,7 @@ namespace NewHorizons.Components.Volumes internal class WarpVolume : BaseVolume { public string TargetSolarSystem; + public string TargetSpawnID; 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 { Main.Instance.ChangeCurrentStarSystem(TargetSolarSystem, PlayerState.AtFlightConsole()); + PlayerSpawnHandler.TargetSpawnID = TargetSpawnID; } } } diff --git a/NewHorizons/External/Modules/SpawnModule.cs b/NewHorizons/External/Modules/SpawnModule.cs index ddfeadcf..3c62766a 100644 --- a/NewHorizons/External/Modules/SpawnModule.cs +++ b/NewHorizons/External/Modules/SpawnModule.cs @@ -1,3 +1,4 @@ +using NewHorizons.Builder.General; using NewHorizons.External.SerializableData; using NewHorizons.Handlers; using Newtonsoft.Json; @@ -61,8 +62,17 @@ namespace NewHorizons.External.Modules /// public string makeDefaultIfPersistentCondition; + /// + /// ID used to have a black hole or warp volume bring the player to this spawn specifically + /// + 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; diff --git a/NewHorizons/External/Modules/VariableSize/SingularityModule.cs b/NewHorizons/External/Modules/VariableSize/SingularityModule.cs index d85a399c..042cbe02 100644 --- a/NewHorizons/External/Modules/VariableSize/SingularityModule.cs +++ b/NewHorizons/External/Modules/VariableSize/SingularityModule.cs @@ -54,6 +54,12 @@ namespace NewHorizons.External.Modules.VariableSize /// public string targetStarSystem; + /// + /// 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 + /// + public string spawnPointID; + /// /// Type of singularity (white hole or black hole) /// diff --git a/NewHorizons/External/Modules/Volumes/VolumeInfos/ChangeStarSystemVolumeInfo.cs b/NewHorizons/External/Modules/Volumes/VolumeInfos/ChangeStarSystemVolumeInfo.cs index 969a5945..24b492db 100644 --- a/NewHorizons/External/Modules/Volumes/VolumeInfos/ChangeStarSystemVolumeInfo.cs +++ b/NewHorizons/External/Modules/Volumes/VolumeInfos/ChangeStarSystemVolumeInfo.cs @@ -10,5 +10,11 @@ namespace NewHorizons.External.Modules.Volumes.VolumeInfos /// The star system that entering this volume will send you to. /// [DefaultValue("SolarSystem")] public string targetStarSystem; + + /// + /// ID assigned to a spawn point in the other system that the player will be sent to + /// Uses the default spawn if not set + /// + public string spawnPointID; } } diff --git a/NewHorizons/Handlers/PlayerSpawnHandler.cs b/NewHorizons/Handlers/PlayerSpawnHandler.cs index af78874a..8ee1a007 100644 --- a/NewHorizons/Handlers/PlayerSpawnHandler.cs +++ b/NewHorizons/Handlers/PlayerSpawnHandler.cs @@ -9,6 +9,11 @@ namespace NewHorizons.Handlers { public static class PlayerSpawnHandler { + /// + /// Set during the previous loop, force the player to spawn here + /// + public static string TargetSpawnID { get; set; } + public static void SetUpPlayerSpawn() { if (UsingCustomSpawn()) @@ -146,6 +151,9 @@ namespace NewHorizons.Handlers FixPlayerVelocity(); InvulnerabilityHandler.MakeInvulnerable(false); + + // Done spawning + TargetSpawnID = null; } private static void FixPlayerVelocity(bool recenter = true) From f36b33075c23057c8850740a4f18c3f53deede6c Mon Sep 17 00:00:00 2001 From: Ben C Date: Fri, 4 Oct 2024 19:06:24 +0000 Subject: [PATCH 09/10] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 129d45d7..de659177 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -2722,6 +2722,10 @@ "type": "string", "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": { "description": "Type of singularity (white hole or black hole)", "$ref": "#/definitions/SingularityType" @@ -3655,6 +3659,10 @@ "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": { "description": "Rotation of the object", "$ref": "#/definitions/MVector3" @@ -3708,6 +3716,10 @@ "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": { "description": "Rotation of the object", "$ref": "#/definitions/MVector3" @@ -5194,6 +5206,10 @@ "type": "string", "description": "The star system that entering this volume will send you to.", "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" } } }, From ab2bf1118afffc5dae04371d4f91ec752eada38e Mon Sep 17 00:00:00 2001 From: xen-42 Date: Fri, 4 Oct 2024 15:08:49 -0400 Subject: [PATCH 10/10] Add an API method for setting spawn ID --- NewHorizons/INewHorizons.cs | 7 +++++++ NewHorizons/NewHorizonsApi.cs | 2 ++ 2 files changed, 9 insertions(+) diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index 71337802..12002b1e 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -214,5 +214,12 @@ namespace NewHorizons /// /// void AddSubtitle(IModBehaviour mod, string filePath); + + /// + /// 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` + /// + /// + void SetNextSpawnID(string id); } } diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index c9193f61..348991c0 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -342,5 +342,7 @@ namespace NewHorizons public string GetTranslationForOtherText(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.OTHER); public void AddSubtitle(IModBehaviour mod, string filePath) => SubtitlesHandler.RegisterAdditionalSubtitle(mod, filePath); + + public void SetNextSpawnID(string id) => PlayerSpawnHandler.TargetSpawnID = id; } }