mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-21 06:48:39 -04:00
bombchu bowling setting: first item (#7070)
desirable for speedrun settings that want less variance. also use for moving rando logic into hooks
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "functions.h"
|
||||
#include "src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
@@ -19,6 +21,9 @@ 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)
|
||||
|
||||
#define CVAR_BOWLING_FIRST_PRIZE_NAME CVAR_ENHANCEMENT("BombchuBowlingFirstPrize")
|
||||
#define CVAR_BOWLING_FIRST_PRIZE_VALUE CVarGetInteger(CVAR_BOWLING_FIRST_PRIZE_NAME, BOWLING_FIRST_PRIZE_RANDOM)
|
||||
|
||||
static constexpr f32 CUCCO_SEARCH_Z = -520.0f;
|
||||
|
||||
typedef enum {
|
||||
@@ -88,8 +93,20 @@ static void RegisterBombchuBowlingAmmo() {
|
||||
});
|
||||
}
|
||||
|
||||
static void RegisterBombchuBowlingFirstPrize() {
|
||||
COND_VB_SHOULD(VB_SET_BOMBCHU_BOWLING_PRIZE_SELECT,
|
||||
!IS_RANDO && CVAR_BOWLING_VALUE && (CVAR_BOWLING_FIRST_PRIZE_VALUE != BOWLING_FIRST_PRIZE_RANDOM), {
|
||||
EnBomBowlMan* bowlMan = va_arg(args, EnBomBowlMan*);
|
||||
s16 prizeSelect = CVAR_BOWLING_FIRST_PRIZE_VALUE - 1;
|
||||
bowlMan->prizeSelect = prizeSelect;
|
||||
*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 });
|
||||
static RegisterShipInitFunc initFunc_FirstPrize(RegisterBombchuBowlingFirstPrize,
|
||||
{ CVAR_BOWLING_NAME, CVAR_BOWLING_FIRST_PRIZE_NAME, "IS_RANDO" });
|
||||
|
||||
@@ -124,6 +124,16 @@ typedef enum {
|
||||
INGO_RACE_NONE,
|
||||
} IngoRaceType;
|
||||
|
||||
// The Bombchu Bowling prize cycle always runs in this order, only the entry it starts on is random
|
||||
typedef enum {
|
||||
BOWLING_FIRST_PRIZE_RANDOM,
|
||||
BOWLING_FIRST_PRIZE_BOMB_BAG,
|
||||
BOWLING_FIRST_PRIZE_PURPLE_RUPEE,
|
||||
BOWLING_FIRST_PRIZE_BOMBCHUS,
|
||||
BOWLING_FIRST_PRIZE_HEART_PIECE,
|
||||
BOWLING_FIRST_PRIZE_BOMBS,
|
||||
} BombchuBowlingFirstPrize;
|
||||
|
||||
typedef enum {
|
||||
RANDOMIZE_OFF,
|
||||
RANDOMIZE_ON_NEW_SCENE,
|
||||
|
||||
@@ -2477,6 +2477,23 @@ typedef enum {
|
||||
// - `None`
|
||||
VB_SET_BOMBCHU_BOWLING_AMMO,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnBomBowlMan`
|
||||
// - `s16*` (prize to show, an `ExItemType`)
|
||||
VB_SET_BOMBCHU_BOWLING_PRIZE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnBomBowlMan`
|
||||
VB_SET_BOMBCHU_BOWLING_PRIZE_SELECT,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include "z64save.h"
|
||||
#include "item_override.h"
|
||||
#include "hint.h"
|
||||
#include "fishsanity.h"
|
||||
|
||||
@@ -45,6 +45,7 @@ extern "C" {
|
||||
#include "src/overlays/actors/ovl_En_Box/z_en_box.h"
|
||||
#include "src/overlays/actors/ovl_En_Skj/z_en_skj.h"
|
||||
#include "src/overlays/actors/ovl_En_Hy/z_en_hy.h"
|
||||
#include "src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h"
|
||||
#include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h"
|
||||
#include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h"
|
||||
#include "src/overlays/actors/ovl_En_Ge2/z_en_ge2.h"
|
||||
@@ -1940,6 +1941,36 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
*should = INV_CONTENT((RAND_GET_OPTION(RSK_BOMBCHU_BAG) ? ITEM_BOMBCHU : ITEM_BOMB)) != ITEM_NONE;
|
||||
break;
|
||||
}
|
||||
case VB_SET_BOMBCHU_BOWLING_PRIZE_SELECT: {
|
||||
EnBomBowlMan* bowlMan = va_arg(args, EnBomBowlMan*);
|
||||
bowlMan->prizeSelect = 0;
|
||||
*should = false;
|
||||
break;
|
||||
}
|
||||
case VB_SET_BOMBCHU_BOWLING_PRIZE: {
|
||||
EnBomBowlMan* bowlMan = va_arg(args, EnBomBowlMan*);
|
||||
s16* prize = va_arg(args, s16*);
|
||||
switch (bowlMan->prizeSelect) {
|
||||
case 0:
|
||||
*prize = Flags_GetItemGetInf(ITEMGETINF_11) ? EXITEM_PURPLE_RUPEE_BOWLING : EXITEM_BOMB_BAG_BOWLING;
|
||||
break;
|
||||
case 1:
|
||||
*prize =
|
||||
Flags_GetItemGetInf(ITEMGETINF_12) ? EXITEM_PURPLE_RUPEE_BOWLING : EXITEM_HEART_PIECE_BOWLING;
|
||||
break;
|
||||
case 2:
|
||||
*prize = EXITEM_BOMBCHUS_BOWLING;
|
||||
break;
|
||||
case 3:
|
||||
*prize = EXITEM_PURPLE_RUPEE_BOWLING;
|
||||
break;
|
||||
case 4:
|
||||
*prize = EXITEM_BOMBS_BOWLING;
|
||||
break;
|
||||
}
|
||||
*should = false;
|
||||
break;
|
||||
}
|
||||
case VB_SHOULD_CHECK_FOR_FISHING_RECORD: {
|
||||
f32 sFishOnHandLength = *va_arg(args, f32*);
|
||||
*should = *should || ShouldGiveFishingPrize(sFishOnHandLength);
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
#include <soh/OTRGlobals.h>
|
||||
#include <soh/Enhancements/cosmetics/authenticGfxPatches.h>
|
||||
#include <soh/Enhancements/TimeDisplay/TimeDisplay.h>
|
||||
#include "soh/Enhancements/randomizer/randomizer.h"
|
||||
#include "soh/Enhancements/Restorations/GetItemManipulation.h"
|
||||
#include "soh/Enhancements/randomizer/SeedContext.h"
|
||||
#include <ship/Context.h>
|
||||
|
||||
extern "C" {
|
||||
#include "functions.h"
|
||||
#include "variables.h"
|
||||
#include "macros.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
@@ -87,6 +88,15 @@ static const std::map<int32_t, const char*> sleepingWaterfallOptions = {
|
||||
{ WATERFALL_NEVER, "Never" },
|
||||
};
|
||||
|
||||
static const std::map<int32_t, const char*> bombchuBowlingFirstPrizeOptions = {
|
||||
{ BOWLING_FIRST_PRIZE_RANDOM, "Random" },
|
||||
{ BOWLING_FIRST_PRIZE_BOMB_BAG, "Bomb Bag" },
|
||||
{ BOWLING_FIRST_PRIZE_PURPLE_RUPEE, "Purple Rupee" },
|
||||
{ BOWLING_FIRST_PRIZE_BOMBCHUS, "Bombchus" },
|
||||
{ BOWLING_FIRST_PRIZE_HEART_PIECE, "Heart Piece" },
|
||||
{ BOWLING_FIRST_PRIZE_BOMBS, "Bombs" },
|
||||
};
|
||||
|
||||
static const std::map<int32_t, const char*> allPowers = {
|
||||
{ DAMAGE_VANILLA, "Vanilla (1x)" }, { DAMAGE_DOUBLE, "Double (2x)" },
|
||||
{ DAMAGE_QUADRUPLE, "Quadruple (4x)" }, { DAMAGE_OCTUPLE, "Octuple (8x)" },
|
||||
@@ -1524,6 +1534,13 @@ void SohMenu::AddMenuEnhancements() {
|
||||
.DefaultValue(10)
|
||||
.Format("%d bombchus")
|
||||
.Tooltip("The number of Bombchus available at the start of the Bombchu Bowling minigame."));
|
||||
AddWidget(path, "First Prize", WIDGET_CVAR_COMBOBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("BombchuBowlingFirstPrize"))
|
||||
.PreFunc(bombchuBowlingDisabledFunc)
|
||||
.Options(ComboboxOptions()
|
||||
.ComboMap(bombchuBowlingFirstPrizeOptions)
|
||||
.DefaultIndex(BOWLING_FIRST_PRIZE_RANDOM)
|
||||
.Tooltip("The prize the cycle starts on."));
|
||||
AddWidget(path, "Horseback Archery", WIDGET_SEPARATOR_TEXT);
|
||||
AddWidget(path, "Customize Behavior##HBA", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("CustomizeHorsebackArchery"))
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h"
|
||||
#include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h"
|
||||
#include "objects/object_bg/object_bg.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
#define FLAGS \
|
||||
@@ -88,7 +86,9 @@ void EnBomBowlMan_Init(Actor* thisx, PlayState* play2) {
|
||||
}
|
||||
}
|
||||
|
||||
this->prizeSelect = IS_RANDO ? 0 : (s16)Rand_ZeroFloat(4.99f);
|
||||
if (GameInteractor_Should(VB_SET_BOMBCHU_BOWLING_PRIZE_SELECT, true, this)) {
|
||||
this->prizeSelect = (s16)Rand_ZeroFloat(4.99f);
|
||||
}
|
||||
this->actor.targetMode = 1;
|
||||
this->actionFunc = EnBomBowMan_SetupWaitAsleep;
|
||||
}
|
||||
@@ -174,17 +174,9 @@ void EnBomBowMan_CheckBeatenDC(EnBomBowlMan* this, PlayState* play) {
|
||||
this->eyeMode = CHU_GIRL_EYES_AWAKE;
|
||||
this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20;
|
||||
|
||||
bool bombchuBowlingClosed;
|
||||
if (IS_RANDO) {
|
||||
// when rando'd, check if we have bombchus if chus are in logic
|
||||
// and check if we have a bomb bag if chus aren't in logic
|
||||
u8 explosive = Randomizer_GetSettingValue(RSK_BOMBCHU_BAG) ? ITEM_BOMBCHU : ITEM_BOMB;
|
||||
bombchuBowlingClosed = (INV_CONTENT(explosive) == ITEM_NONE);
|
||||
} else {
|
||||
// if not rando'd, check if we have beaten Dodongo's Cavern
|
||||
bombchuBowlingClosed = !((Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) || BREG(2));
|
||||
}
|
||||
if (bombchuBowlingClosed) {
|
||||
// Check for beaten Dodongo's Cavern
|
||||
if (!GameInteractor_Should(VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING,
|
||||
(Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) || BREG(2))) {
|
||||
this->actionFunc = EnBomBowMan_WaitNotBeatenDC;
|
||||
} else {
|
||||
this->actor.textId = 0x18;
|
||||
@@ -407,39 +399,30 @@ void EnBomBowMan_ChooseShowPrize(EnBomBowlMan* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
|
||||
if (this->prizeRevealTimer == 0) {
|
||||
switch (this->prizeSelect) {
|
||||
case 0:
|
||||
prizeTemp = EXITEM_BOMB_BAG_BOWLING;
|
||||
if (Flags_GetItemGetInf(ITEMGETINF_11)) {
|
||||
if (GameInteractor_Should(VB_SET_BOMBCHU_BOWLING_PRIZE, true, this, &prizeTemp)) {
|
||||
switch (this->prizeSelect) {
|
||||
case 0:
|
||||
prizeTemp = EXITEM_BOMB_BAG_BOWLING;
|
||||
if (Flags_GetItemGetInf(ITEMGETINF_11)) {
|
||||
prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (!IS_RANDO) {
|
||||
prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
|
||||
} else {
|
||||
break;
|
||||
case 2:
|
||||
prizeTemp = EXITEM_BOMBCHUS_BOWLING;
|
||||
break;
|
||||
case 3:
|
||||
prizeTemp = EXITEM_HEART_PIECE_BOWLING;
|
||||
if (Flags_GetItemGetInf(ITEMGETINF_12)) {
|
||||
prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
prizeTemp = EXITEM_BOMBCHUS_BOWLING;
|
||||
break;
|
||||
case 3:
|
||||
if (!IS_RANDO) {
|
||||
prizeTemp = EXITEM_HEART_PIECE_BOWLING;
|
||||
if (Flags_GetItemGetInf(ITEMGETINF_12)) {
|
||||
prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
|
||||
}
|
||||
} else {
|
||||
prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
prizeTemp = EXITEM_BOMBS_BOWLING;
|
||||
break;
|
||||
break;
|
||||
case 4:
|
||||
prizeTemp = EXITEM_BOMBS_BOWLING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->prizeIndex = prizeTemp;
|
||||
|
||||
Reference in New Issue
Block a user