diff --git a/Example mod/BiomeHandlerExample.cs b/Example mod/BiomeHandlerExample.cs index 7a36effd..5255a142 100644 --- a/Example mod/BiomeHandlerExample.cs +++ b/Example mod/BiomeHandlerExample.cs @@ -37,5 +37,8 @@ private void Awake() // Add the biome somewhere to the world CoordinatedSpawnsHandler.RegisterCoordinatedSpawn(new SpawnInfo(volumePrefabInfo.ClassID, new Vector3(-1400, -80, 600), Quaternion.identity, new Vector3(50, 50, 50))); + + // Add this biome to the "biome" command + ConsoleCommandsHandler.AddBiomeTeleportPosition("nautilusexamplebiome", new Vector3(-1400, -80, 600)); } } \ No newline at end of file diff --git a/Nautilus/Assets/Gadgets/GadgetExtensions.cs b/Nautilus/Assets/Gadgets/GadgetExtensions.cs index cb3b14ef..48166129 100644 --- a/Nautilus/Assets/Gadgets/GadgetExtensions.cs +++ b/Nautilus/Assets/Gadgets/GadgetExtensions.cs @@ -217,9 +217,9 @@ public static ICustomPrefab SetSpawns(this ICustomPrefab customPrefab, params Sp { customPrefab.AddOnRegister(() => { - foreach ((Vector3 position, Vector3 eulerAngles) in spawnLocations) + foreach (var spawnLocation in spawnLocations) { - CoordinatedSpawnsHandler.RegisterCoordinatedSpawn(new SpawnInfo(customPrefab.Info.ClassID, position, eulerAngles)); + CoordinatedSpawnsHandler.RegisterCoordinatedSpawn(new SpawnInfo(customPrefab.Info.ClassID, spawnLocation.Position, spawnLocation.EulerAngles, spawnLocation.Scale)); } }); diff --git a/Nautilus/Assets/PrefabTemplates/AtmosphereVolumeTemplate.cs b/Nautilus/Assets/PrefabTemplates/AtmosphereVolumeTemplate.cs index 2db3ce64..fbf3f1a9 100644 --- a/Nautilus/Assets/PrefabTemplates/AtmosphereVolumeTemplate.cs +++ b/Nautilus/Assets/PrefabTemplates/AtmosphereVolumeTemplate.cs @@ -1,11 +1,12 @@ using System; using System.Collections; +using Nautilus.MonoBehaviours; using UnityEngine; namespace Nautilus.Assets.PrefabTemplates; /// -/// A template for Atmosphere Volumes, which are basic invisible triggers for mini-biomes. +/// A template for Atmosphere Volumes, which are basic invisible triggers for mini-biomes. Atmosphere volumes can affect fog, music, ambient sounds and even the player's swim speed. /// public class AtmosphereVolumeTemplate : PrefabTemplate { @@ -23,6 +24,10 @@ public class AtmosphereVolumeTemplate : PrefabTemplate /// The priority of this atmosphere volume. Atmosphere volumes with higher priorities override those with lower priorities. The default priority is 10. /// public int Priority { get; set; } + /// + /// Whether this atmosphere volume can be entered while inside a vehicle or not. For unknown reasons, this is NOT true for base game volumes. However, in this template, it is true by default. + /// + public bool CanEnterWhileInsideVehicle { get; set; } = true; /// /// Determines the loading distance of this atmosphere volume prefab. Default value is . Although vanilla prefabs always use Batch for this, this does not work with our custom systems. @@ -78,6 +83,11 @@ public override IEnumerator GetPrefabAsync(TaskResult gameObject) var atmosphereVolume = prefab.AddComponent(); atmosphereVolume.overrideBiome = OverrideBiome; atmosphereVolume.priority = Priority; + + if (CanEnterWhileInsideVehicle) + { + prefab.AddComponent().atmosphereVolume = atmosphereVolume; + } ModifyPrefab?.Invoke(prefab); if (ModifyPrefabAsync is { }) diff --git a/Nautilus/Assets/SpawnLocation.cs b/Nautilus/Assets/SpawnLocation.cs index 48d1be38..5b46a188 100644 --- a/Nautilus/Assets/SpawnLocation.cs +++ b/Nautilus/Assets/SpawnLocation.cs @@ -7,4 +7,21 @@ namespace Nautilus.Assets; /// /// The world position. /// Euler angles for the rotation the spawned object will appear with. -public record SpawnLocation(Vector3 Position, Vector3 EulerAngles = default); \ No newline at end of file +public record SpawnLocation(Vector3 Position, Vector3 EulerAngles = default) +{ + /// + /// The scale that the object is spawned at. If default (0, 0, 0) will be resolved to (1, 1, 1). + /// + public Vector3 Scale { get; init; } + + /// + /// Defines the spawn location with world position and optional euler angles. Used in the Coordinated Spawns system. + /// + /// The world position. + /// Euler angles for the rotation the spawned object will appear with. + /// The scale that the object is spawned at. If default (0, 0, 0) will be resolved to (1, 1, 1). + public SpawnLocation(Vector3 Position, Vector3 EulerAngles, Vector3 Scale) : this(Position, EulerAngles) + { + this.Scale = Scale; + } +} \ No newline at end of file diff --git a/Nautilus/Handlers/ConsoleCommandsHandler.cs b/Nautilus/Handlers/ConsoleCommandsHandler.cs index b3fae50c..bc659d10 100644 --- a/Nautilus/Handlers/ConsoleCommandsHandler.cs +++ b/Nautilus/Handlers/ConsoleCommandsHandler.cs @@ -3,6 +3,7 @@ using HarmonyLib; using Nautilus.Commands; using Nautilus.Patchers; +using UnityEngine; namespace Nautilus.Handlers; @@ -79,4 +80,27 @@ public static void RegisterConsoleCommands(Type type) { ConsoleCommandsPatcher.ParseCustomCommands(type); } + + + /// + /// Adds a new teleport position to the "biome" command. + /// + /// The name of the teleport. Case-insensitive, no spaces allowed. + /// The world coordinates of the teleport. + public static void AddBiomeTeleportPosition(string biomeName, Vector3 position) + { + ConsoleCommandsPatcher.BiomeTeleportPositionsToAdd.Add(new TeleportPosition{name = biomeName, position = position}); + ConsoleCommandsPatcher.UpdateTeleportPositions(); + } + + /// + /// Adds a new teleport position to the "goto" command. + /// + /// The name of the teleport. Case-insensitive, no spaces allowed. + /// The world coordinates of the teleport. + public static void AddGotoTeleportPosition(string locationName, Vector3 position) + { + ConsoleCommandsPatcher.GotoTeleportPositionsToAdd.Add(new TeleportPosition{name = locationName, position = position}); + ConsoleCommandsPatcher.UpdateTeleportPositions(); + } } \ No newline at end of file diff --git a/Nautilus/Handlers/CoordinatedSpawnsHandler.cs b/Nautilus/Handlers/CoordinatedSpawnsHandler.cs index bd12dc50..1efc1fe2 100644 --- a/Nautilus/Handlers/CoordinatedSpawnsHandler.cs +++ b/Nautilus/Handlers/CoordinatedSpawnsHandler.cs @@ -45,7 +45,7 @@ public static void RegisterCoordinatedSpawns(List spawnInfos) /// The spawn locations to spawn in. Euler angles are optional. public static void RegisterCoordinatedSpawnsForOneTechType(TechType techTypeToSpawn, params SpawnLocation[] spawnLocations) { - var spawnInfos = spawnLocations.Select(spawnLocation => new SpawnInfo(techTypeToSpawn, spawnLocation.Position, spawnLocation.EulerAngles)).ToList(); + var spawnInfos = spawnLocations.Select(spawnLocation => new SpawnInfo(techTypeToSpawn, spawnLocation.Position, spawnLocation.EulerAngles, spawnLocation.Scale)).ToList(); RegisterCoordinatedSpawns(spawnInfos); } } diff --git a/Nautilus/MonoBehaviours/AtmosphereVolumeTriggerFix.cs b/Nautilus/MonoBehaviours/AtmosphereVolumeTriggerFix.cs new file mode 100644 index 00000000..815b3ab1 --- /dev/null +++ b/Nautilus/MonoBehaviours/AtmosphereVolumeTriggerFix.cs @@ -0,0 +1,28 @@ +using UnityEngine; + +namespace Nautilus.MonoBehaviours; + +// In the base game, atmosphere volumes will not trigger while you're inside a vehicle. This file fixes that issue on custom atmosphere volumes (can be opted out). +internal class AtmosphereVolumeTriggerFix : MonoBehaviour +{ + public AtmosphereVolume atmosphereVolume; + + private void Start() + { + InvokeRepeating(nameof(CheckTriggerEnter), Random.value, 3f); + } + + private void CheckTriggerEnter() + { + if (atmosphereVolume.settingsActive || !isActiveAndEnabled) + { + return; + } + var playerObject = Player.mainObject; + if (playerObject == null) return; + if (atmosphereVolume.Contains(playerObject.transform.position)) + { + atmosphereVolume.PushSettings(); + } + } +} \ No newline at end of file diff --git a/Nautilus/Patchers/ConsoleCommandsPatcher.cs b/Nautilus/Patchers/ConsoleCommandsPatcher.cs index 12a08dd5..a9664513 100644 --- a/Nautilus/Patchers/ConsoleCommandsPatcher.cs +++ b/Nautilus/Patchers/ConsoleCommandsPatcher.cs @@ -24,6 +24,9 @@ internal static class ConsoleCommandsPatcher private static Color ModOriginColor = new(0, 1, 0); private static Color ModConflictColor = new(0.75f, 0.75f, 0.75f); + internal static List GotoTeleportPositionsToAdd = new List(); + internal static List BiomeTeleportPositionsToAdd = new List(); + public static void Patch(Harmony harmony) { harmony.PatchAll(typeof(ConsoleCommandsPatcher)); @@ -281,4 +284,38 @@ public static string StripXML(this string source) { return xmlRegex.Replace(source, string.Empty); } + + [HarmonyPatch(typeof(GotoConsoleCommand), nameof(GotoConsoleCommand.Awake))] + [HarmonyPostfix] + private static void GotoConsoleCommandAwakePostfix(GotoConsoleCommand __instance) + { + UpdateTeleportPositions(); + } + + [HarmonyPatch(typeof(BiomeConsoleCommand), nameof(BiomeConsoleCommand.Awake))] + [HarmonyPostfix] + private static void BiomeConsoleCommandAwakePostfix(BiomeConsoleCommand __instance) + { + UpdateTeleportPositions(); + } + + internal static void UpdateTeleportPositions() + { + if (GotoConsoleCommand.main != null && GotoTeleportPositionsToAdd.Count > 0) + { + AddTeleportPositionsToCommandData(GotoConsoleCommand.main.data, GotoTeleportPositionsToAdd); + } + if (BiomeConsoleCommand.main != null && BiomeTeleportPositionsToAdd.Count > 0) + { + AddTeleportPositionsToCommandData(BiomeConsoleCommand.main.data, BiomeTeleportPositionsToAdd); + } + } + + private static void AddTeleportPositionsToCommandData(TeleportCommandData commandData, List positionsToAdd) + { + var list = new List(commandData.locations); + list.AddRange(positionsToAdd); + commandData.locations = list.ToArray(); + positionsToAdd.Clear(); + } } \ No newline at end of file