mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-20 01:46:19 +00:00
Add more audio overrides
This commit is contained in:
1 parent
99b8ecab04
commit
239adc583b
3 files changed
+170
-14
No files matched your search
@@ -575,6 +575,27 @@ internal static class Utils
|
||||
return clip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a normalized directory path by combining folder names from a delimited string.
|
||||
/// </summary>
|
||||
/// <param name="path">A string containing folder names separated by the specified separator character. Folder names must not be empty.</param>
|
||||
/// <param name="separator">The character used to separate folder names in the input string. Defaults to '/'.</param>
|
||||
/// <returns>A directory path constructed by combining the non-empty folder names from the input string, using the system's
|
||||
/// directory separator character.</returns>
|
||||
internal static string GenerateDirectoryPath(string path, char separator = '/')
|
||||
{
|
||||
string[] folders = path.Split(separator);
|
||||
string currentPath = "";
|
||||
foreach (string folder in folders)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(folder))
|
||||
{
|
||||
currentPath = Path.Combine(currentPath, folder);
|
||||
}
|
||||
}
|
||||
return currentPath;
|
||||
}
|
||||
|
||||
// Platform utilities
|
||||
/// <summary>
|
||||
/// Gets the platform name for a player.
|
||||
|
||||
@@ -13,21 +13,37 @@ internal static class AudioOverrideManager
|
||||
/// </summary>
|
||||
internal static readonly List<AudioOverrideData> Overrides = [];
|
||||
|
||||
internal static readonly AudioOverrideData Music_MainMenuSong = new("Music/MainMenuSong.wav");
|
||||
internal static readonly AudioOverrideData Music_MainMenuSong = new("Music", "MainMenuSong.wav");
|
||||
|
||||
internal static readonly AudioOverrideData Music_LobbySong = new("Music/LobbySong.wav");
|
||||
internal static readonly AudioOverrideData Music_LobbySong = new("Music", "LobbySong.wav");
|
||||
|
||||
internal static readonly AudioOverrideData Sounds_EmergencyMeeting = new("Sounds/Meeting/EmergencyMeeting.wav");
|
||||
internal static readonly MapAudioOverrideData Sounds_VentEnter = new("Sounds/Gameplay", "VentEnter.wav");
|
||||
|
||||
internal static readonly MapAudioOverrideData Sounds_VentExit = new("Sounds/Gameplay", "VentExit.wav");
|
||||
|
||||
internal static readonly MapAudioOverrideData Sounds_SabotageAlert = new("Sounds/Gameplay", "SabotageAlert.wav");
|
||||
|
||||
internal static readonly AudioOverrideData Sounds_EmergencyMeetingStart = new("Sounds/Meeting", "EmergencyMeetingStart.wav");
|
||||
|
||||
internal static readonly AudioOverrideData Sounds_EmergencyMeetingVote = new("Sounds/Meeting", "EmergencyMeetingVote.wav");
|
||||
|
||||
internal static readonly AudioOverrideData Sounds_EmergencyMeetingVoteLockin = new("Sounds/Meeting", "EmergencyMeetingLockin.wav");
|
||||
|
||||
internal static readonly AudioOverrideData Sounds_EmergencyMeetingEnd = new("Sounds/Meeting", "EmergencyMeetingEnd.wav");
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the AudioOverrideManager by discovering all AudioOverrideData fields,
|
||||
/// Initializes the AudioOverrideManager by discovering all AudioOverrideData fields and loading their audio clips.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method scans all static fields in AudioOverrideManager that inherit from AudioOverrideData,
|
||||
/// adds them to the Overrides collection, and loads their associated audio files from disk.
|
||||
/// </remarks>
|
||||
internal static void Initialize()
|
||||
{
|
||||
// Discover all AudioOverrideInfo fields
|
||||
var infoFields = typeof(AudioOverrideManager)
|
||||
.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(f => f.FieldType == typeof(AudioOverrideData))
|
||||
.Where(f => typeof(AudioOverrideData).IsAssignableFrom(f.FieldType))
|
||||
.Select(f => f.GetValue(null) as AudioOverrideData)
|
||||
.Where(v => v != null);
|
||||
|
||||
@@ -48,22 +64,25 @@ internal static class AudioOverrideManager
|
||||
|
||||
/// <summary>
|
||||
/// Represents an audio override file with its path and loaded AudioClip.
|
||||
/// Provides functionality for loading custom audio files from the file system.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to the audio file within the audio overrides folder.</param>
|
||||
internal sealed class AudioOverrideData(string path)
|
||||
/// <param name="folderPath">The relative folder path to the audio file within the audio overrides directory.</param>
|
||||
/// <param name="fileName">The name of the audio file, including extension.</param>
|
||||
internal class AudioOverrideData(string folderPath, string fileName)
|
||||
{
|
||||
private readonly string _path = path;
|
||||
private readonly string _path = Path.Combine(Utils.GenerateDirectoryPath(folderPath), fileName);
|
||||
private AudioClip? audioClip;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original audio clip associated with this instance.
|
||||
/// Gets or sets the original audio clip that this override replaces.
|
||||
/// </summary>
|
||||
/// <value>The original game audio clip, or null if not set.</value>
|
||||
internal AudioClip? Original;
|
||||
|
||||
/// <summary>
|
||||
/// Loads the audio clip from disk. Creates the file and directory structure if they don't exist.
|
||||
/// </summary>
|
||||
internal void Load()
|
||||
internal virtual void Load()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_path)) return;
|
||||
|
||||
@@ -89,9 +108,9 @@ internal static class AudioOverrideManager
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the loaded AudioClip.
|
||||
/// </summary>
|
||||
/// <param name="clip">The AudioClip if loaded and available; otherwise, null.</param>
|
||||
/// <returns>True if the AudioClip is available; otherwise, false.</returns>
|
||||
internal bool TryGetAudioClip(out AudioClip? clip)
|
||||
/// <param name="clip">When this method returns, contains the loaded AudioClip if successful; otherwise, null.</param>
|
||||
/// <returns>True if the AudioClip is available and loaded; otherwise, false.</returns>
|
||||
internal virtual bool TryGetAudioClip(out AudioClip? clip)
|
||||
{
|
||||
if (audioClip != null)
|
||||
{
|
||||
@@ -102,5 +121,76 @@ internal static class AudioOverrideManager
|
||||
clip = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether an audio clip is currently associated with this instance.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if an audio clip is loaded and present; otherwise, <see langword="false"/>.</returns>
|
||||
internal virtual bool HasAudioClip()
|
||||
{
|
||||
return audioClip != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a map specific audio override that loads different audio files for different maps.
|
||||
/// </summary>
|
||||
/// <param name="folderPath">The relative folder path to the audio files within the audio overrides directory.</param>
|
||||
/// <param name="fileName">The base name of the audio file, which will be prefixed with map names.</param>
|
||||
internal sealed class MapAudioOverrideData(string folderPath, string fileName) : AudioOverrideData(folderPath, fileName)
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of map types for audio override categorization.
|
||||
/// </summary>
|
||||
private enum MapTyped
|
||||
{
|
||||
Ships,
|
||||
MiraHQ,
|
||||
Polus,
|
||||
Fungle
|
||||
}
|
||||
|
||||
private readonly string _folderPath = folderPath;
|
||||
private readonly string _fileName = fileName;
|
||||
private readonly Dictionary<MapTyped, AudioOverrideData> audioOverrideDatas = [];
|
||||
|
||||
/// <summary>
|
||||
/// Loads map specific audio overrides for all supported map types.
|
||||
/// </summary>
|
||||
internal override void Load()
|
||||
{
|
||||
foreach (var map in Enum.GetValues(typeof(ShipStatus.MapType)))
|
||||
{
|
||||
if (map is ShipStatus.MapType mapType)
|
||||
{
|
||||
var audioData = new AudioOverrideData(Path.Combine(Utils.GenerateDirectoryPath(_folderPath), Path.GetFileNameWithoutExtension(_fileName)), $"{(MapTyped)mapType}_" + _fileName);
|
||||
audioOverrideDatas[(MapTyped)mapType] = audioData;
|
||||
audioData.Load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the map appropriate AudioClip based on the currently active map.
|
||||
/// </summary>
|
||||
/// <param name="clip">When this method returns, contains the map specific AudioClip if successful; otherwise, null.</param>
|
||||
/// <returns>True if a map-specific AudioClip is available for the current map; otherwise, false.</returns>
|
||||
internal override bool TryGetAudioClip(out AudioClip? clip)
|
||||
{
|
||||
if (ShipStatus.Instance != null)
|
||||
{
|
||||
if (audioOverrideDatas.TryGetValue((MapTyped)ShipStatus.Instance.Type, out var audioData))
|
||||
{
|
||||
if (audioData.TryGetAudioClip(out var audio))
|
||||
{
|
||||
clip = audio;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clip = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,9 +32,54 @@ internal static class AudioOverridePatch
|
||||
[HarmonyPrefix]
|
||||
private static void MeetingCalledAnimation_CoShow_Prefix(MeetingCalledAnimation __instance)
|
||||
{
|
||||
if (AudioOverrideManager.Sounds_EmergencyMeeting.TryGetAudioClip(out var audio))
|
||||
if (AudioOverrideManager.Sounds_EmergencyMeetingStart.TryGetAudioClip(out var audio))
|
||||
{
|
||||
__instance.Stinger = audio;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Awake))]
|
||||
[HarmonyPrefix]
|
||||
private static void MeetingHud_Awake_Prefix(MeetingHud __instance)
|
||||
{
|
||||
if (AudioOverrideManager.Sounds_EmergencyMeetingVote.TryGetAudioClip(out var vote))
|
||||
{
|
||||
__instance.VoteSound = vote;
|
||||
}
|
||||
|
||||
if (AudioOverrideManager.Sounds_EmergencyMeetingVoteLockin.TryGetAudioClip(out var lockin))
|
||||
{
|
||||
__instance.VoteLockinSound = lockin;
|
||||
}
|
||||
|
||||
if (AudioOverrideManager.Sounds_EmergencyMeetingEnd.TryGetAudioClip(out var end))
|
||||
{
|
||||
__instance.VoteEndingSound = end;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Awake))]
|
||||
[HarmonyPostfix]
|
||||
private static void ShipStatus_Awake_Postfix(ShipStatus __instance)
|
||||
{
|
||||
if (__instance.VentExitSound == null)
|
||||
{
|
||||
__instance.VentExitSound = __instance.VentEnterSound;
|
||||
}
|
||||
|
||||
if (AudioOverrideManager.Sounds_VentEnter.TryGetAudioClip(out var ventEnter))
|
||||
{
|
||||
__instance.VentEnterSound = ventEnter;
|
||||
}
|
||||
|
||||
if (AudioOverrideManager.Sounds_VentExit.TryGetAudioClip(out var ventExit))
|
||||
{
|
||||
__instance.VentExitSound = ventExit;
|
||||
}
|
||||
|
||||
if (AudioOverrideManager.Sounds_SabotageAlert.TryGetAudioClip(out var sabo))
|
||||
{
|
||||
__instance.SabotageSound = sabo;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user