This commit is contained in:
Philip Dubé 2025-07-02 00:41:11 +00:00 committed by GitHub
commit 44fcdb8dd0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 671 additions and 25 deletions

View file

@ -2155,6 +2155,23 @@ typedef enum {
// - `*EnWood02`
VB_TREE_DROP_COLLECTIBLE,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*ObjWood02`
VB_TREE_SETUP_DRAW,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*ObjWood02`
VB_TREE_DROP_ITEM,
// #### `result`
// ```c
// true
// ```

View file

@ -2102,6 +2102,30 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
/*german*/ "Man erzählt sich, daß eine #Kiste im Labor am See# #[[1]]# enthielte.",
/*french*/ "Selon moi, une #caisse dans un laboratoire# contient #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_TREE_HYRULE_FIELD] =
HintText(CustomMessage("They say that a #tree in Hyrule Field# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_MARKET] =
HintText(CustomMessage("They say that a #tree in Hyrule Market# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_HYRULE_CASTLE] =
HintText(CustomMessage("They say that a #tree in Hyrule Castle# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_ZORAS_RIVER] =
HintText(CustomMessage("They say that a #tree in Zora's River# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_ZORAS_FOUNTAIN] =
HintText(CustomMessage("They say that a #tree in Zora's Fountain# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_LON_LON_RANCH] =
HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", { QM_RED, QM_GREEN }));
// clang-format on
}
} // namespace Rando

View file

@ -604,17 +604,23 @@ void GenerateItemPool() {
ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL);
PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive);
// Shuffle Trees
bool treesActive = (bool)ctx->GetOption(RSK_SHUFFLE_TREES);
PlaceItemsForType(RCTYPE_TREE, treesActive, false);
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) {
PlaceItemsForType(RCTYPE_NLTREE, treesActive, false);
}
// Shuffle Crates
bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) ||
ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL);
bool overworldNLCratesActive = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) &&
(ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) ||
ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL));
bool dungeonCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_DUNGEONS) ||
ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL);
PlaceItemsForType(RCTYPE_CRATE, overworldCratesActive, dungeonCratesActive);
PlaceItemsForType(RCTYPE_NLCRATE, overworldNLCratesActive, dungeonCratesActive);
PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive);
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) {
PlaceItemsForType(RCTYPE_NLCRATE, overworldCratesActive, dungeonCratesActive);
}
auto fsMode = ctx->GetOption(RSK_FISHSANITY);
if (fsMode.IsNot(RO_FISHSANITY_OFF)) {

View file

@ -0,0 +1,249 @@
#include <soh/OTRGlobals.h>
#include "soh_assets.h"
#include "static_data.h"
extern "C" {
#include "variables.h"
#include "src/overlays/actors/ovl_En_Wood02/z_en_wood02.h"
#include "objects/object_wood02/object_wood02.h"
#include "soh/Enhancements/enhancementTypes.h"
extern PlayState* gPlayState;
void EnWood02_Draw(Actor*, PlayState*);
}
static Gfx* D_80B3BF54[] = {
(Gfx*)object_wood02_DL_0078D0, (Gfx*)object_wood02_DL_007CA0, (Gfx*)object_wood02_DL_0080D0,
(Gfx*)object_wood02_DL_000090, (Gfx*)object_wood02_DL_000340, (Gfx*)object_wood02_DL_000340,
(Gfx*)object_wood02_DL_000700,
};
static Gfx* D_80B3BF70[] = {
(Gfx*)object_wood02_DL_007968,
(Gfx*)object_wood02_DL_007D38,
(Gfx*)object_wood02_DL_0081A8,
NULL,
NULL,
NULL,
(Gfx*)object_wood02_DL_007AD0,
(Gfx*)object_wood02_DL_007E20,
(Gfx*)object_wood02_DL_008350,
(Gfx*)object_wood02_DL_000160,
(Gfx*)object_wood02_DL_000440,
(Gfx*)object_wood02_DL_000700,
};
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
uint8_t EnWood02_RandomizerHoldsItem(EnWood02* treeActor, PlayState* play) {
// Don't pull randomized item if tree isn't randomized or is already checked
return IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get() &&
!Flags_GetRandomizerInf(treeActor->treeId.randomizerInf) &&
treeActor->treeId.randomizerCheck != RC_UNKNOWN_CHECK;
}
extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) {
GetItemCategory getItemCategory;
auto treeActor = (EnWood02*)thisx;
int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED);
int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0);
int isVanilla =
csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY));
if (isVanilla || treeActor->treeId.randomizerCheck == RC_UNKNOWN_CHECK) {
return;
}
GetItemEntry smallCrateItem =
Rando::Context::GetInstance()->GetFinalGIEntry(treeActor->treeId.randomizerCheck, true, GI_NONE);
getItemCategory = smallCrateItem.getItemCategory;
// If they have bombchus, don't consider the bombchu item major
if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU &&
((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) ||
(smallCrateItem.modIndex == MOD_NONE &&
(smallCrateItem.getItemId == GI_BOMBCHUS_5 || smallCrateItem.getItemId == GI_BOMBCHUS_10 ||
smallCrateItem.getItemId == GI_BOMBCHUS_20)))) {
getItemCategory = ITEM_CATEGORY_JUNK;
// If it's a bottle and they already have one, consider the item lesser
} else if ((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION &&
smallCrateItem.getItemId <= RG_BOTTLE_WITH_POE) ||
(smallCrateItem.modIndex == MOD_NONE &&
(smallCrateItem.getItemId == GI_BOTTLE || smallCrateItem.getItemId == GI_MILK_BOTTLE))) {
if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) {
getItemCategory = ITEM_CATEGORY_LESSER;
}
}
GraphicsContext* gfxCtx = play->state.gfxCtx;
OPEN_DISPS(gfxCtx);
Matrix_Push();
// Change texture
switch (getItemCategory) {
case ITEM_CATEGORY_MAJOR:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallMajorCrateDL);
break;
case ITEM_CATEGORY_SKULLTULA_TOKEN:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallTokenCrateDL);
break;
case ITEM_CATEGORY_SMALL_KEY:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallSmallKeyCrateDL);
break;
case ITEM_CATEGORY_BOSS_KEY:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallBossKeyCrateDL);
break;
case ITEM_CATEGORY_LESSER:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
switch (smallCrateItem.itemId) {
case ITEM_HEART_PIECE:
case ITEM_HEART_PIECE_2:
case ITEM_HEART_CONTAINER:
Gfx_DrawDListOpa(play, (Gfx*)gSmallHeartCrateDL);
break;
default:
Gfx_DrawDListOpa(play, (Gfx*)gSmallMinorCrateDL);
break;
}
case ITEM_CATEGORY_JUNK:
default:
Matrix_Scale(0.04, 0.02, 0.04, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gLargeJunkCrateDL);
break;
}
Matrix_Pop();
CLOSE_DISPS(gfxCtx);
}
void EnWood02_RandomizerSpawnCollectible(EnWood02* treeActor, PlayState* play) {
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &treeActor->actor.world.pos, ITEM00_SOH_DUMMY);
item00->randoInf = treeActor->treeId.randomizerInf;
item00->itemEntry =
Rando::Context::GetInstance()->GetFinalGIEntry(treeActor->treeId.randomizerCheck, true, GI_NONE);
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
item00->actor.velocity.y = 0.0f;
item00->actor.world.pos.y += 120.0f;
item00->actor.speedXZ = 2.0f;
item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
// clear randomizerCheck to prevent multiple bonks,
// reloading area without collecting drop won't persist this
treeActor->treeId.randomizerCheck = RC_UNKNOWN_CHECK;
}
void EnWood02_RandomizerInit(void* actorRef) {
EnWood02* treeActor = static_cast<EnWood02*>(actorRef);
if (treeActor->actor.params <= WOOD_TREE_KAKARIKO_ADULT) {
treeActor->treeId = OTRGlobals::Instance->gRandomizer->IdentifyTree(
gPlayState->sceneNum, (s16)treeActor->actor.world.pos.x, (s16)treeActor->actor.world.pos.z);
}
}
void RegisterShuffleTrees() {
bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get();
COND_ID_HOOK(OnActorInit, ACTOR_EN_WOOD02, shouldRegister, EnWood02_RandomizerInit);
COND_VB_SHOULD(VB_TREE_SETUP_DRAW, shouldRegister, {
EnWood02* treeActor = va_arg(args, EnWood02*);
if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) {
EnWood02_RandomizerDraw(&treeActor->actor, gPlayState);
}
});
COND_VB_SHOULD(VB_TREE_DROP_ITEM, shouldRegister, {
EnWood02* treeActor = va_arg(args, EnWood02*);
if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) {
EnWood02_RandomizerSpawnCollectible(treeActor, gPlayState);
// QoL, drop golden skulltula alongside item
if ((treeActor->unk_14C < 0 || treeActor->unk_14C >= 0x64) && treeActor->actor.home.rot.z != 0) {
Vec3f dropsSpawnPt = treeActor->actor.world.pos;
dropsSpawnPt.y += 200.0f;
treeActor->actor.home.rot.z &= 0x1FFF;
treeActor->actor.home.rot.z |= 0xE000;
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y,
dropsSpawnPt.z, 0, treeActor->actor.world.rot.y, 0, treeActor->actor.home.rot.z, true);
treeActor->actor.home.rot.z = 0;
}
*should = false;
}
});
}
static RegisterShipInitFunc initFunc(RegisterShuffleTrees, { "IS_RANDO" });
void Rando::StaticData::RegisterTreeLocations() {
// clang-format off
// Trees
// Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check
locationTable[RC_MARKET_TREE] = Location::Tree(RC_MARKET_TREE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-100, 240), "Tree in Hyrule Market", RHT_TREE_MARKET, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREE));
locationTable[RC_HC_NEAR_GUARDS_TREE_1] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1209, 2242), "Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_1));
locationTable[RC_HC_NEAR_GUARDS_TREE_2] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(943, 2051), "Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_2));
locationTable[RC_HC_NEAR_GUARDS_TREE_3] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(827, 1428), "Tree Near Guards 3", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_3));
locationTable[RC_HC_NEAR_GUARDS_TREE_4] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(421, 1397), "Tree Near Guards 4", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_4));
locationTable[RC_HC_NEAR_GUARDS_TREE_5] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-73, 1459), "Tree Near Guards 5", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_5));
locationTable[RC_HC_NEAR_GUARDS_TREE_6] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1494, 2108), "Tree Near Guards 6", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_6));
locationTable[RC_HC_SKULLTULA_TREE] = Location::Tree(RC_HC_SKULLTULA_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-145, 2961), "HC GS Tree", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_SKULLTULA_TREE));
locationTable[RC_HC_GROTTO_TREE] = Location::Tree(RC_HC_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(924, 872), "Tree Near Storms Grotto", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GROTTO_TREE));
locationTable[RC_HC_NL_TREE_1] = Location::NLTree(RC_HC_NL_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-331, 1438), "NL Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_1));
locationTable[RC_HC_NL_TREE_2] = Location::NLTree(RC_HC_NL_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1022, 1444), "NL Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_2));
locationTable[RC_HF_NEAR_KAK_TREE] = Location::Tree(RC_HF_NEAR_KAK_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3276, 971), "Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_TREE));
locationTable[RC_HF_NEAR_KAK_SMALL_TREE] = Location::Tree(RC_HF_NEAR_KAK_SMALL_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2076, -91), "Small Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_SMALL_TREE));
locationTable[RC_HF_NEAR_MARKET_TREE_1] = Location::Tree(RC_HF_NEAR_MARKET_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1041, 1022), "Tree Near HC Entrance Grotto 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_1));
locationTable[RC_HF_NEAR_MARKET_TREE_2] = Location::Tree(RC_HF_NEAR_MARKET_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1244, 819), "Tree Near HC Entrance Grotto 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_2));
locationTable[RC_HF_NEAR_MARKET_TREE_3] = Location::Tree(RC_HF_NEAR_MARKET_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1448, 620), "Tree Near HC Entrance Grotto 3", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_3));
locationTable[RC_HF_NEAR_LLR_TREE] = Location::Tree(RC_HF_NEAR_LLR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1907, 5409), "Tree Outside Lon Lon Ranch", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LLR_TREE));
locationTable[RC_HF_NEAR_LH_TREE] = Location::Tree(RC_HF_NEAR_LH_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4377, 13662), "Tree Outside Lake Hylia", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LH_TREE));
locationTable[RC_HF_CHILD_NEAR_GV_TREE] = Location::Tree(RC_HF_CHILD_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6270, 8579), "Child Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NEAR_GV_TREE));
locationTable[RC_HF_ADULT_NEAR_GV_TREE] = Location::Tree(RC_HF_ADULT_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6241, 7097), "Adult Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ADULT_NEAR_GV_TREE));
locationTable[RC_HF_NEAR_ZR_TREE] = Location::Tree(RC_HF_NEAR_ZR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3117, 4239), "Tree Outside Zora's River", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_ZR_TREE));
locationTable[RC_HF_NORTHWEST_TREE_1] = Location::Tree(RC_HF_NORTHWEST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4777, 136), "Tree in Northwest 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_1));
locationTable[RC_HF_NORTHWEST_TREE_2] = Location::Tree(RC_HF_NORTHWEST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4188, 263), "Tree in Northwest 2", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_2));
locationTable[RC_HF_NORTHWEST_TREE_3] = Location::Tree(RC_HF_NORTHWEST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5000, -147), "Tree in Northwest 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_3));
locationTable[RC_HF_NORTHWEST_TREE_4] = Location::Tree(RC_HF_NORTHWEST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4463, -182), "Tree in Northwest 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_4));
locationTable[RC_HF_NORTHWEST_TREE_5] = Location::Tree(RC_HF_NORTHWEST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5262, 398), "Tree in Northwest 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_5));
locationTable[RC_HF_NORTHWEST_TREE_6] = Location::Tree(RC_HF_NORTHWEST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4391, 891), "Tree in Northwest 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_6));
locationTable[RC_HF_EAST_TREE_1] = Location::Tree(RC_HF_EAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3817, 7119), "Tree in East 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_1));
locationTable[RC_HF_EAST_TREE_2] = Location::Tree(RC_HF_EAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(4365, 7182), "Tree in East 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_2));
locationTable[RC_HF_EAST_TREE_3] = Location::Tree(RC_HF_EAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3837, 7479), "Tree in East 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_3));
locationTable[RC_HF_EAST_TREE_4] = Location::Tree(RC_HF_EAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3377, 7201), "Tree in East 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_4));
locationTable[RC_HF_EAST_TREE_5] = Location::Tree(RC_HF_EAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3408, 6676), "Tree in East 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_5));
locationTable[RC_HF_EAST_TREE_6] = Location::Tree(RC_HF_EAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3935, 6279), "Tree in East 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_6));
locationTable[RC_HF_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(915, 12557), "Tree in Southeast 1", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_1));
locationTable[RC_HF_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(350, 11605), "Tree in Southeast 2", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_2));
locationTable[RC_HF_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(470, 12494), "Tree in Southeast 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_3));
locationTable[RC_HF_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(614, 12357), "Tree in Southeast 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_4));
locationTable[RC_HF_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1114, 12156), "Tree in Southeast 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_5));
locationTable[RC_HF_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(549, 11204), "Tree in Southeast 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_6));
locationTable[RC_HF_SOUTHEAST_TREE_7] = Location::Tree(RC_HF_SOUTHEAST_TREE_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(49, 11405), "Tree in Southeast 7", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_7));
locationTable[RC_HF_SOUTHEAST_TREE_8] = Location::Tree(RC_HF_SOUTHEAST_TREE_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-29, 12005), "Tree in Southeast 8", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_8));
locationTable[RC_HF_SOUTHEAST_TREE_9] = Location::Tree(RC_HF_SOUTHEAST_TREE_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1514,13157), "Tree in Southeast 9", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_9));
locationTable[RC_HF_SOUTHEAST_TREE_10] = Location::Tree(RC_HF_SOUTHEAST_TREE_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-509,12954), "Tree in Southeast 10", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_10));
locationTable[RC_HF_SOUTHEAST_TREE_11] = Location::Tree(RC_HF_SOUTHEAST_TREE_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-430,12354), "Tree in Southeast 11", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_11));
locationTable[RC_HF_SOUTHEAST_TREE_12] = Location::Tree(RC_HF_SOUTHEAST_TREE_12, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(69,12153), "Tree in Southeast 12", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_12));
locationTable[RC_HF_SOUTHEAST_TREE_13] = Location::Tree(RC_HF_SOUTHEAST_TREE_13, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-129,12554), "Tree in Southeast 13", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_13));
locationTable[RC_HF_SOUTHEAST_TREE_14] = Location::Tree(RC_HF_SOUTHEAST_TREE_14, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(950,11545), "Tree in Southeast 14", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_14));
locationTable[RC_HF_SOUTHEAST_TREE_15] = Location::Tree(RC_HF_SOUTHEAST_TREE_15, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(949,12205), "Tree in Southeast 15", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_15));
locationTable[RC_HF_SOUTHEAST_TREE_16] = Location::Tree(RC_HF_SOUTHEAST_TREE_16, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(469,13154), "Tree in Southeast 16", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_16));
locationTable[RC_HF_SOUTHEAST_TREE_17] = Location::Tree(RC_HF_SOUTHEAST_TREE_17, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(535,12957), "Tree in Southeast 17", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_17));
locationTable[RC_HF_SOUTHEAST_TREE_18] = Location::Tree(RC_HF_SOUTHEAST_TREE_18, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1515,12497), "Tree in Southeast 18", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_18));
locationTable[RC_HF_SOUTHEAST_TREE_19] = Location::Tree(RC_HF_SOUTHEAST_TREE_19, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-786,11293), "Tree in Southeast 19", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_19));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1535, 11943), "Child Tree in Southeast Corner 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_1));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2135,11883), "Child Tree in Southeast Corner 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_2));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2134,12543), "Child Tree in Southeast Corner 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_3));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1734,11542), "Child Tree in Southeast Corner 4", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_4));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1234,11743), "Child Tree in Southeast Corner 5", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_5));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1155,12343), "Child Tree in Southeast Corner 6", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_6));
locationTable[RC_HF_TEKTITE_GROTTO_TREE] = Location::Tree(RC_HF_TEKTITE_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4976, 2812), "Tektite Grotto Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_TEKTITE_GROTTO_TREE));
locationTable[RC_ZF_TREE] = Location::Tree(RC_ZF_TREE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(186, 2222), "Tree in Zora's Fountain", RHT_TREE_ZORAS_FOUNTAIN, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_TREE));
locationTable[RC_ZR_TREE] = Location::Tree(RC_ZR_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1690, 554), "Tree in Zoras River", RHT_TREE_ZORAS_RIVER, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_TREE));
locationTable[RC_KAK_TREE] = Location::Tree(RC_KAK_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-860, 522), "Kakariko GS Tree", RHT_TREE_KAKARIKO, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_TREE));
locationTable[RC_LLR_TREE] = Location::Tree(RC_LLR_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(1309, -2241), "Lon Lon Ranch GS Tree", RHT_TREE_LON_LON_RANCH, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TREE));
// clang-format on
}
static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterTreeLocations);

