diff --git a/MiraAPI/GameModes/HideAndSeekMode.cs b/MiraAPI/GameModes/HideAndSeekMode.cs index 2c0f38e..dfbed5c 100644 --- a/MiraAPI/GameModes/HideAndSeekMode.cs +++ b/MiraAPI/GameModes/HideAndSeekMode.cs @@ -309,12 +309,7 @@ public class HideAndSeekMode : AbstractGameMode __instance.HideAndSeekPanels.SetActive(false); __instance.CrewmateRules.SetActive(false); __instance.ImpostorRules.SetActive(false); - /*LogicOptionsHnS logicOptionsHnS = GameManager.Instance.LogicOptions as LogicOptionsHnS; - LogicHnSMusic logicHnSMusic = GameManager.Instance.GetLogicComponent() as LogicHnSMusic; - if (logicHnSMusic != null) - { - logicHnSMusic.StartMusicWithIntro(); - }*/ + HnsMusicHandler.Instance.StartMusicWithIntro(); var hideTimer = 10f; if (PlayerControl.LocalPlayer.Data.Role.IsImpostor) @@ -373,7 +368,7 @@ public class HideAndSeekMode : AbstractGameMode } else { - ShipStatus.Instance.HideCountdown = hideTimer; + HideAndSeekHudHelper.Instance.HideCountdown = hideTimer; if (AprilFoolsMode.ShouldHorseAround()) { if (impostor != null) @@ -395,6 +390,8 @@ public class HideAndSeekMode : AbstractGameMode } } ShipStatus.Instance.StartSFX(); + HnsMusicHandler.Instance.OnGameStart(); + HnsDangerMeter.Instance.OnGameStart(); UnityEngine.Object.Destroy(__instance.gameObject); } public override void Initialize() @@ -404,7 +401,9 @@ public class HideAndSeekMode : AbstractGameMode PlayerControl.LocalPlayer.SetKillTimer(0.01f); if (HudManager.InstanceExists) { + HudManager.Instance.gameObject.AddComponent(); HudManager.Instance.gameObject.AddComponent(); + HudManager.Instance.gameObject.AddComponent(); } } public override MapOptions GetMapOptions() diff --git a/MiraAPI/HnsReimplemented/HideAndSeekHudHelper.cs b/MiraAPI/HnsReimplemented/HideAndSeekHudHelper.cs index 329c8dc..d41b445 100644 --- a/MiraAPI/HnsReimplemented/HideAndSeekHudHelper.cs +++ b/MiraAPI/HnsReimplemented/HideAndSeekHudHelper.cs @@ -118,7 +118,65 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr) beepCoroutine = null!; } + private float taskDirtyTimer; + public float HideCountdown { get; set; } + public void LateUpdate() + { + if (!HudManager.InstanceExists) + { + return; + } + if (HideCountdown > 0f && taskDirtyTimer > 0.25f) + { + float num = taskDirtyTimer; + taskDirtyTimer = 0f; + if (!PlayerControl.LocalPlayer) + { + HudManager.Instance.TaskPanel.SetTaskText(string.Empty); + return; + } + NetworkedPlayerInfo data = PlayerControl.LocalPlayer.Data; + if (data == null) + { + return; + } + bool flag = data.Role != null && data.Role.IsImpostor; + HudManager.Instance.tasksString.Clear(); + if (PlayerControl.LocalPlayer.myTasks == null || PlayerControl.LocalPlayer.myTasks.Count == 0) + { + HudManager.Instance.tasksString.Append("None"); + } + else + { + for (int i = 0; i < PlayerControl.LocalPlayer.myTasks.Count; i++) + { + PlayerTask playerTask = PlayerControl.LocalPlayer.myTasks[i]; + if (playerTask) + { + if (playerTask.TaskType == TaskTypes.FixComms && !flag) + { + HudManager.Instance.tasksString.Clear(); + playerTask.AppendTaskText(HudManager.Instance.tasksString); + break; + } + playerTask.AppendTaskText(HudManager.Instance.tasksString); + } + } + if (data.Role != null) + { + data.Role.AppendTaskHint(HudManager.Instance.tasksString); + } + if (HideCountdown > 0f) + { + HideCountdown -= num; + HudManager.Instance.tasksString.Append("\n\n" + ((int)HideCountdown)); + } + HudManager.Instance.tasksString.TrimEnd(); + } + HudManager.Instance.TaskPanel.SetTaskText(HudManager.Instance.tasksString.ToString()); + } + } public void FixedUpdate() { secondsSinceLastSetDirty += Time.fixedDeltaTime; diff --git a/MiraAPI/HnsReimplemented/HnsDangerMeter.cs b/MiraAPI/HnsReimplemented/HnsDangerMeter.cs new file mode 100644 index 0000000..d36c198 --- /dev/null +++ b/MiraAPI/HnsReimplemented/HnsDangerMeter.cs @@ -0,0 +1,142 @@ +using System.Collections.Generic; +using System.Linq; +using MiraAPI.GameOptions; +using MiraAPI.HnsReimplemented.Options; +using MiraAPI.Utilities; +using Reactor.Utilities.Attributes; +using UnityEngine; + +namespace MiraAPI.HnsReimplemented; + +[RegisterInIl2Cpp] +public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr) +{ + public static HnsDangerMeter Instance; + + private void Awake() + { + Instance = this; + } + + private DangerMeter dangerMeter; + + private List impostors = []; + + private float scaryMusicDistance; + + private float veryScaryMusicDistance; + + private float dangerLevel1; + + private float dangerLevel2; + + private bool firstMusicActivation; + + private float firstCrossfadeCountdown; + + public void FixedUpdate() + { + PlayerControl localPlayer = PlayerControl.LocalPlayer; + if (impostors == null || localPlayer == null) + { + return; + } + + if (impostors.Count <= 0) + { + return; + } + + float num = float.MaxValue; + foreach (PlayerControl playerControl in impostors) + { + if (!(playerControl == null)) + { + float sqrMagnitude = (playerControl.transform.position - localPlayer.transform.position).sqrMagnitude; + if (sqrMagnitude < scaryMusicDistance && num > sqrMagnitude) + { + num = sqrMagnitude; + } + } + } + + if (HideAndSeekHudHelper.Instance.HideCountdown > 0f) + { + dangerLevel1 = 0f; + dangerLevel2 = 0f; + } + else + { + if (firstMusicActivation) + { + firstMusicActivation = false; + firstCrossfadeCountdown = 3f; + HnsMusicHandler.Instance.SetMusicCrossfadeSpeed(0.6f); + } + + if (firstCrossfadeCountdown > 0f) + { + firstCrossfadeCountdown -= Time.deltaTime; + if (firstCrossfadeCountdown <= 0f) + { + HnsMusicHandler.Instance.SetMusicCrossfadeSpeed(5f); + } + } + + dangerLevel1 = Mathf.Clamp01( + (scaryMusicDistance - num) / (scaryMusicDistance - veryScaryMusicDistance)); + dangerLevel2 = Mathf.Clamp01((veryScaryMusicDistance - num) / veryScaryMusicDistance); + } + + UpdateDangerMeter(); + UpdateDangerMusic(); + } + + private void UpdateDangerMusic() + { + PlayerControl localPlayer = PlayerControl.LocalPlayer; + if (localPlayer != null && localPlayer.Data != null && localPlayer.Data.IsDead) + { + HnsMusicHandler.Instance.SetTaskState(false); + HnsMusicHandler.Instance.ResetMusic(); + return; + } + + HnsMusicHandler.Instance.SetMusicValues(dangerLevel1, dangerLevel2); + } + + private void UpdateDangerMeter() + { + if (dangerMeter == null) + { + return; + } + + dangerMeter.SetDangerValue(dangerLevel1, dangerLevel2); + } + + public void OnGameStart() + { + firstMusicActivation = true; + if (!PlayerControl.LocalPlayer.Data.Role.IsImpostor) + { + dangerMeter = HudManager.Instance.DangerMeter; + dangerMeter.gameObject.SetActive(true); + } + + impostors = Helpers.GetAlivePlayers().Where(x => x.Data.Role.IsImpostor).ToList(); + + var baseSpeed = OptionGroupSingleton.Instance.PlayerSpeed.Value; + scaryMusicDistance = 55f * + baseSpeed; + veryScaryMusicDistance = 15f * + baseSpeed; + if (scaryMusicDistance < veryScaryMusicDistance) + { + float num = veryScaryMusicDistance; + float num2 = scaryMusicDistance; + scaryMusicDistance = num; + veryScaryMusicDistance = num2; + } + } +} diff --git a/MiraAPI/HnsReimplemented/HnsMusicHandler.cs b/MiraAPI/HnsReimplemented/HnsMusicHandler.cs new file mode 100644 index 0000000..e3b7d68 --- /dev/null +++ b/MiraAPI/HnsReimplemented/HnsMusicHandler.cs @@ -0,0 +1,237 @@ +using System.Collections.Generic; +using Amongus.GameModes.HideAndSeek; +using MiraAPI.GameOptions; +using MiraAPI.HnsReimplemented.Options; +using Reactor.Utilities.Attributes; +using UnityEngine; + +namespace MiraAPI.HnsReimplemented; + +[RegisterInIl2Cpp] +public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr) +{ + public static HnsMusicHandler Instance; + + private void Awake() + { + Instance = this; + } + + private HideAndSeekMusicCollection musicCollection; + + private float lastMusicSyncTime; + + private bool isDoingTask; + + private float normalVolume; + + private float taskVolume; + + private float dangerLevel1Volume; + + private float dangerLevel2Volume; + + private AudioSource normalSource; + + private AudioSource taskSource; + + private AudioSource dangerLevel1Source; + + private AudioSource dangerLevel2Source; + + private float musicLerpSpeed = 5f; + + public void Start() + { + musicCollection = GameManagerCreator.Instance.HideAndSeekManagerPrefab.MusicCollection; + } + + public void OnGameStart() + { + InitMusic(); + ResetMusic(); + } + + public void OnDestroy() + { + ResetMusic(); + } + + private void InitMusic() + { + if (normalSource == null) + { + normalSource = + SoundManager.Instance.GetNamedSfxSource(musicNames[LogicHnSMusic.HideAndSeekMusicTrack.Normal]); + } + + normalSource.outputAudioMixerGroup = SoundManager.Instance.MusicChannel; + normalSource.clip = musicCollection.NormalMusic; + normalSource.loop = true; + if (taskSource == null) + { + taskSource = + SoundManager.Instance.GetNamedSfxSource(musicNames[LogicHnSMusic.HideAndSeekMusicTrack.Task]); + } + + taskSource.outputAudioMixerGroup = SoundManager.Instance.MusicChannel; + taskSource.volume = 0f; + taskSource.clip = musicCollection.TaskMusic; + taskSource.loop = true; + if (dangerLevel1Source == null) + { + dangerLevel1Source = + SoundManager.Instance.GetNamedSfxSource( + musicNames[LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel1]); + } + + dangerLevel1Source.outputAudioMixerGroup = SoundManager.Instance.MusicChannel; + dangerLevel1Source.volume = 0f; + dangerLevel1Source.clip = musicCollection.DangerLevel1Music; + dangerLevel1Source.loop = true; + if (dangerLevel2Source == null) + { + dangerLevel2Source = + SoundManager.Instance.GetNamedSfxSource( + musicNames[LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel2]); + } + + dangerLevel2Source.outputAudioMixerGroup = SoundManager.Instance.MusicChannel; + dangerLevel2Source.volume = 0f; + dangerLevel2Source.clip = musicCollection.DangerLevel2Music; + dangerLevel2Source.loop = true; + normalSource.Play(); + taskSource.Play(); + dangerLevel1Source.Play(); + dangerLevel2Source.Play(); + SyncMusic(); + } + + public void StartMusicWithIntro() + { + if (PlayerControl.LocalPlayer.Data.Role.IsImpostor) + { + AudioClip clip = OptionGroupSingleton.Instance.HidingTime.Value <= 180f + ? musicCollection.ImpostorShortMusic + : musicCollection.ImpostorLongMusic; + if (AprilFoolsMode.ShouldHorseAround()) + { + clip = musicCollection.ImpostorRanchMusic; + } + + SoundManager.Instance.PlaySound(clip, true, 1f, SoundManager.Instance.MusicChannel); + } + } + + public void SetTaskState(bool isDoingTask) + { + isDoingTask = isDoingTask; + } + + public void FixedUpdate() + { + if (normalSource == null || taskSource == null || dangerLevel1Source == null || + dangerLevel2Source == null) + { + return; + } + + if (Time.unscaledTime > lastMusicSyncTime + 1f) + { + SyncMusic(); + } + + normalSource.volume = Mathf.Lerp( + normalSource.volume, + normalVolume, + Time.fixedDeltaTime * musicLerpSpeed); + taskSource.volume = Mathf.Lerp( + taskSource.volume, + taskVolume, + Time.fixedDeltaTime * musicLerpSpeed); + dangerLevel1Source.volume = Mathf.Lerp( + dangerLevel1Source.volume, + dangerLevel1Volume, + Time.fixedDeltaTime * musicLerpSpeed); + dangerLevel2Source.volume = Mathf.Lerp( + dangerLevel2Source.volume, + dangerLevel2Volume, + Time.fixedDeltaTime * musicLerpSpeed); + } + + private void SyncMusic() + { + taskSource.timeSamples = normalSource.timeSamples; + dangerLevel1Source.timeSamples = normalSource.timeSamples; + dangerLevel2Source.timeSamples = normalSource.timeSamples; + lastMusicSyncTime = Time.unscaledTime; + } + + public void ResetMusic() + { + SetMusicValues(0f, 0f); + } + + public void SetMusicCrossfadeSpeed(float lerpSpeed) + { + musicLerpSpeed = lerpSpeed; + } + + public void SetMusicValues(float dangerLevel1, float dangerLevel2) + { + if (PlayerControl.LocalPlayer != null && PlayerControl.LocalPlayer.Data.Role.IsImpostor) + { + return; + } + + if (normalSource == null || taskSource == null || dangerLevel1Source == null || + dangerLevel2Source == null) + { + return; + } + + normalVolume = (isDoingTask ? 0f : 1f); + taskVolume = (isDoingTask ? 1f : 0f); + dangerLevel1Volume = 0f; + dangerLevel2Volume = 0f; + if (dangerLevel1 > 0f) + { + dangerLevel1Volume = dangerLevel1; + if (isDoingTask) + { + taskVolume = 1f - dangerLevel1; + } + else + { + normalVolume = 1f - dangerLevel1; + } + } + + if (dangerLevel2 > 0f) + { + dangerLevel2Volume = dangerLevel2; + dangerLevel1Volume = 1f - dangerLevel2; + } + } + + private readonly Dictionary musicNames = + new Dictionary + { + { + LogicHnSMusic.HideAndSeekMusicTrack.Normal, + "HnS_Music_Normal" + }, + { + LogicHnSMusic.HideAndSeekMusicTrack.Task, + "HnS_Music_Task" + }, + { + LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel1, + "HnS_Music_DangerLevel1" + }, + { + LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel2, + "HnS_Music_DangerLevel2" + }, + }; +}