Rando, prevent carrying abducted Ruto into Bigocto room (#6845)

If Ruto enters Bigocto's room after she has already been abducted, the room behaves weird due to actor functions. Randomizer respawns Ruto after abduction, so this can become a problem.

The easiest solution is probably to just not let player open doors to Bigocto room while carrying Ruto after abduction.
This fix makes shutter doors in randomizer when offering player to open the door - check scene, abduction flag, if door is transition actor index 21 or 3, held actor, and if held actor is Ruto.
Looks like this: https://www.youtube.com/watch?v=2Siq2Z41Pqo

The shutter door in decomp and thus this fix uses macros that are missing here, I copied all of them to the corresponding place in actor.h as they are very useful for actor params and will be added anyway when/if code is synced with decomp.
This commit is contained in:
djevangelia
2026-07-13 17:32:10 +02:00
committed by GitHub
parent d1d6a564e5
commit 852fb86cf2
3 changed files with 32 additions and 12 deletions
@@ -1496,6 +1496,14 @@ typedef enum {
// - `*EnKz`
VB_KING_ZORA_TUNIC_CHECK,
// #### `result`
// ```c
// false if in Jabu, carrying Ruto, abducted flag set, door is id 21 or 3
// ```
// #### `args`
// - `*Actor` (shutter door)
VB_JABU_PREVENT_RUTO_REENTER_BIGOCTO,
// #### `result`
// ```c
// varies
@@ -1271,6 +1271,17 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
}
break;
}
case VB_JABU_PREVENT_RUTO_REENTER_BIGOCTO: {
// Don't let player carry Ruto through doors 21 and 3 to Bigocto room if Ruto abducted flag set
Player* player = va_arg(args, Player*);
Actor* doorActor = va_arg(args, Actor*);
if (gPlayState->sceneNum == SCENE_JABU_JABU && GET_INFTABLE(INFTABLE_146) &&
(GET_TRANSITION_ACTOR_INDEX(doorActor) == 21 || GET_TRANSITION_ACTOR_INDEX(doorActor) == 3) &&
player->heldActor != NULL && player->heldActor->id == ACTOR_EN_RU1) {
*should = false;
}
break;
}
case VB_BIGGORON_CONSIDER_SWORD_COLLECTED: {
*should = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK);
break;
@@ -402,22 +402,23 @@ void DoorShutter_Idle(DoorShutter* this, PlayState* play) {
if (doorDirection != 0) {
Player* player = GET_PLAYER(play);
if (this->unlockTimer != 0) {
if (this->doorType == SHUTTER_BOSS) {
if (!CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, gSaveContext.mapIndex)) {
player->naviTextId = -0x204;
if (GameInteractor_Should(VB_JABU_PREVENT_RUTO_REENTER_BIGOCTO, true, player, &this->dyna.actor)) {
if (this->unlockTimer != 0) {
if (this->doorType == SHUTTER_BOSS) {
if (!CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, gSaveContext.mapIndex)) {
player->naviTextId = -0x204;
return;
}
} else if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0) {
player->naviTextId = -0x203;
return;
}
} else if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0) {
player->naviTextId = -0x203;
return;
player->doorTimer = 10;
}
player->doorTimer = 10;
player->doorType = PLAYER_DOORTYPE_SLIDING;
player->doorDirection = doorDirection;
player->doorActor = &this->dyna.actor;
}
player->doorType = PLAYER_DOORTYPE_SLIDING;
player->doorDirection = doorDirection;
player->doorActor = &this->dyna.actor;
}
}
}