summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--soh/soh/Enhancements/Minigames/BombchuBowling.cpp95
-rw-r--r--soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h16
-rw-r--r--soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c9
3 files changed, 113 insertions, 7 deletions
diff --git a/soh/soh/Enhancements/Minigames/BombchuBowling.cpp b/soh/soh/Enhancements/Minigames/BombchuBowling.cpp
new file mode 100644
index 000000000..24ae8246c
--- /dev/null
+++ b/soh/soh/Enhancements/Minigames/BombchuBowling.cpp
@@ -0,0 +1,95 @@
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/ShipInit.hpp"
+
+extern "C" {
+#include "functions.h"
+extern PlayState* gPlayState;
+}
+
+#define CVAR_BOWLING_NAME CVAR_ENHANCEMENT("CustomizeBombchuBowling")
+#define CVAR_BOWLING_VALUE CVarGetInteger(CVAR_BOWLING_NAME, 0)
+
+#define CVAR_CUCCO_SMALL_NAME CVAR_ENHANCEMENT("BombchuBowlingNoSmallCucco")
+#define CVAR_CUCCO_SMALL_VALUE CVarGetInteger(CVAR_CUCCO_SMALL_NAME, 0)
+
+#define CVAR_CUCCO_BIG_NAME CVAR_ENHANCEMENT("BombchuBowlingNoBigCucco")
+#define CVAR_CUCCO_BIG_VALUE CVarGetInteger(CVAR_CUCCO_BIG_NAME, 0)
+
+static constexpr s32 CUCCO_BOWLING_AMMO_DEFAULT = 10;
+#define CVAR_BOWLING_AMMO_NAME CVAR_ENHANCEMENT("BombchuBowlingAmmo")
+#define CVAR_BOWLING_AMMO_VALUE CVarGetInteger(CVAR_BOWLING_AMMO_NAME, CUCCO_BOWLING_AMMO_DEFAULT)
+
+static constexpr f32 CUCCO_SEARCH_Z = -520.0f;
+
+typedef enum {
+ CUCCO_INDEX_SMALL,
+ CUCCO_INDEX_BIG,
+} BombchuBowlingCuccoIndex;
+
+static void KillSmallCucco() {
+ Actor* cucco = gPlayState->actorCtx.actorLists[ACTORCAT_PROP].head;
+
+ while (cucco != NULL) {
+ if (cucco->id == ACTOR_EN_SYATEKI_NIW && cucco->home.pos.z > CUCCO_SEARCH_Z) {
+ Actor_Kill(cucco);
+ break;
+ }
+ cucco = cucco->next;
+ }
+}
+
+static void KillBigCucco() {
+ Actor* cucco = gPlayState->actorCtx.actorLists[ACTORCAT_PROP].head;
+
+ while (cucco != NULL) {
+ if (cucco->id == ACTOR_EN_SYATEKI_NIW && cucco->home.pos.z < CUCCO_SEARCH_Z) {
+ Actor_Kill(cucco);
+ break;
+ }
+ cucco = cucco->next;
+ }
+}
+
+static void RegisterBombchuBowlingNoSmallCucco() {
+ s32 noCucco = CVAR_BOWLING_VALUE && CVAR_CUCCO_SMALL_VALUE;
+
+ if (noCucco && gPlayState != NULL && gPlayState->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY) {
+ KillSmallCucco();
+ }
+
+ COND_VB_SHOULD(VB_SPAWN_BOMBCHU_BOWLING_CUCCOS, noCucco, {
+ s32 index = va_arg(args, s32);
+ if (index == CUCCO_INDEX_SMALL) {
+ *should = false;
+ }
+ });
+}
+
+static void RegisterBombchuBowlingNoBigCucco() {
+ s32 noCucco = CVAR_BOWLING_VALUE && CVAR_CUCCO_BIG_VALUE;
+
+ if (noCucco && gPlayState != NULL && gPlayState->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY) {
+ KillBigCucco();
+ }
+
+ COND_VB_SHOULD(VB_SPAWN_BOMBCHU_BOWLING_CUCCOS, noCucco, {
+ s32 index = va_arg(args, s32);
+ if (index == CUCCO_INDEX_BIG) {
+ *should = false;
+ }
+ });
+}
+
+static void RegisterBombchuBowlingAmmo() {
+ COND_VB_SHOULD(VB_SET_BOMBCHU_BOWLING_AMMO,
+ CVAR_BOWLING_VALUE && (CVAR_BOWLING_AMMO_VALUE != CUCCO_BOWLING_AMMO_DEFAULT), {
+ gPlayState->bombchuBowlingStatus = CVAR_BOWLING_AMMO_VALUE;
+ *should = false;
+ });
+}
+
+static RegisterShipInitFunc initFunc_SmallCucco(RegisterBombchuBowlingNoSmallCucco,
+ { CVAR_BOWLING_NAME, CVAR_CUCCO_SMALL_NAME });
+static RegisterShipInitFunc initFunc_BigCucco(RegisterBombchuBowlingNoBigCucco,
+ { CVAR_BOWLING_NAME, CVAR_CUCCO_BIG_NAME });
+static RegisterShipInitFunc initFunc_Ammo(RegisterBombchuBowlingAmmo, { CVAR_BOWLING_NAME, CVAR_BOWLING_AMMO_NAME });
diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
index f8196a1a1..81c2acc2f 100644
--- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
+++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
@@ -2345,6 +2345,14 @@ typedef enum {
// true
// ```
// #### `args`
+ // - `None`
+ VB_SET_BOMBCHU_BOWLING_AMMO,
+
+ // #### `result`
+ // ```c
+ // true
+ // ```
+ // #### `args`
// - `int32_t` (button - promoted from `s16`)
VB_SET_BUTTON_ITEM_FROM_C_BUTTON_SLOT,
@@ -2548,6 +2556,14 @@ typedef enum {
// #### `result`
// ```c
+ // true
+ // ```
+ // #### `args`
+ // - `s32` (Cucco index; 0 = small, 1 = big)
+ VB_SPAWN_BOMBCHU_BOWLING_CUCCOS,
+
+ // #### `result`
+ // ```c
// this->timer == 4
// ```
// #### `args`
diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
index 32d8bbcaa..cb89cebd6 100644
--- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
+++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
@@ -75,10 +75,7 @@ void EnBomBowlMan_Init(Actor* thisx, PlayState* play2) {
Actor_SetScale(&this->actor, 0.013f);
for (i = 0; i < 2; i++) {
- if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeBombchuBowling"), 0) &&
- CVarGetInteger(i == 0 ? CVAR_ENHANCEMENT("BombchuBowlingNoSmallCucco")
- : CVAR_ENHANCEMENT("BombchuBowlingNoBigCucco"),
- 0)) {
+ if (!GameInteractor_Should(VB_SPAWN_BOMBCHU_BOWLING_CUCCOS, true, i)) {
continue;
}
@@ -321,9 +318,7 @@ void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, PlayState* play) {
Rupees_ChangeBy(-30);
this->minigamePlayStatus = 1;
this->wallStatus[0] = this->wallStatus[1] = 0;
- if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeBombchuBowling"), 0)) {
- play->bombchuBowlingStatus = CVarGetInteger(CVAR_ENHANCEMENT("BombchuBowlingAmmo"), 10);
- } else {
+ if (GameInteractor_Should(VB_SET_BOMBCHU_BOWLING_AMMO, true)) {
play->bombchuBowlingStatus = 10;
}
Flags_SetSwitch(play, 0x38);