Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions soh/soh/Enhancements/Cheats/AdultCrawlspaces.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ShipInit.hpp"

#define CVAR_ADULT_CRAWLSPACES_NAME CVAR_CHEAT("AdultCrawlspaces")
#define CVAR_ADULT_CRAWLSPACES_VALUE CVarGetInteger(CVAR_ADULT_CRAWLSPACES_NAME, 0)

void RegisterAdultCrawlspaces() {
COND_VB_SHOULD(VB_LINK_BE_ABLE_TO_ENTER_CRAWLSPACE, CVAR_ADULT_CRAWLSPACES_VALUE, { *should = true; });
}

static RegisterShipInitFunc initFunc(RegisterAdultCrawlspaces, { CVAR_ADULT_CRAWLSPACES_NAME });
Original file line number Diff line number Diff line change
Expand Up @@ -2965,7 +2965,15 @@ typedef enum {
// ```
// #### `args`
// - `*int32_t (camId)`
VB_SHOULD_LOAD_BG_IMAGE
VB_SHOULD_LOAD_BG_IMAGE,

// #### `result`
// ```c
// !LINK_IS_ADULT
// ```
// #### `args`
// - None
VB_LINK_BE_ABLE_TO_ENTER_CRAWLSPACE,
} GIVanillaBehavior;

#endif
3 changes: 3 additions & 0 deletions soh/soh/SohGui/SohMenuEnhancements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,9 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Climb Everything", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_CHEAT("ClimbEverything"))
.Options(CheckboxOptions().Tooltip("Makes every surface in the game climbable."));
AddWidget(path, "Adult Crawlspaces", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_CHEAT("AdultCrawlspaces"))
.Options(CheckboxOptions().Tooltip("Allows Adult Link to enter crawlspaces."));
AddWidget(path, "Moon Jump on L", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_CHEAT("MoonJumpOnL"))
.Options(CheckboxOptions().Tooltip("Holding L makes you float into the air."));
Expand Down
5 changes: 3 additions & 2 deletions soh/src/overlays/actors/ovl_player_actor/z_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -7637,7 +7637,8 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall
f32 zVertex2;
s32 i;

if (!LINK_IS_ADULT && !(this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (interactWallFlags & 0x30)) {
if (GameInteractor_Should(VB_LINK_BE_ABLE_TO_ENTER_CRAWLSPACE, !LINK_IS_ADULT) &&
!(this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (interactWallFlags & 0x30)) {
if (!GameInteractor_Should(VB_CRAWL, true)) {
Comment on lines +7640 to 7642
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should these VBs be combined?

Copy link
Copy Markdown
Author

@unreference unreference May 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that as well, but I decided to keep them separate because they handle different conditions. VB_CRAWL is the same pattern as VB_OPEN_CHEST -- it's the randomizer shuffle gate (RAND_INF_CAN_CRAWL). VB_LINK_BE_ABLE_TO_ENTER_CRAWLSPACE wraps the age check which crawlspaces have, but chests don't. Keeping them separate means that the cheat can let Adult Link through without bypassing a possible future shuffle restriction.

That said, I don't imagine that ever actually being a randomization option simply because there aren't a lot of crawlspaces to begin with, so I think either works.

return false;
}
Expand Down Expand Up @@ -16707,4 +16708,4 @@ void Player_StartTalking(PlayState* play, Actor* actor) {
this->naviActor->flags |= ACTOR_FLAG_TALK;
func_80835EA4(play, 0xB);
}
}
}
Loading