View file

@ -189,9 +189,12 @@ void Context::GenerateLocationPool() {
(location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OFF)) ||
(location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) ||
(location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) ||
!mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC))) ||
mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) ||
(location.GetRCType() == RCTYPE_SMALL_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) ||
(location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) ||
(location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) ||
(location.GetRCType() == RCTYPE_NLTREE &&
(!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) ||
(location.GetRCType() == RCTYPE_FREESTANDING &&
mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) ||
(location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) {

View file

@ -567,6 +567,24 @@ Rando::Location Rando::Location::SmallCrate(RandomizerCheck rc, RandomizerCheckQ
false, collectionCheck };
}
Rando::Location Rando::Location::Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_TREE, area_, ACTOR_EN_WOOD02,
scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem,
false, collectionCheck };
}
Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_NLTREE, area_, ACTOR_EN_WOOD02,
scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem,
false, collectionCheck };
}
Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_) {
return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS,

View file

@ -246,6 +246,14 @@ class Location {
RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck);
static Location Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey,
RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck);
static Location NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey,
RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck);
static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_);

View file

@ -24,7 +24,7 @@ void RegionTable_Init_CastleGrounds() {
}, {
//Locations
LOCATION(RC_HC_MALON_EGG, true),
LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)),
LOCATION(RC_HC_GS_TREE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()),
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
@ -33,6 +33,16 @@ void RegionTable_Init_CastleGrounds() {
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true),
LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_HC_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_HC_GROTTO_TREE, logic->CanBonkTrees()),
LOCATION(RC_HC_NL_TREE_1, false),
LOCATION(RC_HC_NL_TREE_2, false),
LOCATION(RC_HC_SKULLTULA_TREE, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_1, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_2, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_3, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_4, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_5, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_CASTLE_GROUNDS, []{return true;}),

