Added AudioSourceInfo as a new prop, refactors signals

This commit is contained in:
Nick 2023-03-26 22:39:29 -04:00
parent e536ab2d23
commit 031ad5266c
20 changed files with 231 additions and 115 deletions

View File

@ -0,0 +1,21 @@
using NewHorizons.External.Modules.Props.Audio;
using NewHorizons.Utility;
using OWML.Common;
using UnityEngine;
namespace NewHorizons.Builder.Props.Audio
{
public static class AudioSourceBuilder
{
public static GameObject Make(GameObject planetGO, Sector sector, AudioSourceInfo info, IModBehaviour mod)
{
var owAudioSource = GeneralAudioBuilder.Make(planetGO, sector, info, mod);
owAudioSource.SetTrack(info.track.ConvertToOW());
owAudioSource.gameObject.SetActive(true);
return owAudioSource.gameObject;
}
}
}

View File

@ -0,0 +1,44 @@
using NewHorizons.External.Modules.Props.Audio;
using NewHorizons.Utility.Files;
using NewHorizons.Utility.OuterWilds;
using OWML.Common;
using UnityEngine;
namespace NewHorizons.Builder.Props.Audio
{
public static class GeneralAudioBuilder
{
public static AnimationCurve CustomCurve => new(
new Keyframe(0.0333f, 1f, -30.012f, -30.012f, 0.3333f, 0.3333f),
new Keyframe(0.0667f, 0.5f, -7.503f, -7.503f, 0.3333f, 0.3333f),
new Keyframe(0.1333f, 0.25f, -1.8758f, -1.8758f, 0.3333f, 0.3333f),
new Keyframe(0.2667f, 0.125f, -0.4689f, -0.4689f, 0.3333f, 0.3333f),
new Keyframe(0.5333f, 0.0625f, -0.1172f, -0.1172f, 0.3333f, 0.3333f),
new Keyframe(1f, 0f, -0.0333f, -0.0333f, 0.3333f, 0.3333f)
);
public static OWAudioSource Make(GameObject planetGO, Sector sector, BaseAudioInfo info, IModBehaviour mod)
{
var signalGO = GeneralPropBuilder.MakeNew($"{(string.IsNullOrEmpty(info.rename) ? "AudioSource" : info.rename)}", planetGO, sector, info);
signalGO.layer = Layer.AdvancedEffectVolume;
var source = signalGO.AddComponent<AudioSource>();
var owAudioSource = signalGO.AddComponent<OWAudioSource>();
owAudioSource._audioSource = source;
source.loop = true;
source.minDistance = info.minDistance;
source.maxDistance = info.maxDistance;
source.velocityUpdateMode = AudioVelocityUpdateMode.Fixed;
source.rolloffMode = AudioRolloffMode.Custom;
source.spatialBlend = 1f;
source.volume = info.volume;
source.dopplerLevel = 0;
source.SetCustomCurve(AudioSourceCurveType.CustomRolloff, CustomCurve);
AudioUtilities.SetAudioClip(owAudioSource, info.audio, mod);
return owAudioSource;
}
}
}

View File

