Allow for custom signals

This commit is contained in:
Nick J. Connors 2021-12-31 21:43:32 -05:00
parent 8af7a7a75b
commit b09df3b4bd
8 changed files with 287 additions and 1 deletions

View File

@ -0,0 +1,146 @@
using NewHorizons.External;
using NewHorizons.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.Props
{
public static class SignalBuilder
{
private static AnimationCurve _customCurve = null;
private static Dictionary<SignalName, string> _customSignalNames;
private static Stack<int> _availableSignalNames;
public static void Reset()
{
_customSignalNames = new Dictionary<SignalName, string>();
_availableSignalNames = new Stack<int> (new int[]
{
17,
18,
19,
26,
27,
28,
29,
33,
34,
35,
36,
37,
38,
39,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59
});
}
public static SignalName AddSignalName(string str)
{
if (_availableSignalNames.Count == 0)
{
Logger.LogWarning($"There are no more available SignalName spots. Cannot use name [{str}].");
return SignalName.Default;
}
Logger.Log($"Registering new signal name [{str}]");
var newName = (SignalName)_availableSignalNames.Pop();
_customSignalNames.Add(newName, str.ToUpper());
return newName;
}
public static string GetCustomSignalName(SignalName signalName)
{
if (_customSignalNames.ContainsKey(signalName)) return _customSignalNames[signalName];
return null;
}
public static void Make(GameObject body, Sector sector, SignalModule module)
{
foreach(var info in module.Signals)
{
Make(body, sector, info);
}
}
public static void Make(GameObject body, Sector sector, SignalModule.SignalInfo info)
{
var signalGO = new GameObject($"Signal_{info.Name}");
signalGO.SetActive(false);
signalGO.transform.parent = sector.transform;
signalGO.transform.localPosition = info.Position != null ? (Vector3)info.Position : Vector3.zero;
var source = signalGO.AddComponent<AudioSource>();
var owAudioSource = signalGO.AddComponent<OWAudioSource>();
var audioSignal = signalGO.AddComponent<AudioSignal>();
var frequency = StringToFrequency(info.Frequency);
var name = StringToSignalName(info.Name);
AudioClip clip = SearchUtilities.FindResourceOfTypeAndName<AudioClip>(info.AudioClip);
if (clip == null) return;
audioSignal.SetSector(sector);
audioSignal._frequency = frequency;
if (name == SignalName.Default)
{
name = AddSignalName(info.Name);
if(name == SignalName.Default) audioSignal._preventIdentification = true;
}
audioSignal._name = name;
audioSignal._sourceRadius = info.SourceRadius;
audioSignal._onlyAudibleToScope = info.OnlyAudibleToScope;
source.clip = clip;
source.loop = true;
source.minDistance = 0;
source.maxDistance = 30;
source.velocityUpdateMode = AudioVelocityUpdateMode.Fixed;
source.rolloffMode = AudioRolloffMode.Custom;
if(_customCurve == null)
_customCurve = GameObject.Find("Moon_Body/Sector_THM/Characters_THM/Villager_HEA_Esker/Signal_Whistling").GetComponent<AudioSource>().GetCustomCurve(AudioSourceCurveType.CustomRolloff);
source.SetCustomCurve(AudioSourceCurveType.CustomRolloff, _customCurve);
source.playOnAwake = false;
source.spatialBlend = 1f;
source.volume = 0.5f;
owAudioSource.SetTrack(OWAudioMixer.TrackName.Signal);
signalGO.SetActive(true);
}
private static SignalFrequency StringToFrequency(string str)
{
foreach(SignalFrequency freq in Enum.GetValues(typeof(SignalFrequency)))
{
if (str.Equals(freq.ToString())) return freq;
}
return SignalFrequency.Default;
}
private static SignalName StringToSignalName(string str)
{
foreach (SignalName name in Enum.GetValues(typeof(SignalName)))
{
if (str.Equals(name.ToString())) return name;
}
return SignalName.Default;
}
}
}

View File

@ -18,5 +18,6 @@ namespace NewHorizons.External
FocalPointModule FocalPoint { get; }
PropModule Props { get; }
SpawnModule Spawn { get; }
SignalModule Signal { get; }
}
}

View File