View file

@ -62,6 +62,54 @@ void RegionTable_Init_HyruleField() {
LOCATION(RC_HF_NEAR_KF_GRASS_10, logic->CanCutShrubs()),
LOCATION(RC_HF_NEAR_KF_GRASS_11, logic->CanCutShrubs()),
LOCATION(RC_HF_NEAR_KF_GRASS_12, logic->CanCutShrubs()),
LOCATION(RC_HF_NEAR_LLR_TREE, logic->CanBonkTrees()),
LOCATION(RC_HF_NEAR_LH_TREE, logic->CanBonkTrees()),
LOCATION(RC_HF_CHILD_NEAR_GV_TREE, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_HF_ADULT_NEAR_GV_TREE, logic->IsAdult && logic->CanBonkTrees()),
LOCATION(RC_HF_NEAR_ZR_TREE, logic->CanBonkTrees()),
LOCATION(RC_HF_NEAR_KAK_TREE, logic->CanBonkTrees()),
LOCATION(RC_HF_NEAR_KAK_SMALL_TREE, logic->CanBonkTrees()),
LOCATION(RC_HF_NEAR_MARKET_TREE_1, logic->CanBonkTrees()),
LOCATION(RC_HF_NEAR_MARKET_TREE_2, logic->CanBonkTrees()),
LOCATION(RC_HF_NEAR_MARKET_TREE_3, logic->CanBonkTrees()),
LOCATION(RC_HF_NORTHWEST_TREE_1, logic->CanBonkTrees()),
LOCATION(RC_HF_NORTHWEST_TREE_2, logic->CanBonkTrees()),
LOCATION(RC_HF_NORTHWEST_TREE_3, logic->CanBonkTrees()),
LOCATION(RC_HF_NORTHWEST_TREE_4, logic->CanBonkTrees()),
LOCATION(RC_HF_NORTHWEST_TREE_5, logic->CanBonkTrees()),
LOCATION(RC_HF_NORTHWEST_TREE_6, logic->CanBonkTrees()),
LOCATION(RC_HF_EAST_TREE_1, logic->CanBonkTrees()),
LOCATION(RC_HF_EAST_TREE_2, logic->CanBonkTrees()),
LOCATION(RC_HF_EAST_TREE_3, logic->CanBonkTrees()),
LOCATION(RC_HF_EAST_TREE_4, logic->CanBonkTrees()),
LOCATION(RC_HF_EAST_TREE_5, logic->CanBonkTrees()),
LOCATION(RC_HF_EAST_TREE_6, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_1, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_2, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_3, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_4, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_5, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_6, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_7, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_8, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_9, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_10, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_11, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_12, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_13, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_14, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_15, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_16, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_17, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_18, logic->CanBonkTrees()),
LOCATION(RC_HF_SOUTHEAST_TREE_19, logic->CanBonkTrees()),
LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_1, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_2, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_3, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_4, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_LW_BRIDGE, []{return true;}),