@ -7,14 +7,12 @@ using OWML.Common;
using OWML.Utils;
using System.Collections.Generic;
using UnityEngine;
using NewHorizons.External.Modules.Props.Audio;
namespace NewHorizons.Builder.Props
namespace NewHorizons.Builder.Props.Audio
{
public static class SignalBuilder
{
private static AnimationCurve _customCurve = null;
private static Dictionary<SignalName, string> _customSignalNames;
private static Dictionary<SignalFrequency, string> _customFrequencyNames;
@ -56,7 +54,7 @@ namespace NewHorizons.Builder.Props
public static SignalFrequency AddFrequency(string str)
{
if (_customFrequencyNames == null) Init();
var freq = CollectionUtilities.KeyByValue(_customFrequencyNames, str);
if (freq != default) return freq;
@ -74,7 +72,7 @@ namespace NewHorizons.Builder.Props
NumberOfFrequencies = EnumUtils.GetValues<SignalFrequency>().Length;
// This stuff happens after the signalscope is Awake so we have to change the number of frequencies now
GameObject.FindObjectOfType<Signalscope>()._strongestSignals = new AudioSignal[NumberOfFrequencies + 1];
Object.FindObjectOfType<Signalscope>()._strongestSignals = new AudioSignal[NumberOfFrequencies + 1];
return freq;
}
@ -90,7 +88,7 @@ namespace NewHorizons.Builder.Props
public static SignalName AddSignalName(string str)
{
if (_customSignalNames == null) Init();
var name = CollectionUtilities.KeyByValue(_customSignalNames, str);
if (name != default) return name;
@ -110,14 +108,10 @@ namespace NewHorizons.Builder.Props
return name;
}
public static GameObject Make(GameObject planetGO, Sector sector, SignalModule.SignalInfo info, IModBehaviour mod)
public static GameObject Make(GameObject planetGO, Sector sector, SignalInfo info, IModBehaviour mod)
{
var signalGO = GeneralPropBuilder.MakeNew($"Signal_{info.name}", planetGO, sector, info);
signalGO.layer = Layer.AdvancedEffectVolume;
var source = signalGO.AddComponent<AudioSource>();
var owAudioSource = signalGO.AddComponent<OWAudioSource>();
owAudioSource._audioSource = source;
var owAudioSource = GeneralAudioBuilder.Make(planetGO, sector, info, mod);
var signalGO = owAudioSource.gameObject;
var audioSignal = signalGO.AddComponent<AudioSignal>();
audioSignal._owAudioSource = owAudioSource;
@ -137,36 +131,11 @@ namespace NewHorizons.Builder.Props
audioSignal._identificationDistance = info.identificationRadius;
audioSignal._canBePickedUpByScope = true;
audioSignal._outerFogWarpVolume = planetGO.GetComponentInChildren<OuterFogWarpVolume>(); // shouldn't break non-bramble signals
source.loop = true;
source.minDistance = 0;
source.maxDistance = 30;
source.velocityUpdateMode = AudioVelocityUpdateMode.Fixed;
source.rolloffMode = AudioRolloffMode.Custom;
if (_customCurve == null)
{
_customCurve = new AnimationCurve(
new Keyframe(0.0333f, 1f, -30.012f, -30.012f, 0.3333f, 0.3333f),
new Keyframe(0.0667f, 0.5f, -7.503f, -7.503f, 0.3333f, 0.3333f),
new Keyframe(0.1333f, 0.25f, -1.8758f, -1.8758f, 0.3333f, 0.3333f),
new Keyframe(0.2667f, 0.125f, -0.4689f, -0.4689f, 0.3333f, 0.3333f),
new Keyframe(0.5333f, 0.0625f, -0.1172f, -0.1172f, 0.3333f, 0.3333f),
new Keyframe(1f, 0f, -0.0333f, -0.0333f, 0.3333f, 0.3333f));
}
source.SetCustomCurve(AudioSourceCurveType.CustomRolloff, _customCurve);
// If it can be heard regularly then we play it immediately
source.playOnAwake = !info.onlyAudibleToScope;
source.spatialBlend = 1f;
source.volume = 0.5f;
source.dopplerLevel = 0;
owAudioSource.SetTrack(OWAudioMixer.TrackName.Signal);
AudioUtilities.SetAudioClip(owAudioSource, info.audio, mod);
owAudioSource.playOnAwake = !info.onlyAudibleToScope;
// Frequency detection trigger volume
var sphereShape = signalGO.AddComponent<SphereShape>();
var owTriggerVolume = signalGO.AddComponent<OWTriggerVolume>();
var audioSignalDetectionTrigger = signalGO.AddComponent<AudioSignalDetectionTrigger>();
@ -175,6 +144,8 @@ namespace NewHorizons.Builder.Props
audioSignalDetectionTrigger._signal = audioSignal;
audioSignalDetectionTrigger._trigger = owTriggerVolume;
owAudioSource.SetTrack(OWAudioMixer.TrackName.Signal);
signalGO.SetActive(true);
// Track certain special signal things
@ -186,12 +157,12 @@ namespace NewHorizons.Builder.Props
private static SignalFrequency StringToFrequency(string str)
{
return EnumUtils.TryParse<SignalFrequency>(str, out SignalFrequency frequency) ? frequency : AddFrequency(str);
return EnumUtils.TryParse(str, out SignalFrequency frequency) ? frequency : AddFrequency(str);
}
public static SignalName StringToSignalName(string str)
{
return EnumUtils.TryParse<SignalName>(str, out SignalName name) ? name : AddSignalName(str);
return EnumUtils.TryParse(str, out SignalName name) ? name : AddSignalName(str);
}
}
}

View File

@ -1,5 +1,7 @@
using NewHorizons.Builder.Body;
using NewHorizons.Builder.Props.Audio;
using NewHorizons.External.Configs;
using NewHorizons.External.Modules.Props.Audio;
using NewHorizons.Handlers;
using NewHorizons.Utility;
using NewHorizons.Utility.OuterWilds;

View File

@ -1,4 +1,5 @@
using NewHorizons.Builder.Body;
using NewHorizons.Builder.Props.Audio;
using NewHorizons.Builder.Props.TranslatorText;
using NewHorizons.Builder.ShipLog;
using NewHorizons.External;
@ -269,6 +270,20 @@ namespace NewHorizons.Builder.Props
}
}
}
if (config.Props.audioSources != null)
{
foreach (var audioSource in config.Props.audioSources)
{
try
{
AudioSourceBuilder.Make(go, sector, audioSource, mod);
}
catch (Exception ex)
{
NHLogger.LogError($"Couldn't make audio source [{audioSource.audio}] for [{go.name}]:\n{ex}");
}
}
}
}
}
}

