From 7c42a63cebcb85489473c9a4deca4b515a75377b Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 11 Jun 2026 14:49:55 +0200 Subject: [PATCH] Add the 2 "decoy" crates as NL crates (#6672) --- .../vanilla-behavior/GIVanillaBehavior.h | 6 +++ .../Enhancements/randomizer/RCToRandInf.cpp | 8 ++++ .../Enhancements/randomizer/ShuffleCrates.cpp | 46 ++++++++++++------- .../overworld/gerudo_fortress.cpp | 3 ++ .../randomizerEnums/RandomizerCheck.h | 2 + .../randomizerEnums/RandomizerInf.h | 2 + soh/src/code/z_en_item00.c | 2 +- 7 files changed, 51 insertions(+), 18 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 16389f8ad5..d7a66640d8 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -3004,6 +3004,12 @@ typedef enum { // #### `result` // ```c + // this->actor.floorHeight <= -10000.0f + // ``` + // #### `args` + // - `*EnItem00` + VB_ITEM00_KILL, + // true // ``` // #### `args` diff --git a/soh/soh/Enhancements/randomizer/RCToRandInf.cpp b/soh/soh/Enhancements/randomizer/RCToRandInf.cpp index 0cde9e4665..aab4a19f73 100644 --- a/soh/soh/Enhancements/randomizer/RCToRandInf.cpp +++ b/soh/soh/Enhancements/randomizer/RCToRandInf.cpp @@ -1220,6 +1220,14 @@ std::map rcToRandomizerInf = { RC_GF_SOUTH_TARGET_WEST_CRATE, RAND_INF_GF_SOUTH_TARGET_WEST_CRATE, }, + { + RC_GF_FAR_AWAY_CRATE_CHILD, + RAND_INF_GF_FAR_AWAY_CRATE_CHILD, + }, + { + RC_GF_FAR_AWAY_CRATE_ADULT, + RAND_INF_GF_FAR_AWAY_CRATE_ADULT, + }, { RC_TH_NEAR_KITCHEN_LEFTMOST_CRATE, RAND_INF_TH_NEAR_KITCHEN_LEFTMOST_CRATE, diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp index 2f835d965c..d3308578c5 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp @@ -248,23 +248,22 @@ void ObjKibako2_RandomizerInit(void* actorRef) { Actor* actor = static_cast(actorRef); auto logicSetting = RAND_GET_OPTION(RSK_LOGIC_RULES); - // don't shuffle two OOB crates in GF and don't shuffle child GV/GF crates when not in no logic - if (actor->id != ACTOR_OBJ_KIBAKO2 || - (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == -4051 && - (s16)actor->world.pos.z == -3429) || - (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == -4571 && - (s16)actor->world.pos.z == -3429) || - (logicSetting.IsNot(RO_LOGIC_NO_LOGIC) && - ((gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == 3443 && - (s16)actor->world.pos.z == -4876) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -764 && - (s16)actor->world.pos.z == 148) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -860 && - (s16)actor->world.pos.z == -125) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -860 && - (s16)actor->world.pos.z == -150) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -860 && - (s16)actor->world.pos.z == -90)))) + // don't shuffle the no logic crates when not in no logic + if (actor->id != ACTOR_OBJ_KIBAKO2 || (logicSetting.IsNot(RO_LOGIC_NO_LOGIC) && + ((gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && + (s16)actor->world.pos.x == -4051 && (s16)actor->world.pos.z == -3429) || + (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && + (s16)actor->world.pos.x == -4571 && (s16)actor->world.pos.z == -3429) || + (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && + (s16)actor->world.pos.x == 3443 && (s16)actor->world.pos.z == -4876) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -764 && (s16)actor->world.pos.z == 148) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -125) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -150) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -90)))) return; ObjKibako2* crateActor = static_cast(actorRef); @@ -327,6 +326,17 @@ void RegisterShuffleCrates() { *should = true; } }); + + // Prevent the randomized items from the "decoy" crates from immediately despawning + COND_VB_SHOULD(VB_ITEM00_KILL, shouldRegister, { + if (RAND_GET_OPTION(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS) { + EnItem00* item00 = va_arg(args, EnItem00*); + + if (item00->actor.world.pos.x < -3500.0f) { + *should &= item00->actor.world.pos.y < -10000.0f; + } + } + }); } void Rando::StaticData::RegisterCrateLocations() { @@ -417,6 +427,8 @@ void Rando::StaticData::RegisterCrateLocations() { locationTable[RC_GV_CRATE_BRIDGE_3] = Location::NLCrate(RC_GV_CRATE_BRIDGE_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-860, -150), "Near Bridge Crate 3", RHT_CRATE_GERUDO_VALLEY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_CRATE_BRIDGE_3)); locationTable[RC_GV_CRATE_BRIDGE_4] = Location::NLCrate(RC_GV_CRATE_BRIDGE_4, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(-860, -90), "Near Bridge Crate 4", RHT_CRATE_GERUDO_VALLEY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_CRATE_BRIDGE_4)); locationTable[RC_GF_NORTH_TARGET_CHILD_CRATE] = Location::NLCrate(RC_GF_NORTH_TARGET_CHILD_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(3443, -4876), "North Target Child Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTH_TARGET_CHILD_CRATE)); + locationTable[RC_GF_FAR_AWAY_CRATE_CHILD] = Location::NLCrate(RC_GF_FAR_AWAY_CRATE_CHILD, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-4571, -3429), "Far Away Crate Child", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAR_AWAY_CRATE_CHILD)); + locationTable[RC_GF_FAR_AWAY_CRATE_ADULT] = Location::NLCrate(RC_GF_FAR_AWAY_CRATE_ADULT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-4051, -3429), "Far Away Crate Adult", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAR_AWAY_CRATE_ADULT)); // MQ Crates // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index d57288f406..e092d9ce7a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -258,6 +258,9 @@ void RegionTable_Init_GerudoFortress() { }, { //Locations LOCATION(RC_GF_GATE_EXIT_RECTANGLE_SIGN, logic->IsAdult && logic->CanRead()), + // "Decoy" crates to look like the crate in wasteland + LOCATION(RC_GF_FAR_AWAY_CRATE_CHILD, logic->IsChild && false), + LOCATION(RC_GF_FAR_AWAY_CRATE_ADULT, logic->IsAdult && false), }, { //Exits ENTRANCE(RR_GF_OUTSKIRTS, logic->Get(LOGIC_GF_GATE_OPEN)), diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h index dfdb5d22c6..b60768b28f 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerCheck.h @@ -1329,6 +1329,8 @@ RANDO_ENUM_ITEM(RC_GF_NORTH_TARGET_WEST_CRATE) RANDO_ENUM_ITEM(RC_GF_NORTH_TARGET_CHILD_CRATE) RANDO_ENUM_ITEM(RC_GF_SOUTH_TARGET_EAST_CRATE) RANDO_ENUM_ITEM(RC_GF_SOUTH_TARGET_WEST_CRATE) +RANDO_ENUM_ITEM(RC_GF_FAR_AWAY_CRATE_CHILD) +RANDO_ENUM_ITEM(RC_GF_FAR_AWAY_CRATE_ADULT) RANDO_ENUM_ITEM(RC_TH_NEAR_KITCHEN_LEFTMOST_CRATE) RANDO_ENUM_ITEM(RC_TH_NEAR_KITCHEN_MID_LEFT_CRATE) RANDO_ENUM_ITEM(RC_TH_NEAR_KITCHEN_MID_RIGHT_CRATE) diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h index 7f142c787b..6dc342aa1a 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h @@ -794,6 +794,8 @@ RANDO_ENUM_ITEM(RAND_INF_GF_NORTH_TARGET_WEST_CRATE) RANDO_ENUM_ITEM(RAND_INF_GF_NORTH_TARGET_CHILD_CRATE) RANDO_ENUM_ITEM(RAND_INF_GF_SOUTH_TARGET_EAST_CRATE) RANDO_ENUM_ITEM(RAND_INF_GF_SOUTH_TARGET_WEST_CRATE) +RANDO_ENUM_ITEM(RAND_INF_GF_FAR_AWAY_CRATE_CHILD) +RANDO_ENUM_ITEM(RAND_INF_GF_FAR_AWAY_CRATE_ADULT) RANDO_ENUM_ITEM(RAND_INF_TH_NEAR_KITCHEN_LEFTMOST_CRATE) RANDO_ENUM_ITEM(RAND_INF_TH_NEAR_KITCHEN_MID_LEFT_CRATE) RANDO_ENUM_ITEM(RAND_INF_TH_NEAR_KITCHEN_MID_RIGHT_CRATE) diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index b2da1c40db..237745a016 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -823,7 +823,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { if (sp3A || D_80157D94[0]) { Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 15.0f, 15.0f, 0x1D); - if (this->actor.floorHeight <= -10000.0f) { + if (GameInteractor_Should(VB_ITEM00_KILL, this->actor.floorHeight <= -10000.0f, this)) { Actor_Kill(&this->actor); return; }