View file

@ -22,7 +22,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->CanGetNightTimeGS()),
LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()),
LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()),
LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS()),
LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS() && logic->CanBonkTrees()),
LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()),
LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_1, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_2, logic->IsChild && logic->CanBreakPots()),
@ -59,6 +59,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_NEAR_FENCE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()),
LOCATION(RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()),
LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()),
LOCATION(RC_KAK_TREE, logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_HYRULE_FIELD, []{return true;}),

View file

@ -12,7 +12,7 @@ void RegionTable_Init_LonLonRanch() {
}, {
//Locations
LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay),
LOCATION(RC_LLR_GS_TREE, logic->IsChild),
LOCATION(RC_LLR_GS_TREE, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS()),
LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
@ -24,6 +24,7 @@ void RegionTable_Init_LonLonRanch() {
LOCATION(RC_LLR_RAIN_SHED_POT_2, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_LLR_RAIN_SHED_POT_3, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_LLR_NEAR_TREE_CRATE, logic->IsChild && logic->CanBreakCrates()),
LOCATION(RC_LLR_TREE, logic->IsChild && logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_HYRULE_FIELD, []{return true;}),

View file

@ -27,6 +27,7 @@ void RegionTable_Init_Market() {
LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/),
LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/),
LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/),
LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_MARKET_ENTRANCE, []{return true;}),