View File

@ -1,9 +1,9 @@
using NewHorizons.Builder.Props;
using NewHorizons.External.Modules.Volumes.VolumeInfos;
using NewHorizons.Utility;
using NewHorizons.Utility.Files;
using NewHorizons.Utility.OuterWilds;
using OWML.Common;
using OWML.Utils;
using UnityEngine;
namespace NewHorizons.Builder.Volumes
@ -21,8 +21,8 @@ namespace NewHorizons.Builder.Volumes
owAudioSource._audioSource = audioSource;
owAudioSource.loop = info.loop;
owAudioSource.SetMaxVolume(info.volume);
owAudioSource.SetClipSelectionType(EnumUtils.Parse<OWAudioSource.ClipSelectionOnPlay>(info.clipSelection.ToString()));
owAudioSource.SetTrack(EnumUtils.Parse<OWAudioMixer.TrackName>(info.track.ToString()));
owAudioSource.SetClipSelectionType(info.clipSelection.ConvertToOW());
owAudioSource.SetTrack(info.track.ConvertToOW());
AudioUtilities.SetAudioClip(owAudioSource, info.audio, mod);
var audioVolume = go.AddComponent<AudioVolume>();

View File

@ -1,5 +1,6 @@
using NewHorizons.External.Modules;
using NewHorizons.External.Modules.Props;
using NewHorizons.External.Modules.Props.Audio;
using NewHorizons.External.Modules.Props.Dialogue;
using NewHorizons.External.Modules.Props.Quantum;
using NewHorizons.External.Modules.VariableSize;
@ -408,7 +409,7 @@ namespace NewHorizons.External.Configs
if (Signal?.signals != null)
{
if (Props == null) Props = new PropModule();
if (Props.signals == null) Props.signals = new SignalModule.SignalInfo[0];
if (Props.signals == null) Props.signals = new SignalInfo[0];
Props.signals = Props.signals.Concat(Signal.signals).ToArray();
}

View File

@ -1,4 +1,5 @@
using NewHorizons.External.Modules.Props;
using NewHorizons.External.Modules.Props.Audio;
using NewHorizons.External.Modules.Props.Dialogue;
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
using NewHorizons.External.Modules.Props.Quantum;
@ -89,7 +90,7 @@ namespace NewHorizons.External.Modules
/// <summary>
/// Add signalscope signals to this planet
/// </summary>
public SignalModule.SignalInfo[] signals;
public SignalInfo[] signals;
/// <summary>
/// Add projection pools/platforms, whiteboards, and stones to this planet
@ -106,6 +107,11 @@ namespace NewHorizons.External.Modules
/// </summary>
public NomaiWarpTransmitterInfo[] warpTransmitters;
/// <summary>
/// Add audio point sources to this planet. For audio across an entire area, look for AudioVolumes under the Volumes module.
/// </summary>
public AudioSourceInfo[] audioSources;
[Obsolete("reveal is deprecated. Use Volumes->revealVolumes instead.")] public RevealVolumeInfo[] reveal;
[Obsolete("audioVolumes is deprecated. Use Volumes->audioVolumes instead.")] public AudioVolumeInfo[] audioVolumes;

View File