@ -22,6 +22,7 @@ namespace NewHorizons.External
public FocalPointModule FocalPoint { get; set; }
public PropModule Props { get; set; }
public SpawnModule Spawn { get; set; }
public SignalModule Signal { get; set; }
public PlanetConfig(Dictionary<string, object> dict)
{

24
NewHorizons/External/SignalModule.cs vendored Normal file
View File

@ -0,0 +1,24 @@
using NewHorizons.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NewHorizons.External
{
public class SignalModule : Module
{
public SignalInfo[] Signals;
public class SignalInfo
{
public MVector3 Position;
public string Frequency;
public string Name;
public string AudioClip;
public float SourceRadius = 1f;
public bool OnlyAudibleToScope = true;
}
}
}

View File

@ -101,6 +101,10 @@ namespace NewHorizons
// TODO: Make this configurable probably
Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => Locator.GetPlayerBody().gameObject.AddComponent<DebugRaycaster>());
// Some builders need to be reset each time
SignalBuilder.Reset();
// We do our own AstroObject tracking
AstroObjectLocator.RefreshList();
foreach (AstroObject ao in GameObject.FindObjectsOfType<AstroObject>())
{
@ -312,6 +316,9 @@ namespace NewHorizons
if (body.Config.FocalPoint != null)
FocalPointBuilder.Make(go, body.Config.FocalPoint);
if (body.Config.Signal != null)
SignalBuilder.Make(go, sector, body.Config.Signal);
// Do stuff that's shared between generating new planets and updating old ones
go = SharedGenerateBody(body, go, sector, owRigidBody, ao);

View File

@ -30,4 +30,7 @@
<ItemGroup>
<Content Include="NewHorizons.csproj.user" />
</ItemGroup>
<ItemGroup>
<Folder Include="Components\" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,5 @@
using OWML.Common;
using NewHorizons.Builder.Props;
using OWML.Common;
using System;
using System.Collections.Generic;
using System.Linq;
@ -17,6 +18,7 @@ namespace NewHorizons.Utility
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<PlayerState>("CheckShipOutsideSolarSystem", typeof(Patches), nameof(Patches.CheckShipOutersideSolarSystem));
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<SunLightParamUpdater>("LateUpdate", typeof(Patches), nameof(Patches.OnSunLightParamUpdaterLateUpdate));
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<SunSurfaceAudioController>("Update", typeof(Patches), nameof(Patches.OnSunSurfaceAudioControllerUpdate));
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<AudioSignal>("SignalNameToString", typeof(Patches), nameof(Patches.OnAudioSignalSignalNameToString));
// Postfixes
Main.Instance.ModHelper.HarmonyHelper.AddPostfix<EllipticOrbitLine>("Start", typeof(Patches), nameof(Patches.OnEllipticOrbitLineStart));
@ -93,5 +95,47 @@ namespace NewHorizons.Utility
__instance._audioSource.SetLocalVolume(num * num * __instance._fade);
return false;
}
public static bool OnAudioSignalSignalNameToString(SignalName __0, ref string __result)
{
switch(__0)
{
case SignalName.WhiteHole_SS_Receiver:
__result = "Sun Station Receiver";
return false;
case SignalName.WhiteHole_CT_Receiver:
__result = "Ember Twin Receiver";
return false;
case SignalName.WhiteHole_CT_Experiment:
__result = "White Hole Receiver";
return false;
case SignalName.WhiteHole_TT_Receiver:
__result = "Ash Twin Receiver";
return false;
case SignalName.WhiteHole_TT_TimeLoopCore:
__result = "Ash Twin Project";
return false;
case SignalName.WhiteHole_TH_Receiver:
__result = "Timber Hearth Receiver";
return false;
case SignalName.WhiteHole_BH_NorthPoleReceiver:
__result = "North Pole Receiver";
return false;
case SignalName.WhiteHole_BH_ForgeReceiver:
__result = "Black Hole Forge Receiver";
return false;
case SignalName.WhiteHole_GD_Receiver:
__result = "Giant's Deep Receiver";
return false;
default:
var customSignalName = SignalBuilder.GetCustomSignalName(__0);
if (customSignalName == null) return true;
else
{
__result = customSignalName;
return false;
}
}
}
}
}

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Object = UnityEngine.Object;
namespace NewHorizons.Utility
{
public static class SearchUtilities
{
public static List<T> FindObjectsOfTypeAndName<T>(string name) where T : MonoBehaviour
{
T[] firstList = GameObject.FindObjectsOfType<T>();
List<T> finalList = new List<T>();
for (var i = 0; i < firstList.Length; i++)
{
if (firstList[i].name == name)
{
finalList.Add(firstList[i]);
}
}
return finalList;
}
public static List<T> FindResourcesOfTypeAndName<T>(string name) where T : Object
{
T[] firstList = Resources.FindObjectsOfTypeAll<T>();
List<T> finalList = new List<T>();
for (var i = 0; i < firstList.Length; i++)
{
if (firstList[i].name == name)
{
finalList.Add(firstList[i]);
}
}
return finalList;
}
public static T FindResourceOfTypeAndName<T>(string name) where T : Object
{
T[] firstList = Resources.FindObjectsOfTypeAll<T>();
for (var i = 0; i < firstList.Length; i++)
{
if (firstList[i].name == name)
{
return firstList[i];
}
}
return null;
}
}
}