View file

@ -11,7 +11,7 @@ void RegionTable_Init_ZorasFountain() {
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}),
}, {
//Locations
LOCATION(RC_ZF_GS_TREE, logic->IsChild),
LOCATION(RC_ZF_GS_TREE, logic->IsChild && logic->CanBonkTrees()),
LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
@ -23,6 +23,7 @@ void RegionTable_Init_ZorasFountain() {
LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_ZF_TREE, logic->IsChild && logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_ZD_BEHIND_KING_ZORA, []{return true;}),

View file

@ -7,7 +7,7 @@ void RegionTable_Init_ZoraRiver() {
// clang-format off
areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, {
//Locations
LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)),
LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()),
LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()),
@ -20,6 +20,7 @@ void RegionTable_Init_ZoraRiver() {
LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()),
LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()),
LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()),
LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_ZORAS_RIVER, []{return logic->IsAdult || logic->BlastOrSmash();}),

View file

@ -1152,6 +1152,10 @@ bool Logic::CanBreakSmallCrates() {
return true;
}
bool Logic::CanBonkTrees() {
return true;
}
bool Logic::HasExplosives() {
return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5);
}

View file

@ -249,6 +249,7 @@ class Logic {
bool CanBreakPots();
bool CanBreakCrates();
bool CanBreakSmallCrates();
bool CanBonkTrees();
bool HasFireSource();
bool HasFireSourceWithTorch();
bool TradeQuestStep(RandomizerGet rg);

View file

@ -290,6 +290,10 @@ void Settings::CreateOptionDescriptions() {
"Overworld - Only shuffle crates that are outside of dungeons.\n"
"\n"
"All Crates - Shuffle all crates.";
mOptionDescriptions[RSK_SHUFFLE_TREES] =
"Trees will contain randomized items which are dropped the first time the player rolls into one.\n"
"Trees will have a special appearance when carrying randomized items.\n"
"\nSome trees are dependant on Link's age, such as some trees in Hyrule Field.";
mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n"
"\n"
"The fishing pole is required to play the fishing pond minigame.";

View file

@ -3304,6 +3304,69 @@ std::map<RandomizerCheck, RandomizerInf> rcToRandomizerInf = {
RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE,
RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE,
},
{ RC_MARKET_TREE, RAND_INF_MARKET_TREE },
{ RC_HC_NEAR_GUARDS_TREE_1, RAND_INF_HC_NEAR_GUARDS_TREE_1 },
{ RC_HC_NEAR_GUARDS_TREE_2, RAND_INF_HC_NEAR_GUARDS_TREE_2 },
{ RC_HC_NEAR_GUARDS_TREE_3, RAND_INF_HC_NEAR_GUARDS_TREE_3 },
{ RC_HC_NEAR_GUARDS_TREE_4, RAND_INF_HC_NEAR_GUARDS_TREE_4 },
{ RC_HC_NEAR_GUARDS_TREE_5, RAND_INF_HC_NEAR_GUARDS_TREE_5 },
{ RC_HC_NEAR_GUARDS_TREE_6, RAND_INF_HC_NEAR_GUARDS_TREE_6 },
{ RC_HC_SKULLTULA_TREE, RAND_INF_HC_SKULLTULA_TREE },
{ RC_HC_GROTTO_TREE, RAND_INF_HC_GROTTO_TREE },
{ RC_HC_NL_TREE_1, RAND_INF_HC_NL_TREE_1 },
{ RC_HC_NL_TREE_2, RAND_INF_HC_NL_TREE_2 },
{ RC_HF_NEAR_KAK_TREE, RAND_INF_HF_NEAR_KAK_TREE },
{ RC_HF_NEAR_KAK_SMALL_TREE, RAND_INF_HF_NEAR_KAK_SMALL_TREE },
{ RC_HF_NEAR_MARKET_TREE_1, RAND_INF_HF_NEAR_MARKET_TREE_1 },
{ RC_HF_NEAR_MARKET_TREE_2, RAND_INF_HF_NEAR_MARKET_TREE_2 },
{ RC_HF_NEAR_MARKET_TREE_3, RAND_INF_HF_NEAR_MARKET_TREE_3 },
{ RC_HF_NEAR_LLR_TREE, RAND_INF_HF_NEAR_LLR_TREE },
{ RC_HF_NEAR_LH_TREE, RAND_INF_HF_NEAR_LH_TREE },
{ RC_HF_CHILD_NEAR_GV_TREE, RAND_INF_HF_CHILD_NEAR_GV_TREE },
{ RC_HF_ADULT_NEAR_GV_TREE, RAND_INF_HF_ADULT_NEAR_GV_TREE },
{ RC_HF_NEAR_ZR_TREE, RAND_INF_HF_NEAR_ZR_TREE },
{ RC_HF_NORTHWEST_TREE_1, RAND_INF_HF_NORTHWEST_TREE_1 },
{ RC_HF_NORTHWEST_TREE_2, RAND_INF_HF_NORTHWEST_TREE_2 },
{ RC_HF_NORTHWEST_TREE_3, RAND_INF_HF_NORTHWEST_TREE_3 },
{ RC_HF_NORTHWEST_TREE_4, RAND_INF_HF_NORTHWEST_TREE_4 },
{ RC_HF_NORTHWEST_TREE_5, RAND_INF_HF_NORTHWEST_TREE_5 },
{ RC_HF_NORTHWEST_TREE_6, RAND_INF_HF_NORTHWEST_TREE_6 },
{ RC_HF_EAST_TREE_1, RAND_INF_HF_EAST_TREE_1 },
{ RC_HF_EAST_TREE_2, RAND_INF_HF_EAST_TREE_2 },
{ RC_HF_EAST_TREE_3, RAND_INF_HF_EAST_TREE_3 },
{ RC_HF_EAST_TREE_4, RAND_INF_HF_EAST_TREE_4 },
{ RC_HF_EAST_TREE_5, RAND_INF_HF_EAST_TREE_5 },
{ RC_HF_EAST_TREE_6, RAND_INF_HF_EAST_TREE_6 },
{ RC_HF_SOUTHEAST_TREE_1, RAND_INF_HF_SOUTHEAST_TREE_1 },
{ RC_HF_SOUTHEAST_TREE_2, RAND_INF_HF_SOUTHEAST_TREE_2 },
{ RC_HF_SOUTHEAST_TREE_3, RAND_INF_HF_SOUTHEAST_TREE_3 },
{ RC_HF_SOUTHEAST_TREE_4, RAND_INF_HF_SOUTHEAST_TREE_4 },
{ RC_HF_SOUTHEAST_TREE_5, RAND_INF_HF_SOUTHEAST_TREE_5 },
{ RC_HF_SOUTHEAST_TREE_6, RAND_INF_HF_SOUTHEAST_TREE_6 },
{ RC_HF_SOUTHEAST_TREE_7, RAND_INF_HF_SOUTHEAST_TREE_7 },
{ RC_HF_SOUTHEAST_TREE_8, RAND_INF_HF_SOUTHEAST_TREE_8 },
{ RC_HF_SOUTHEAST_TREE_9, RAND_INF_HF_SOUTHEAST_TREE_9 },
{ RC_HF_SOUTHEAST_TREE_10, RAND_INF_HF_SOUTHEAST_TREE_10 },
{ RC_HF_SOUTHEAST_TREE_11, RAND_INF_HF_SOUTHEAST_TREE_11 },
{ RC_HF_SOUTHEAST_TREE_12, RAND_INF_HF_SOUTHEAST_TREE_12 },
{ RC_HF_SOUTHEAST_TREE_13, RAND_INF_HF_SOUTHEAST_TREE_13 },
{ RC_HF_SOUTHEAST_TREE_14, RAND_INF_HF_SOUTHEAST_TREE_14 },
{ RC_HF_SOUTHEAST_TREE_15, RAND_INF_HF_SOUTHEAST_TREE_15 },
{ RC_HF_SOUTHEAST_TREE_16, RAND_INF_HF_SOUTHEAST_TREE_16 },
{ RC_HF_SOUTHEAST_TREE_17, RAND_INF_HF_SOUTHEAST_TREE_17 },
{ RC_HF_SOUTHEAST_TREE_18, RAND_INF_HF_SOUTHEAST_TREE_18 },
{ RC_HF_SOUTHEAST_TREE_19, RAND_INF_HF_SOUTHEAST_TREE_19 },
{ RC_HF_CHILD_SOUTHEAST_TREE_1, RAND_INF_HF_CHILD_SOUTHEAST_TREE_1 },
{ RC_HF_CHILD_SOUTHEAST_TREE_2, RAND_INF_HF_CHILD_SOUTHEAST_TREE_2 },
{ RC_HF_CHILD_SOUTHEAST_TREE_3, RAND_INF_HF_CHILD_SOUTHEAST_TREE_3 },
{ RC_HF_CHILD_SOUTHEAST_TREE_4, RAND_INF_HF_CHILD_SOUTHEAST_TREE_4 },
{ RC_HF_CHILD_SOUTHEAST_TREE_5, RAND_INF_HF_CHILD_SOUTHEAST_TREE_5 },
{ RC_HF_CHILD_SOUTHEAST_TREE_6, RAND_INF_HF_CHILD_SOUTHEAST_TREE_6 },
{ RC_HF_TEKTITE_GROTTO_TREE, RAND_INF_HF_TEKTITE_GROTTO_TREE },
{ RC_ZF_TREE, RAND_INF_ZF_TREE },
{ RC_ZR_TREE, RAND_INF_ZR_TREE },
{ RC_KAK_TREE, RAND_INF_KAK_TREE },
{ RC_LLR_TREE, RAND_INF_LLR_TREE },
};
BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) {
@ -3725,6 +3788,27 @@ SmallCrateIdentity Randomizer::IdentifySmallCrate(s32 sceneNum, s32 posX, s32 po
return smallCrateIdentity;
}
TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) {
struct TreeIdentity treeIdentity;
if (sceneNum == SCENE_MARKET_NIGHT) {
sceneNum = SCENE_MARKET_DAY;
}
s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ);
Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams);
if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK &&
(location->GetRCType() != RCTYPE_NLTREE || GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) {
treeIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()];
treeIdentity.randomizerCheck = location->GetRandomizerCheck();
return treeIdentity;
}
treeIdentity.randomizerInf = RAND_INF_MAX;
treeIdentity.randomizerCheck = RC_UNKNOWN_CHECK;
return treeIdentity;
}
u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) {
return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get();
}