@ -0,0 +1,15 @@
using NewHorizons.External.SerializableEnums;
using Newtonsoft.Json;
using System.ComponentModel;
namespace NewHorizons.External.Modules.Props.Audio
{
[JsonObject]
public class AudioSourceInfo : BaseAudioInfo
{
/// <summary>
/// The audio track of this audio source
/// </summary>
[DefaultValue("environment")] public NHAudioMixerTrackName track = NHAudioMixerTrackName.Environment;
}
}

View File

@ -0,0 +1,29 @@
using Newtonsoft.Json;
using System.ComponentModel;
namespace NewHorizons.External.Modules.Props.Audio
{
[JsonObject]
public abstract class BaseAudioInfo : GeneralPointPropInfo
{
/// <summary>
/// The audio to use. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.
/// </summary>
public string audio;
/// <summary>
/// At this distance the sound is at its loudest.
/// </summary>
public float minDistance;
/// <summary>
/// The sound will drop off by this distance (Note: for signals, this only effects when it is heard aloud and not via the signalscope).
/// </summary>
[DefaultValue(5f)] public float maxDistance = 30f;
/// <summary>
/// How loud the sound will play
/// </summary>
[DefaultValue(0.5f)] public float volume = 0.5f;
}
}

View File

@ -0,0 +1,61 @@
using Newtonsoft.Json;
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace NewHorizons.External.Modules.Props.Audio
{
[JsonObject]
public class SignalInfo : BaseAudioInfo
{
[Obsolete("audioClip is deprecated, please use audio instead")]
public string audioClip;
[Obsolete("audioFilePath is deprecated, please use audio instead")]
public string audioFilePath;
/// <summary>
/// How close the player must get to the signal to detect it. This is when you get the "Unknown Signal Detected"
/// notification.
/// </summary>
[Range(0f, double.MaxValue)] public float detectionRadius;
/// <summary>
/// The frequency ID of the signal. The built-in game values are `Default`, `Traveler`, `Quantum`, `EscapePod`,
/// `Statue`, `WarpCore`, `HideAndSeek`, and `Radio`. You can also put a custom value.
/// </summary>
public string frequency;
/// <summary>
/// How close the player must get to the signal to identify it. This is when you learn its name.
/// </summary>
[DefaultValue(10f)]
[Range(0f, double.MaxValue)]
public float identificationRadius = 10f;
/// <summary>
/// Only set to `true` if you are putting this signal inside a cloaking field.
/// </summary>
public bool insideCloak;
/// <summary>
/// The unique ID of the signal.
/// </summary>
public string name;
/// <summary>
/// `false` if the player can hear the signal without equipping the signal-scope.
/// </summary>
[DefaultValue(true)] public bool onlyAudibleToScope = true;
/// <summary>
/// A ship log fact to reveal when the signal is identified.
/// </summary>
[DefaultValue("")] public string reveals = "";
/// <summary>
/// Radius of the sphere giving off the signal.
/// </summary>
[DefaultValue(1f)] public float sourceRadius = 1f;
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using NewHorizons.External.Modules.Props.Audio;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules
@ -8,67 +9,7 @@ namespace NewHorizons.External.Modules
[JsonObject]
public class SignalModule
{
/// <summary>
/// List of signals to add (Why did xen do it like this)
/// </summary>
[Obsolete("signals is deprecated, please use Props->signals instead")]
public SignalInfo[] signals;
[JsonObject]
public class SignalInfo : GeneralPointPropInfo
{
[Obsolete("audioClip is deprecated, please use audio instead")]
public string audioClip;
[Obsolete("audioFilePath is deprecated, please use audio instead")]
public string audioFilePath;
/// <summary>
/// The audio to use. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.
/// </summary>
public string audio;
/// <summary>
/// How close the player must get to the signal to detect it. This is when you get the "Unknown Signal Detected"
/// notification.
/// </summary>
[Range(0f, double.MaxValue)] public float detectionRadius;
/// <summary>
/// The frequency ID of the signal. The built-in game values are `Default`, `Traveler`, `Quantum`, `EscapePod`,
/// `Statue`, `WarpCore`, `HideAndSeek`, and `Radio`. You can also put a custom value.
/// </summary>
public string frequency;
/// <summary>
/// How close the player must get to the signal to identify it. This is when you learn its name.
/// </summary>
[DefaultValue(10f)] [Range(0f, double.MaxValue)]
public float identificationRadius = 10f;
/// <summary>
/// Only set to `true` if you are putting this signal inside a cloaking field.
/// </summary>
public bool insideCloak;
/// <summary>
/// The unique ID of the signal.
/// </summary>
public string name;
/// <summary>
/// `false` if the player can hear the signal without equipping the signal-scope.
/// </summary>
[DefaultValue(true)] public bool onlyAudibleToScope = true;
/// <summary>
/// A ship log fact to reveal when the signal is identified.
/// </summary>
[DefaultValue("")] public string reveals = "";
/// <summary>
/// Radius of the sphere giving off the signal.
/// </summary>
[DefaultValue(1f)] public float sourceRadius = 1f;
}
}
}

View File

@ -32,6 +32,7 @@ using UnityEngine.SceneManagement;
using NewHorizons.Utility.DebugTools;
using NewHorizons.Utility.DebugTools.Menu;
using NewHorizons.Builder.Props.Audio;
namespace NewHorizons
{

View File

@ -1,7 +1,9 @@
using NewHorizons.Builder.Props;
using NewHorizons.Builder.Props.Audio;
using NewHorizons.External;
using NewHorizons.External.Modules;
using NewHorizons.External.Modules.Props;
using NewHorizons.External.Modules.Props.Audio;
using NewHorizons.External.Modules.Props.Dialogue;
using NewHorizons.Utility;
using NewHorizons.Utility.OWML;
@ -174,7 +176,7 @@ namespace NewHorizons
float sourceRadius = 1f, float detectionRadius = 20f, float identificationRadius = 10f, bool insideCloak = false,
bool onlyAudibleToScope = true, string reveals = "")
{
var info = new SignalModule.SignalInfo()
var info = new SignalInfo()
{
audio = audio,
detectionRadius = detectionRadius,

View File

@ -1,4 +1,4 @@
using NewHorizons.Builder.Props;
using NewHorizons.Builder.Props.Audio;
using NewHorizons.Handlers;
using Newtonsoft.Json;
using System.Linq;

View File

@ -1,5 +1,5 @@
using HarmonyLib;
using NewHorizons.Builder.Props;
using NewHorizons.Builder.Props.Audio;
using NewHorizons.External;
using NewHorizons.Handlers;
using NewHorizons.OtherMods.AchievementsPlus;

View File

@ -1,5 +1,5 @@
using HarmonyLib;
using NewHorizons.Builder.Props;
using NewHorizons.Builder.Props.Audio;
using NewHorizons.External;
using NewHorizons.Handlers;
using System;

View File

@ -1,5 +1,5 @@
using HarmonyLib;
using NewHorizons.Builder.Props;
using NewHorizons.Builder.Props.Audio;
namespace NewHorizons.Patches.SignalPatches
{

View File

@ -254,6 +254,13 @@ namespace NewHorizons.Utility
return xCorrect && yCorrect && zCorrect;
}
public static FluidVolume.Type ConvertToOW(this NHFluidType fluidType, FluidVolume.Type @default = FluidVolume.Type.NONE) => EnumUtils.Parse(fluidType.ToString().ToUpper(), @default);
public static FluidVolume.Type ConvertToOW(this NHFluidType fluidType, FluidVolume.Type @default = FluidVolume.Type.NONE)
=> EnumUtils.Parse(fluidType.ToString().ToUpper(), @default);
public static OWAudioMixer.TrackName ConvertToOW(this NHAudioMixerTrackName trackName, OWAudioMixer.TrackName @default = OWAudioMixer.TrackName.Environment)
=> EnumUtils.Parse(trackName.ToString().ToUpper(), @default);
public static OWAudioSource.ClipSelectionOnPlay ConvertToOW(this NHClipSelectionType clipSelection, OWAudioSource.ClipSelectionOnPlay @default = OWAudioSource.ClipSelectionOnPlay.RANDOM)
=> EnumUtils.Parse(clipSelection.ToString().ToUpper(), @default);
}
}

View File

@ -4,7 +4,7 @@
"author": "xen, Bwc9876, clay, MegaPiggy, John, Trifid, Hawkbar, Book",
"name": "New Horizons",
"uniqueName": "xen.NewHorizons",
"version": "1.10.1",
"version": "1.10.2",
"owmlVersion": "2.9.0",
"dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ],