From 7c4a3359f005ab97483ed01fd83fe6a79a27d43a Mon Sep 17 00:00:00 2001 From: nclok1405 <155463060+nclok1405@users.noreply.github.com> Date: Tue, 6 Jan 2026 00:07:05 +0900 Subject: [PATCH] Enable Battle Music for Leever option + Modularize EnemyBGMDisable (#5985) Add "Enable Enemy Proximity Music for Leever" option + Modularize EnemyBGMDisable --- soh/soh/Enhancements/audio/AudioEditor.cpp | 10 +++++++ .../Enhancements/audio/EnemyBGMDisable.cpp | 12 ++++++++ soh/soh/Enhancements/audio/LeeverEnemyBGM.cpp | 30 +++++++++++++++++++ .../vanilla-behavior/GIVanillaBehavior.h | 11 +++++++ soh/src/code/z_actor.c | 9 ++++-- .../actors/ovl_player_actor/z_player.c | 2 +- 6 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 soh/soh/Enhancements/audio/EnemyBGMDisable.cpp create mode 100644 soh/soh/Enhancements/audio/LeeverEnemyBGM.cpp diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index d951f5eb4..19fa0ee8a 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -29,6 +29,7 @@ using namespace UIWidgets; static WidgetInfo lowHpAlarm; static WidgetInfo naviCall; static WidgetInfo enemyProx; +static WidgetInfo leeverProx; static WidgetInfo leadingMusic; static WidgetInfo displaySeqName; static WidgetInfo ovlDuration; @@ -577,6 +578,9 @@ void AudioEditor::DrawElement() { SohGui::mSohMenu->MenuDrawItem(lowHpAlarm, ImGui::GetContentRegionAvail().x, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(naviCall, ImGui::GetContentRegionAvail().x, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(enemyProx, ImGui::GetContentRegionAvail().x, THEME_COLOR); + if (!CVarGetInteger(CVAR_AUDIO("EnemyBGMDisable"), 0)) { + SohGui::mSohMenu->MenuDrawItem(leeverProx, ImGui::GetContentRegionAvail().x, THEME_COLOR); + } SohGui::mSohMenu->MenuDrawItem(leadingMusic, ImGui::GetContentRegionAvail().x, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(displaySeqName, ImGui::GetContentRegionAvail().x, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(ovlDuration, ImGui::GetContentRegionAvail().x, THEME_COLOR); @@ -870,6 +874,12 @@ void RegisterAudioWidgets() { .Tooltip("Disables the music change when getting close to enemies. Useful for hearing " "your custom music for each scene more often.")); + leeverProx = { .name = "Enable Enemy Proximity Music for Leever", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + leeverProx.CVar(CVAR_AUDIO("LeeverEnemyBGM")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Plays the battle music when getting close to a Leever, like in Majora's Mask.")); + leadingMusic = { .name = "Disable Leading Music in Lost Woods", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; leadingMusic.CVar(CVAR_AUDIO("LostWoodsConsistentVolume")) .Options(CheckboxOptions() diff --git a/soh/soh/Enhancements/audio/EnemyBGMDisable.cpp b/soh/soh/Enhancements/audio/EnemyBGMDisable.cpp new file mode 100644 index 000000000..27bd9fd8f --- /dev/null +++ b/soh/soh/Enhancements/audio/EnemyBGMDisable.cpp @@ -0,0 +1,12 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +static constexpr int32_t CVAR_ENEMYBGMDISABLE_DEFAULT = 0; +#define CVAR_ENEMYBGMDISABLE_NAME CVAR_AUDIO("EnemyBGMDisable") +#define CVAR_ENEMYBGMDISABLE_VALUE CVarGetInteger(CVAR_ENEMYBGMDISABLE_NAME, CVAR_ENEMYBGMDISABLE_DEFAULT) + +static void RegisterEnemyBGMDisable() { + COND_VB_SHOULD(VB_DETECT_BGM_ENEMY, CVAR_ENEMYBGMDISABLE_VALUE, { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterEnemyBGMDisable, { CVAR_ENEMYBGMDISABLE_NAME }); diff --git a/soh/soh/Enhancements/audio/LeeverEnemyBGM.cpp b/soh/soh/Enhancements/audio/LeeverEnemyBGM.cpp new file mode 100644 index 000000000..9d9b5f073 --- /dev/null +++ b/soh/soh/Enhancements/audio/LeeverEnemyBGM.cpp @@ -0,0 +1,30 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "macros.h" +} + +static constexpr int32_t CVAR_ENEMYBGMDISABLE_DEFAULT = 0; +#define CVAR_ENEMYBGMDISABLE_NAME CVAR_AUDIO("EnemyBGMDisable") +#define CVAR_ENEMYBGMDISABLE_VALUE CVarGetInteger(CVAR_ENEMYBGMDISABLE_NAME, CVAR_ENEMYBGMDISABLE_DEFAULT) + +static constexpr int32_t CVAR_LEEVERENEMYBGM_DEFAULT = 0; +#define CVAR_LEEVERENEMYBGM_NAME CVAR_AUDIO("LeeverEnemyBGM") +#define CVAR_LEEVERENEMYBGM_VALUE CVarGetInteger(CVAR_LEEVERENEMYBGM_NAME, CVAR_LEEVERENEMYBGM_DEFAULT) + +static void RegisterLeeverEnemyBGM() { + COND_VB_SHOULD(VB_DETECT_BGM_ENEMY, !CVAR_ENEMYBGMDISABLE_VALUE && CVAR_LEEVERENEMYBGM_VALUE, { + Actor* actor = va_arg(args, Actor*); + f32* sbgmEnemyDistSq = va_arg(args, f32*); + int32_t actorCategory = va_arg(args, int32_t); + + if ((actor->id == ACTOR_EN_REEBA) && + CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE) && + (actor->xyzDistToPlayerSq < SQ(500.0f)) && (actor->xyzDistToPlayerSq < *sbgmEnemyDistSq)) { + *should = true; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterLeeverEnemyBGM, { CVAR_ENEMYBGMDISABLE_NAME, CVAR_LEEVERENEMYBGM_NAME }); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 6c4729309..f473831c4 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -450,6 +450,17 @@ typedef enum { // - `*EnCow` VB_DESPAWN_HORSE_RACE_COW, + // #### `result` + // ```c + // (actorCategory == ACTORCAT_ENEMY) && CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_ATTENTION_ENABLED | + // ACTOR_FLAG_HOSTILE) && (actor->xyzDistToPlayerSq < SQ(500.0f)) && (actor->xyzDistToPlayerSq < sbgmEnemyDistSq) + // ``` + // #### `args` + // - `*Actor` + // - `*f32` (sbgmEnemyDistSq) + // - `int32_t` (actorCategory) + VB_DETECT_BGM_ENEMY, + // #### `result` // ```c // !Flags_GetSwitch(play, this->actor.params & 0x3F) diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 59966491c..605662669 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -3571,9 +3571,12 @@ void func_800328D4(PlayState* play, ActorContext* actorCtx, Player* player, u32 // This block below is for determining the closest actor to player in determining the volume // used while playing enemy bgm music - if ((actorCategory == ACTORCAT_ENEMY) && - CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE) && - (actor->xyzDistToPlayerSq < SQ(500.0f)) && (actor->xyzDistToPlayerSq < sbgmEnemyDistSq)) { + if (GameInteractor_Should( + VB_DETECT_BGM_ENEMY, + (actorCategory == ACTORCAT_ENEMY) && + CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE) && + (actor->xyzDistToPlayerSq < SQ(500.0f)) && (actor->xyzDistToPlayerSq < sbgmEnemyDistSq), + actor, &sbgmEnemyDistSq, (int32_t)actorCategory)) { actorCtx->targetCtx.bgmEnemy = actor; sbgmEnemyDistSq = actor->xyzDistToPlayerSq; } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 2de7113d2..c01fa161f 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -11599,7 +11599,7 @@ void Player_UpdateCamAndSeqModes(PlayState* play, Player* this) { seqMode = SEQ_MODE_STILL; } - if (play->actorCtx.targetCtx.bgmEnemy != NULL && !CVarGetInteger(CVAR_AUDIO("EnemyBGMDisable"), 0)) { + if (play->actorCtx.targetCtx.bgmEnemy != NULL) { seqMode = SEQ_MODE_ENEMY; Audio_SetBgmEnemyVolume(sqrtf(play->actorCtx.targetCtx.bgmEnemy->xyzDistToPlayerSq)); }