View file

@ -57,6 +57,7 @@ class Randomizer {
GrassIdentity IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 respawnData, s32 linkAge);
CrateIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ);
SmallCrateIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ);
TreeIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ);
GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId,
bool checkObtainability = true);
GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId,

View file

@ -299,6 +299,8 @@ typedef enum {
RCTYPE_CRATE, // Crates
RCTYPE_NLCRATE, // NL Crates
RCTYPE_SMALL_CRATE, // Small crates
RCTYPE_TREE, // Trees
RCTYPE_NLTREE, // NL Trees
RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps)
RCTYPE_OCARINA, // Ocarina locations
RCTYPE_BEEHIVE, // Beehives
@ -2647,6 +2649,72 @@ typedef enum {
RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE,
// End Crates
// Start Trees
RC_MARKET_TREE,
RC_HC_NEAR_GUARDS_TREE_1,
RC_HC_NEAR_GUARDS_TREE_2,
RC_HC_NEAR_GUARDS_TREE_3,
RC_HC_NEAR_GUARDS_TREE_4,
RC_HC_NEAR_GUARDS_TREE_5,
RC_HC_NEAR_GUARDS_TREE_6,
RC_HC_SKULLTULA_TREE,
RC_HC_GROTTO_TREE,
RC_HC_NL_TREE_1,
RC_HC_NL_TREE_2,
RC_HF_NEAR_LLR_TREE,
RC_HF_NEAR_LH_TREE,
RC_HF_CHILD_NEAR_GV_TREE,
RC_HF_ADULT_NEAR_GV_TREE,
RC_HF_NEAR_ZR_TREE,
RC_HF_NEAR_KAK_TREE,
RC_HF_NEAR_KAK_SMALL_TREE,
RC_HF_NEAR_MARKET_TREE_1,
RC_HF_NEAR_MARKET_TREE_2,
RC_HF_NEAR_MARKET_TREE_3,
RC_HF_NORTHWEST_TREE_1,
RC_HF_NORTHWEST_TREE_2,
RC_HF_NORTHWEST_TREE_3,
RC_HF_NORTHWEST_TREE_4,
RC_HF_NORTHWEST_TREE_5,
RC_HF_NORTHWEST_TREE_6,
RC_HF_EAST_TREE_1,
RC_HF_EAST_TREE_2,
RC_HF_EAST_TREE_3,
RC_HF_EAST_TREE_4,
RC_HF_EAST_TREE_5,
RC_HF_EAST_TREE_6,
RC_HF_SOUTHEAST_TREE_1,
RC_HF_SOUTHEAST_TREE_2,
RC_HF_SOUTHEAST_TREE_3,
RC_HF_SOUTHEAST_TREE_4,
RC_HF_SOUTHEAST_TREE_5,
RC_HF_SOUTHEAST_TREE_6,
RC_HF_SOUTHEAST_TREE_7,
RC_HF_SOUTHEAST_TREE_8,
RC_HF_SOUTHEAST_TREE_9,
RC_HF_SOUTHEAST_TREE_10,
RC_HF_SOUTHEAST_TREE_11,
RC_HF_SOUTHEAST_TREE_12,
RC_HF_SOUTHEAST_TREE_13,
RC_HF_SOUTHEAST_TREE_14,
RC_HF_SOUTHEAST_TREE_15,
RC_HF_SOUTHEAST_TREE_16,
RC_HF_SOUTHEAST_TREE_17,
RC_HF_SOUTHEAST_TREE_18,
RC_HF_SOUTHEAST_TREE_19,
RC_HF_CHILD_SOUTHEAST_TREE_1,
RC_HF_CHILD_SOUTHEAST_TREE_2,
RC_HF_CHILD_SOUTHEAST_TREE_3,
RC_HF_CHILD_SOUTHEAST_TREE_4,
RC_HF_CHILD_SOUTHEAST_TREE_5,
RC_HF_CHILD_SOUTHEAST_TREE_6,
RC_HF_TEKTITE_GROTTO_TREE,
RC_ZF_TREE,
RC_ZR_TREE,
RC_KAK_TREE,
RC_LLR_TREE,
// End Trees
RC_PIERRE,
RC_DELIVER_RUTOS_LETTER,
RC_MASTER_SWORD_PEDESTAL,
@ -5485,6 +5553,14 @@ typedef enum {
RHT_CRATE_SPIRIT_TEMPLE,
RHT_CRATE_SHADOW_TEMPLE,
RHT_CRATE_GERUDO_TRAINING_GROUND,
// Shuffle Trees
RHT_TREE_HYRULE_FIELD,
RHT_TREE_MARKET,
RHT_TREE_HYRULE_CASTLE,
RHT_TREE_ZORAS_FOUNTAIN,
RHT_TREE_ZORAS_RIVER,
RHT_TREE_LON_LON_RANCH,
RHT_TREE_KAKARIKO,
// Ganon Line
RHT_GANON_JOKE01,
RHT_GANON_JOKE02,
@ -5824,6 +5900,7 @@ typedef enum {
RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD,
RSK_SHUFFLE_POTS,
RSK_SHUFFLE_CRATES,
RSK_SHUFFLE_TREES,
RSK_SHUFFLE_FROG_SONG_RUPEES,
RSK_ITEM_POOL,
RSK_ICE_TRAPS,
@ -6441,6 +6518,11 @@ typedef struct SmallCrateIdentity {
RandomizerCheck randomizerCheck;
} SmallCrateIdentity;
typedef struct TreeIdentity {
RandomizerInf randomizerInf;
RandomizerCheck randomizerCheck;
} TreeIdentity;
typedef enum {
TRACKER_WINDOW_FLOATING,
TRACKER_WINDOW_WINDOW,

View file

@ -189,6 +189,10 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_SMALL_CRATE ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_TREE ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_NLTREE ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_FISH ||
ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) &&
(location.GetRCType() != RCTYPE_ADULT_TRADE ||

View file

@ -68,6 +68,7 @@ bool showOverworldGrass;
bool showDungeonGrass;
bool showOverworldCrates;
bool showDungeonCrates;
bool showTrees;
bool showFrogSongRupees;
bool showFairies;
bool showStartingMapsCompasses;
@ -1456,6 +1457,7 @@ void LoadSettings() {
showDungeonCrates = false;
break;
}
showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES);
} else { // Vanilla
showOverworldTokens = true;
showDungeonTokens = true;
@ -1465,6 +1467,7 @@ void LoadSettings() {
showDungeonGrass = false;
showOverworldCrates = false;
showDungeonCrates = false;
showTrees = false;
}
fortressFast = false;
@ -1541,9 +1544,9 @@ bool IsCheckShuffled(RandomizerCheck rc) {
return (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations
(loc->GetRCType() != RCTYPE_GOSSIP_STONE) && // TODO: Don't show hints until tracker supports them
(loc->GetRCType() != RCTYPE_STATIC_HINT) && // TODO: Don't show hints until tracker supports them
(loc->GetRCType() !=
RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them
(rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it
(loc->GetRCType() != RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we
// support shuffling them
(rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it
(rc != RC_LINKS_POCKET || showLinksPocket) &&
OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) &&
(loc->GetRCType() != RCTYPE_SHOP ||
@ -1577,6 +1580,10 @@ bool IsCheckShuffled(RandomizerCheck rc) {
(loc->GetRCType() != RCTYPE_SMALL_CRATE ||
(showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) ||
(showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) &&
(loc->GetRCType() != RCTYPE_TREE || showTrees) &&
(loc->GetRCType() != RCTYPE_NLTREE ||
(showTrees &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) &&
(loc->GetRCType() != RCTYPE_COW || showCows) &&
(loc->GetRCType() != RCTYPE_FISH ||
OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) &&

View file

@ -997,6 +997,69 @@ DEFINE_RAND_INF(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3)
DEFINE_RAND_INF(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4)
DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE)
DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE)
DEFINE_RAND_INF(RAND_INF_MARKET_TREE)
DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_1)
DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_2)
DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_3)
DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_4)
DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_5)
DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_6)
DEFINE_RAND_INF(RAND_INF_HC_SKULLTULA_TREE)
DEFINE_RAND_INF(RAND_INF_HC_GROTTO_TREE)
DEFINE_RAND_INF(RAND_INF_HC_NL_TREE_1)
DEFINE_RAND_INF(RAND_INF_HC_NL_TREE_2)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_LLR_TREE)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_LH_TREE)
DEFINE_RAND_INF(RAND_INF_HF_CHILD_NEAR_GV_TREE)
DEFINE_RAND_INF(RAND_INF_HF_ADULT_NEAR_GV_TREE)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_ZR_TREE)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_KAK_TREE)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_KAK_SMALL_TREE)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_1)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_2)
DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_3)
DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_1)
DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_2)
DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_3)
DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_4)
DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_5)
DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_6)
DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_1)
DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_2)
DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_3)
DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_4)
DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_5)
DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_6)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_1)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_2)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_3)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_4)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_5)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_6)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_7)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_8)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_9)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_10)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_11)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_12)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_13)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_14)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_15)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_16)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_17)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_18)
DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_19)
DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_1)
DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_2)
DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_3)
DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_4)
DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_5)
DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_6)
DEFINE_RAND_INF(RAND_INF_HF_TEKTITE_GROTTO_TREE)
DEFINE_RAND_INF(RAND_INF_ZF_TREE)
DEFINE_RAND_INF(RAND_INF_ZR_TREE)
DEFINE_RAND_INF(RAND_INF_KAK_TREE)
DEFINE_RAND_INF(RAND_INF_LLR_TREE)
DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH)

View file

@ -217,6 +217,7 @@ void Settings::CreateOptions() {
OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WidgetType::Combobox, RO_SHUFFLE_POTS_OFF);
OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF);
OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF);
OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]);
OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]);
OPT_U8(RSK_SHUFFLE_MERCHANTS, "Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES, "Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE);
@ -1282,6 +1283,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_COWS],
&mOptions[RSK_SHUFFLE_POTS],
&mOptions[RSK_SHUFFLE_CRATES],
&mOptions[RSK_SHUFFLE_TREES],
&mOptions[RSK_SHUFFLE_MERCHANTS],
&mOptions[RSK_MERCHANT_PRICES],
&mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE],
@ -1515,6 +1517,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_COWS],
&mOptions[RSK_SHUFFLE_POTS],
&mOptions[RSK_SHUFFLE_CRATES],
&mOptions[RSK_SHUFFLE_TREES],
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD],
&mOptions[RSK_SHUFFLE_OCARINA],
&mOptions[RSK_SHUFFLE_OCARINA_BUTTONS],

View file

@ -58,6 +58,7 @@ class StaticData {
static void RegisterFreestandingLocations();
static void RegisterGrassLocations();
static void RegisterCrateLocations();
static void RegisterTreeLocations();
static void InitHashMaps();
static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish;
static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap;

View file

@ -357,16 +357,18 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) {
dropsSpawnPt = this->actor.world.pos;
dropsSpawnPt.y += 200.0f;
if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) {
if (GameInteractor_Should(VB_TREE_DROP_COLLECTIBLE, true, this)) {
Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4);
if (GameInteractor_Should(VB_TREE_DROP_ITEM, true, this)) {
if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) {
if (GameInteractor_Should(VB_TREE_DROP_COLLECTIBLE, true, this)) {
Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4);
}
} else if (this->actor.home.rot.z != 0) {
this->actor.home.rot.z &= 0x1FFF;
this->actor.home.rot.z |= 0xE000;
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, dropsSpawnPt.z, 0,
this->actor.world.rot.y, 0, this->actor.home.rot.z, true);
this->actor.home.rot.z = 0;
}
} else if (this->actor.home.rot.z != 0) {
this->actor.home.rot.z &= 0x1FFF;
this->actor.home.rot.z |= 0xE000;
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, dropsSpawnPt.z, 0,
this->actor.world.rot.y, 0, this->actor.home.rot.z, true);
this->actor.home.rot.z = 0;
}
// Spawn falling leaves
@ -457,12 +459,13 @@ void EnWood02_Draw(Actor* thisx, PlayState* play) {
}
Gfx_SetupDL_25Xlu(gfxCtx);
if ((this->actor.params == WOOD_LEAF_GREEN) || (this->actor.params == WOOD_LEAF_YELLOW)) {
if (GameInteractor_Should(VB_TREE_SETUP_DRAW,
(this->actor.params == WOOD_LEAF_GREEN) || (this->actor.params == WOOD_LEAF_YELLOW),
this)) {
Gfx_SetupDL_25Opa(gfxCtx);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 127);
Gfx_DrawDListOpa(play, object_wood02_DL_000700);
} else if (D_80B3BF70[this->drawType & 0xF] != NULL) {
} else if (GameInteractor_Should(VB_TREE_SETUP_DRAW, D_80B3BF70[this->drawType & 0xF] != NULL, this)) {
Gfx_DrawDListOpa(play, D_80B3BF54[this->drawType & 0xF]);
gDPSetEnvColor(POLY_XLU_DISP++, red, green, blue, 0);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);

View file

@ -13,6 +13,7 @@ typedef struct EnWood02 {
/* 0x0153 */ u8 spawnType;
/* 0x0154 */ u8 drawType;
/* 0x0158 */ ColliderCylinder collider;
/* */ TreeIdentity treeId;
} EnWood02; // size = 0x01A4
// Types with SPAWNED in the name are those that can be managed by a spawner, however the actor allows you to spawn them