From de934973104fe175b209e91bff4d977e190b6107 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 25 May 2025 19:35:00 +0000 Subject: [PATCH 01/12] treesanity co-authored-by: turbofist --- .../objects/object_rando_tree/gRandoTreeDL | 12 ++ .../gRandoTreeDLTriforceTexture32.rgba16 | Bin 0 -> 2140 bytes .../object_rando_tree/gRandoTreeDL_tri_0 | 12 ++ .../object_rando_tree/gRandoTreeDL_tri_1 | 9 + .../object_rando_tree/gRandoTreeDL_vtx_0 | 32 +++ .../object_rando_tree/gRandoTreeDL_vtx_1 | 18 ++ .../object_rando_tree/gRandoTreeDL_vtx_cull | 10 + .../mat_gRandoTreeDL_treeTexMaterial | 16 ++ .../mat_gRandoTreeDL_triforceTexMaterial | 16 ++ .../mat_revert_gRandoTreeDL_treeTexMaterial | 6 + ...at_revert_gRandoTreeDL_triforceTexMaterial | 6 + soh/assets/soh_assets.h | 3 + .../vanilla-behavior/GIVanillaBehavior.h | 16 ++ .../hint_list/hint_list_exclude_overworld.cpp | 24 +++ .../randomizer/3drando/item_pool.cpp | 4 + .../Enhancements/randomizer/ShuffleTrees.cpp | 203 ++++++++++++++++++ soh/soh/Enhancements/randomizer/context.cpp | 1 + soh/soh/Enhancements/randomizer/location.cpp | 9 + soh/soh/Enhancements/randomizer/location.h | 4 + .../overworld/castle_grounds.cpp | 10 +- .../overworld/hyrule_field.cpp | 48 +++++ .../location_access/overworld/kakariko.cpp | 3 +- .../overworld/lon_lon_ranch.cpp | 3 +- .../location_access/overworld/market.cpp | 1 + .../overworld/zoras_fountain.cpp | 3 +- .../location_access/overworld/zoras_river.cpp | 3 +- soh/soh/Enhancements/randomizer/logic.cpp | 4 + soh/soh/Enhancements/randomizer/logic.h | 1 + .../randomizer/option_descriptions.cpp | 4 + .../Enhancements/randomizer/randomizer.cpp | 81 +++++++ soh/soh/Enhancements/randomizer/randomizer.h | 1 + .../Enhancements/randomizer/randomizerTypes.h | 79 +++++++ .../randomizer/randomizer_check_objects.cpp | 2 + .../randomizer/randomizer_check_tracker.cpp | 5 +- .../Enhancements/randomizer/randomizer_inf.h | 61 ++++++ soh/soh/Enhancements/randomizer/settings.cpp | 3 + soh/soh/Enhancements/randomizer/static_data.h | 1 + .../actors/ovl_En_Wood02/z_en_wood02.c | 27 +-- .../actors/ovl_En_Wood02/z_en_wood02.h | 1 + 39 files changed, 724 insertions(+), 18 deletions(-) create mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL create mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDLTriforceTexture32.rgba16 create mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 create mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 create mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 create mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 create mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull create mode 100644 soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial create mode 100644 soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial create mode 100644 soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial create mode 100644 soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial create mode 100644 soh/soh/Enhancements/randomizer/ShuffleTrees.cpp diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL new file mode 100644 index 000000000..8ab80efae --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDLTriforceTexture32.rgba16 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDLTriforceTexture32.rgba16 new file mode 100644 index 0000000000000000000000000000000000000000..256efd65a2a477f136c33b04119d02f306594ded GIT binary patch literal 2140 zcma)7J&Wr`6!l~fj@e@W!YjRFiPg zF$iOVN^j}%wdqploRPiTq{v?MVa+}F+`0GM+1YG1`!)ULXMyM6fBtdhh1dW6_Z>Vx z-L47r+YhrDuJ32FM8-b$iA?0uFY!iO4lw-s^dH9WFnR==5CQdppQ7Bo0^;s*!%tCg zS5irh3zmla^e&W)eQ7#fx~GVFB@x$kqZ>TaL@NG{CX_a|(Wy4dyvITmZQ6dUF1-zV zi9Mt1)NT=D%l+yme^4oL!QijJddmfGo4(TntTPERxMfQJR5#$4w#m+kdB+>e41f=2 ztZOS^fgh{qNQFIUQ#|C0d|`ptCOhYgC!uTNEOSV+6SKCdt!?A5_o0I6!Hl&%vrkGE z547wY_e$oA;vo^t9sVg%*_p9ejWQh!b04b_5#FNRmNiQvdoDj`r+lGL$}kf}BpI9R z1UxQs7xTR%p6C(#@66bgE8@L&2RvoSA6UlFrqtl}qhs9$eH2Ha$v;-#^x7eV z6|_bk?4Olj-CTK8{@6a`%JK)>uD6j)u-}Irkp6boO5BvfdqhicEJMj*7^Cm8R z;D&O;8+35!+p4WD)jxe{s9d7#srU(~b6}tF__}jf@zR&N6vexhg1@r96o>u@-9o!5 zs$S=J{w8ZIrV8qeF21eSm37u>je4NU!6aF-VN+dYnJzJl&@XqvSwL4%kyR4K{>5Kq z>(@FPup1Y$qq6xII)~c0(P_+6?5P=bW58raNu;qhy1jeWU{AB5TotQgjyOK_EiFvz zj`AuUy2w3H2Vvr%D=1UGiZ?L;@0|6_tei7KnPwjS!u<!6I$p^6dk;mn{av7e}r ztU9&+RTh|D>a2*0`Fcwp>(>4iDj29NfACP+N=5WhX*|S(b}#-m?a1*NePmsVc~)Uo zSXtws!w%XS-JmZ$l(a$wscW3OI7c^rgkC}fGgL>p#@Pqnn)^e)!QLW14Eb>`_gG~W zY!d^m%^u%E{-TpuM-@uWOHfN-hl(aubx`Hlzkz`#tTM|Xkj*pjv_Nn4rlxm7}}LSL!&mp6sD^A71e07ck+;%s7FVK|Fb(1O6(m z;#n4EgTC&~p+EF{oDh3t(+1SUb?B!^w^h`Y9`yVQ{%48v$HCAkbb~tLbfIQ9Lw+js zfZxM<1U1w|V73~CsZmyMKTO$Vp3LvR^T+&AZ6^;!ufO!xj`^eB{fHHs-aR2gJYafu d%EEJ};SYPiKQSvr43Ssp_I%=?>hOPU_!m^vAPxWk literal 0 HcmV?d00001 diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 new file mode 100644 index 000000000..16bbada99 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 new file mode 100644 index 000000000..136154b4c --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 new file mode 100644 index 000000000..e92b51e78 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 new file mode 100644 index 000000000..adf256fc1 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull new file mode 100644 index 000000000..ea47c02e0 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial new file mode 100644 index 000000000..219a71f77 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial new file mode 100644 index 000000000..a95fff2b0 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial new file mode 100644 index 000000000..ee8de0c37 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial @@ -0,0 +1,6 @@ + + + + + + diff --git a/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial new file mode 100644 index 000000000..ee8de0c37 --- /dev/null +++ b/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial @@ -0,0 +1,6 @@ + + + + + + diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index 3c3ddcf5a..e3e2f4780 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -77,6 +77,9 @@ static const ALIGN_ASSET(2) char gBossSoulSkullDL[] = dgBossSoulSkullDL; #define dgRandoPotDL "__OTR__objects/gameplay_dangeon_keep/gRandoPotDL" static const ALIGN_ASSET(2) char gRandoPotDL[] = dgRandoPotDL; +#define dgRandoTreeDL "__OTR__objects/object_rando_tree/gRandoTreeDL" +static const ALIGN_ASSET(2) char gRandoTreeDL[] = dgRandoTreeDL; + #define dgRandoBushDL "__OTR__objects/gameplay_field_keep/gFieldBushRandomDL" static const ALIGN_ASSET(2) char gRandoBushDL[] = dgRandoBushDL; diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 186307aed..ea20b398f 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2155,6 +2155,22 @@ typedef enum { // - `*EnWood02` VB_TREE_DROP_COLLECTIBLE, + // ```c + // true + // ``` + // #### `args` + // - `*ObjWood02` + VB_TREE_SETUP_DRAW, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjWood02` + VB_TREE_DROP_ITEM, + + // #### `result` // ```c // true // ``` diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index a8afd7cb2..3314d6872 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -2081,6 +2081,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 diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index c97ae35ce..ef8585e4b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -604,6 +604,10 @@ 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); + // Shuffle Crates bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp new file mode 100644 index 000000000..c5db4b352 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -0,0 +1,203 @@ +#include +#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" +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) { + EnWood02* thisy = (EnWood02*)thisx; + s16 type = thisy->actor.params; + u8 red; + u8 green; + u8 blue; + + if ((type == WOOD_TREE_OVAL_GREEN_SPAWNER) || (type == WOOD_TREE_OVAL_GREEN_SPAWNED) || + (type == WOOD_TREE_OVAL_GREEN) || (type == WOOD_LEAF_GREEN)) { + red = 50; + green = 170; + blue = 70; + } else if ((type == WOOD_TREE_OVAL_YELLOW_SPAWNER) || (type == WOOD_TREE_OVAL_YELLOW_SPAWNED) || + (type == WOOD_LEAF_YELLOW)) { + red = 180; + green = 155; + blue = 0; + } else { + red = green = blue = 255; + } + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + if ((thisy->actor.params == WOOD_LEAF_GREEN) || (thisy->actor.params == WOOD_LEAF_YELLOW)) { + Gfx_SetupDL_25Opa(play->state.gfxCtx); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 127); + Gfx_DrawDListOpa(play, (Gfx*)gRandoTreeDL); + } else if (D_80B3BF70[thisy->drawType & 0xF] != NULL) { + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 0); + Gfx_DrawDListOpa(play, (Gfx*)gRandoTreeDL); + gDPSetEnvColor(POLY_XLU_DISP++, red, green, blue, 0); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_80B3BF70[thisy->drawType & 0xF]); + } + CLOSE_DISPS(play->state.gfxCtx); + + if (!EnWood02_RandomizerHoldsItem(thisy, gPlayState)) { + thisy->actor.draw = (ActorFunc)EnWood02_Draw; + } +} + +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(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); + if (treeActor->treeId.randomizerCheck == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("TREE %d,%d", (int)treeActor->actor.world.pos.x, (int)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)) { + treeActor->actor.draw = (ActorFunc)EnWood02_RandomizerDraw; + *should = false; + } + }); + + COND_VB_SHOULD(VB_TREE_DROP_ITEM, shouldRegister, { + EnWood02* treeActor = va_arg(args, EnWood02*); + if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { + EnWood02_RandomizerSpawnCollectible(treeActor, gPlayState); + *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_DAY_TREE] = Location::Tree(RC_MARKET_DAY_TREE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-100, 240), "Tree in Hyrule Market (Day)", RHT_TREE_MARKET, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_DAY_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_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_TREE_NEAR_HC_GROTTO_1] = Location::Tree(RC_HF_TREE_NEAR_HC_GROTTO_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_TREE_NEAR_HC_GROTTO_1)); + locationTable[RC_HF_TREE_NEAR_HC_GROTTO_2] = Location::Tree(RC_HF_TREE_NEAR_HC_GROTTO_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_TREE_NEAR_HC_GROTTO_2)); + locationTable[RC_HF_TREE_NEAR_HC_GROTTO_3] = Location::Tree(RC_HF_TREE_NEAR_HC_GROTTO_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_TREE_NEAR_HC_GROTTO_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); diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 2ee39006d..a8a397827 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -192,6 +192,7 @@ void Context::GenerateLocationPool() { !mOptions[RSK_LOGIC_RULES].Is(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_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || (location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) { diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index f474397aa..c82724180 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -566,6 +566,15 @@ 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::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, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index f99499652..6de26bc41 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -246,6 +246,10 @@ 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 OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index b9525386c..d88e6acff 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -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,14 @@ 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_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;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 5bc3aeb26..98b904cc6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -61,6 +61,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_TREE_NEAR_HC_GROTTO_1, logic->CanBonkTrees()), + LOCATION(RC_HF_TREE_NEAR_HC_GROTTO_2, logic->CanBonkTrees()), + LOCATION(RC_HF_TREE_NEAR_HC_GROTTO_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;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 13490c9a4..9ca3fd266 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -20,7 +20,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()), @@ -57,6 +57,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->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index c29a5924e..e6c29e425 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -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;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 7d7655ef0..63e2570ad 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -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_DAY_TREE, logic->IsChild && logic->CanBonkTrees() && logic->AtDay), }, { //Exits Entrance(RR_MARKET_ENTRANCE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index cfd2125c1..b0b3ab8b5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -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;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 5473ee2ca..c8f24b85a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -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();}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 442f2b23b..61057944d 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -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); } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index ba9ab60d0..2a339b34b 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -247,6 +247,7 @@ class Logic { bool CanBreakPots(); bool CanBreakCrates(); bool CanBreakSmallCrates(); + bool CanBonkTrees(); bool HasFireSource(); bool HasFireSourceWithTorch(); bool TradeQuestStep(RandomizerGet rg); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 16c89a1c4..a86ac3281 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -288,6 +288,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."; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index abfa8f3b6..bcec85029 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3258,6 +3258,67 @@ std::map rcToRandomizerInf = { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, }, + { RC_MARKET_DAY_TREE, RAND_INF_MARKET_DAY_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_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_TREE_NEAR_HC_GROTTO_1, RAND_INF_HF_TREE_NEAR_HC_GROTTO_1 }, + { RC_HF_TREE_NEAR_HC_GROTTO_2, RAND_INF_HF_TREE_NEAR_HC_GROTTO_2 }, + { RC_HF_TREE_NEAR_HC_GROTTO_3, RAND_INF_HF_TREE_NEAR_HC_GROTTO_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) { @@ -3679,6 +3740,26 @@ SmallCrateIdentity Randomizer::IdentifySmallCrate(s32 sceneNum, s32 posX, s32 po return smallCrateIdentity; } +TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { + struct TreeIdentity treeIdentity; + + for (int x = -1; x <= 1; x++) { + for (int z = -1; z <= 1; z++) { + s32 actorParams = TWO_ACTOR_PARAMS(posX + x, posZ + z); + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams); + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + 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(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 78f48b01c..54c85307b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -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, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 8295eb6cd..a1611dd7c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -299,6 +299,7 @@ typedef enum { RCTYPE_CRATE, // Crates RCTYPE_NLCRATE, // NL Crates RCTYPE_SMALL_CRATE, // Small crates + RCTYPE_TREE, // Trees RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps) RCTYPE_OCARINA, // Ocarina locations RCTYPE_BEEHIVE, // Beehives @@ -2645,6 +2646,70 @@ typedef enum { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, // End Crates + // Start Trees + RC_MARKET_DAY_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_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_TREE_NEAR_HC_GROTTO_1, + RC_HF_TREE_NEAR_HC_GROTTO_2, + RC_HF_TREE_NEAR_HC_GROTTO_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, @@ -5477,6 +5542,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, @@ -5815,6 +5888,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, @@ -6426,6 +6500,11 @@ typedef struct SmallCrateIdentity { RandomizerCheck randomizerCheck; } SmallCrateIdentity; +typedef struct TreeIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} TreeIdentity; + typedef enum { TRACKER_WINDOW_FLOATING, TRACKER_WINDOW_WINDOW, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index da05ee508..29e0fae7a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -189,6 +189,8 @@ 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_FISH || ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && (location.GetRCType() != RCTYPE_ADULT_TRADE || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d460c6daf..56480079b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -68,6 +68,7 @@ bool showOverworldGrass; bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; +bool showTrees; bool showFrogSongRupees; bool showFairies; bool showStartingMapsCompasses; @@ -1448,6 +1449,7 @@ void LoadSettings() { showDungeonCrates = false; break; } + showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); } else { // Vanilla showOverworldTokens = true; showDungeonTokens = true; @@ -1457,6 +1459,7 @@ void LoadSettings() { showDungeonGrass = false; showOverworldCrates = false; showDungeonCrates = false; + showTrees = false; } fortressFast = false; @@ -1569,7 +1572,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_SMALL_CRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_COW || showCows) && + (loc->GetRCType() != RCTYPE_TREE || showTrees) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && (loc->GetRCType() != RCTYPE_FREESTANDING || diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index cf2f83d3a..1349b27df 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -997,6 +997,67 @@ 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_DAY_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_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_TREE_NEAR_HC_GROTTO_1) +DEFINE_RAND_INF(RAND_INF_HF_TREE_NEAR_HC_GROTTO_2) +DEFINE_RAND_INF(RAND_INF_HF_TREE_NEAR_HC_GROTTO_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) diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 52add036e..c99947f6b 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -216,6 +216,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); @@ -1277,6 +1278,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], @@ -1509,6 +1511,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], diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 7bdec17c1..d6a151391 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -58,6 +58,7 @@ class StaticData { static void RegisterFreestandingLocations(); static void RegisterGrassLocations(); static void RegisterCrateLocations(); + static void RegisterTreeLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index 2fe2445a6..1fe96d38c 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -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); diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h index 96746c0af..6cc2cdae1 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h @@ -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 From cba32714735d9e3fe9c0209bdc6a50c5e51597e7 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Mon, 9 Jun 2025 00:15:57 +0000 Subject: [PATCH 02/12] market tree at night --- soh/soh/Enhancements/randomizer/ShuffleTrees.cpp | 2 +- .../randomizer/location_access/overworld/market.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizer.cpp | 6 +++++- soh/soh/Enhancements/randomizer/randomizerTypes.h | 2 +- soh/soh/Enhancements/randomizer/randomizer_inf.h | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index c5db4b352..45b51c0b5 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -136,7 +136,7 @@ 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_DAY_TREE] = Location::Tree(RC_MARKET_DAY_TREE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-100, 240), "Tree in Hyrule Market (Day)", RHT_TREE_MARKET, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_DAY_TREE)); + 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)); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 63e2570ad..d77138e1d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -27,7 +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_DAY_TREE, logic->IsChild && logic->CanBonkTrees() && logic->AtDay), + LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_MARKET_ENTRANCE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index bcec85029..584408b15 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3258,7 +3258,7 @@ std::map rcToRandomizerInf = { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, }, - { RC_MARKET_DAY_TREE, RAND_INF_MARKET_DAY_TREE }, + { 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 }, @@ -3743,6 +3743,10 @@ SmallCrateIdentity Randomizer::IdentifySmallCrate(s32 sceneNum, s32 posX, s32 po TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { struct TreeIdentity treeIdentity; + if (sceneNum == SCENE_MARKET_NIGHT) { + sceneNum = SCENE_MARKET_DAY; + } + for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { s32 actorParams = TWO_ACTOR_PARAMS(posX + x, posZ + z); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index a1611dd7c..198f51996 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2647,7 +2647,7 @@ typedef enum { // End Crates // Start Trees - RC_MARKET_DAY_TREE, + RC_MARKET_TREE, RC_HC_NEAR_GUARDS_TREE_1, RC_HC_NEAR_GUARDS_TREE_2, RC_HC_NEAR_GUARDS_TREE_3, diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 1349b27df..20dc0e8b7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -997,7 +997,7 @@ 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_DAY_TREE) +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) From 07e3454bc04c8b096124e9ad783a651fefeb7131 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Mon, 9 Jun 2025 02:30:39 +0000 Subject: [PATCH 03/12] NL Trees --- .../randomizer/3drando/item_pool.cpp | 7 +- .../Enhancements/randomizer/ShuffleTrees.cpp | 8 +- soh/soh/Enhancements/randomizer/context.cpp | 4 +- soh/soh/Enhancements/randomizer/location.cpp | 9 ++ soh/soh/Enhancements/randomizer/location.h | 4 + .../overworld/castle_grounds.cpp | 2 + .../overworld/hyrule_field.cpp | 6 +- .../Enhancements/randomizer/randomizer.cpp | 12 +- .../Enhancements/randomizer/randomizerTypes.h | 9 +- .../randomizer/randomizer_check_objects.cpp | 2 + .../randomizer/randomizer_check_tracker.cpp | 127 +++++++++--------- .../Enhancements/randomizer/randomizer_inf.h | 8 +- 12 files changed, 117 insertions(+), 81 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index ef8585e4b..e99a41402 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -607,17 +607,16 @@ void GenerateItemPool() { // Shuffle Trees bool treesActive = (bool)ctx->GetOption(RSK_SHUFFLE_TREES); PlaceItemsForType(RCTYPE_TREE, treesActive, false); + PlaceItemsForType(RCTYPE_NLTREE, treesActive && ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC), 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 overworldNLCratesActive = overworldCratesActive && ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC); 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_NLCRATE, overworldNLCratesActive, false); PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); auto fsMode = ctx->GetOption(RSK_FISHSANITY); diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index 45b51c0b5..1a9da8f04 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -145,11 +145,13 @@ void Rando::StaticData::RegisterTreeLocations() { 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_TREE_NEAR_HC_GROTTO_1] = Location::Tree(RC_HF_TREE_NEAR_HC_GROTTO_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_TREE_NEAR_HC_GROTTO_1)); - locationTable[RC_HF_TREE_NEAR_HC_GROTTO_2] = Location::Tree(RC_HF_TREE_NEAR_HC_GROTTO_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_TREE_NEAR_HC_GROTTO_2)); - locationTable[RC_HF_TREE_NEAR_HC_GROTTO_3] = Location::Tree(RC_HF_TREE_NEAR_HC_GROTTO_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_TREE_NEAR_HC_GROTTO_3)); + 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)); diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index a8a397827..fa4d5cb16 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -189,10 +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])) { diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index c82724180..575198649 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -575,6 +575,15 @@ Rando::Location Rando::Location::Tree(RandomizerCheck rc, RandomizerCheckQuest q 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, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index 6de26bc41..9c565344f 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -250,6 +250,10 @@ class Location { 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_); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index d88e6acff..3309b5fea 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -34,6 +34,8 @@ void RegionTable_Init_CastleGrounds() { 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, logic->CanBonkTrees()), + LOCATION(RC_HC_NL_TREE_2, logic->CanBonkTrees()), 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()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 98b904cc6..3789a8851 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -68,9 +68,9 @@ void RegionTable_Init_HyruleField() { 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_TREE_NEAR_HC_GROTTO_1, logic->CanBonkTrees()), - LOCATION(RC_HF_TREE_NEAR_HC_GROTTO_2, logic->CanBonkTrees()), - LOCATION(RC_HF_TREE_NEAR_HC_GROTTO_3, 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()), diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 584408b15..8286fa2cd 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3267,11 +3267,13 @@ std::map rcToRandomizerInf = { { 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_TREE_NEAR_HC_GROTTO_1, RAND_INF_HF_TREE_NEAR_HC_GROTTO_1 }, - { RC_HF_TREE_NEAR_HC_GROTTO_2, RAND_INF_HF_TREE_NEAR_HC_GROTTO_2 }, - { RC_HF_TREE_NEAR_HC_GROTTO_3, RAND_INF_HF_TREE_NEAR_HC_GROTTO_3 }, + { 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 }, @@ -3752,6 +3754,10 @@ TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { s32 actorParams = TWO_ACTOR_PARAMS(posX + x, posZ + z); Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams); if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + if (location->GetRCType() == RCTYPE_NLTREE && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) { + break; + } treeIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; treeIdentity.randomizerCheck = location->GetRandomizerCheck(); return treeIdentity; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 198f51996..960b908b1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -300,6 +300,7 @@ typedef enum { 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 @@ -2656,6 +2657,8 @@ typedef enum { 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, @@ -2663,9 +2666,9 @@ typedef enum { RC_HF_NEAR_ZR_TREE, RC_HF_NEAR_KAK_TREE, RC_HF_NEAR_KAK_SMALL_TREE, - RC_HF_TREE_NEAR_HC_GROTTO_1, - RC_HF_TREE_NEAR_HC_GROTTO_2, - RC_HF_TREE_NEAR_HC_GROTTO_3, + 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, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 29e0fae7a..f8a73ddd2 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -191,6 +191,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { 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 || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 56480079b..017cda742 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1533,69 +1533,74 @@ bool IsCheckShuffled(RandomizerCheck rc) { auto identity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1); } if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) { - 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 - (rc != RC_LINKS_POCKET || showLinksPocket) && - OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && - (loc->GetRCType() != RCTYPE_SHOP || - (showShops && - OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1) - .enGirlAShopItem == 50)) && - (rc != RC_TRIFORCE_COMPLETED) && (rc != RC_GANON) && - (loc->GetRCType() != RCTYPE_SCRUB || showScrubs || - (showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized - rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) && - (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && - (loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) && - (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && - (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && - (loc->GetRCType() != RCTYPE_SKULL_TOKEN || alwaysShowGS || - (showOverworldTokens && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonTokens && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_POT || - (showOverworldPots && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonPots && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_GRASS || - (showOverworldGrass && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonGrass && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_CRATE || - (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_NLCRATE || - (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea()) && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC) || - (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_SMALL_CRATE || - (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_TREE || showTrees) && (loc->GetRCType() != RCTYPE_COW || showCows) && + 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 + (rc != RC_LINKS_POCKET || showLinksPocket) && + OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && + (loc->GetRCType() != RCTYPE_SHOP || + (showShops && + OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1) + .enGirlAShopItem == 50)) && + (rc != RC_TRIFORCE_COMPLETED) && (rc != RC_GANON) && + (loc->GetRCType() != RCTYPE_SCRUB || showScrubs || + (showMajorScrubs && + (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized + rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) && + (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && + (loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) && + (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && + (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && + (loc->GetRCType() != RCTYPE_SKULL_TOKEN || alwaysShowGS || + (showOverworldTokens && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonTokens && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_POT || + (showOverworldPots && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonPots && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_GRASS || + (showOverworldGrass && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonGrass && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_CRATE || + (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_NLCRATE || + (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea()) && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC) || + (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_SMALL_CRATE || + (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_TREE || showTrees) && (loc->GetRCType() != RCTYPE_COW || showCows) && + (loc->GetRCType() != RCTYPE_NLTREE || + (showTrees && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) || (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && - (loc->GetRCType() != RCTYPE_FREESTANDING || - (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || - rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled - rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off - ) && - (rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && (rc != RC_TOT_MASTER_SWORD || showMasterSword) && - (rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && - (rc != RC_HC_MALON_EGG || showWeirdEgg) && - (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && - ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && - (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && - (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && - (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && - (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && - (rc != RC_KAK_100_GOLD_SKULLTULA_REWARD || show100SkullReward) && - (loc->GetRCType() != RCTYPE_GF_KEY && rc != RC_TH_FREED_CARPENTERS || - (showGerudoCard && rc == RC_TH_FREED_CARPENTERS) || - (fortressNormal && showGerudoFortressKeys && loc->GetRCType() == RCTYPE_GF_KEY) || - (fortressFast && showGerudoFortressKeys && rc == RC_TH_1_TORCH_CARPENTER)); + (loc->GetRCType() != RCTYPE_FREESTANDING || + (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || + rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled + rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off + ) && + (rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && + (rc != RC_TOT_MASTER_SWORD || showMasterSword) && (rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && + (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && (rc != RC_HC_MALON_EGG || showWeirdEgg) && + (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && + ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || + showStartingMapsCompasses) && + (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && + (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && + (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && + (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && + (rc != RC_KAK_100_GOLD_SKULLTULA_REWARD || show100SkullReward) && + (loc->GetRCType() != RCTYPE_GF_KEY && rc != RC_TH_FREED_CARPENTERS || + (showGerudoCard && rc == RC_TH_FREED_CARPENTERS) || + (fortressNormal && showGerudoFortressKeys && loc->GetRCType() == RCTYPE_GF_KEY) || + (fortressFast && showGerudoFortressKeys && rc == RC_TH_1_TORCH_CARPENTER)); } else if (loc->IsVanillaCompletion()) { return (OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) || rc == RC_GIFT_FROM_RAURU) && rc != RC_LINKS_POCKET; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 20dc0e8b7..824a7e67c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1006,6 +1006,8 @@ 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) @@ -1013,9 +1015,9 @@ 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_TREE_NEAR_HC_GROTTO_1) -DEFINE_RAND_INF(RAND_INF_HF_TREE_NEAR_HC_GROTTO_2) -DEFINE_RAND_INF(RAND_INF_HF_TREE_NEAR_HC_GROTTO_3) +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) From e73808bb7fdb351cea816f668ee2a1803dda10c6 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Mon, 9 Jun 2025 03:03:13 +0000 Subject: [PATCH 04/12] remove LUSLOG --- soh/soh/Enhancements/randomizer/ShuffleTrees.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index 1a9da8f04..aec3ab235 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -102,9 +102,6 @@ void EnWood02_RandomizerInit(void* 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); - if (treeActor->treeId.randomizerCheck == RC_UNKNOWN_CHECK) { - LUSLOG_WARN("TREE %d,%d", (int)treeActor->actor.world.pos.x, (int)treeActor->actor.world.pos.z); - } } } From 4d552638092d19f79e25185de7e6961987e1321f Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Mon, 9 Jun 2025 22:45:03 +0000 Subject: [PATCH 05/12] feedback --- soh/soh/Enhancements/randomizer/3drando/item_pool.cpp | 9 ++++++--- .../location_access/overworld/castle_grounds.cpp | 4 ++-- .../randomizer/location_access/overworld/kakariko.cpp | 2 +- .../Enhancements/randomizer/randomizer_check_tracker.cpp | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index e99a41402..9a6eee78c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -607,17 +607,20 @@ void GenerateItemPool() { // Shuffle Trees bool treesActive = (bool)ctx->GetOption(RSK_SHUFFLE_TREES); PlaceItemsForType(RCTYPE_TREE, treesActive, false); - PlaceItemsForType(RCTYPE_NLTREE, treesActive && ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC), 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 = overworldCratesActive && ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC); 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, false); 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)) { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index 3309b5fea..a5dfcfd6d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -34,8 +34,8 @@ void RegionTable_Init_CastleGrounds() { 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, logic->CanBonkTrees()), - LOCATION(RC_HC_NL_TREE_2, 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()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 9ca3fd266..e4bb89e64 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -57,7 +57,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->IsChild && logic->CanBonkTrees()), + LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 017cda742..a3fe14fb7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1576,7 +1576,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_TREE || showTrees) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_NLTREE || (showTrees && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && (loc->GetRCType() != RCTYPE_FREESTANDING || From b93bb26e6137ecabd639320b927b18943bd940db Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Tue, 10 Jun 2025 02:41:43 +0000 Subject: [PATCH 06/12] format --- .../randomizer/randomizer_check_tracker.cpp | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index a3fe14fb7..d9dce55c2 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1533,50 +1533,50 @@ bool IsCheckShuffled(RandomizerCheck rc) { auto identity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1); } if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) { - 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 - (rc != RC_LINKS_POCKET || showLinksPocket) && - OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && - (loc->GetRCType() != RCTYPE_SHOP || - (showShops && - OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1) - .enGirlAShopItem == 50)) && - (rc != RC_TRIFORCE_COMPLETED) && (rc != RC_GANON) && - (loc->GetRCType() != RCTYPE_SCRUB || showScrubs || - (showMajorScrubs && - (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized - rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) && - (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && - (loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) && - (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && - (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && - (loc->GetRCType() != RCTYPE_SKULL_TOKEN || alwaysShowGS || - (showOverworldTokens && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonTokens && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_POT || - (showOverworldPots && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonPots && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_GRASS || - (showOverworldGrass && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonGrass && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_CRATE || - (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_NLCRATE || - (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea()) && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC) || - (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_SMALL_CRATE || - (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_TREE || showTrees) && (loc->GetRCType() != RCTYPE_COW || showCows) && - (loc->GetRCType() != RCTYPE_NLTREE || - (showTrees && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && + 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 + (rc != RC_LINKS_POCKET || showLinksPocket) && + OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && + (loc->GetRCType() != RCTYPE_SHOP || + (showShops && + OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1) + .enGirlAShopItem == 50)) && + (rc != RC_TRIFORCE_COMPLETED) && (rc != RC_GANON) && + (loc->GetRCType() != RCTYPE_SCRUB || showScrubs || + (showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized + rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) && + (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && + (loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) && + (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && + (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && + (loc->GetRCType() != RCTYPE_SKULL_TOKEN || alwaysShowGS || + (showOverworldTokens && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonTokens && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_POT || + (showOverworldPots && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonPots && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_GRASS || + (showOverworldGrass && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonGrass && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_CRATE || + (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_NLCRATE || + (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea()) && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC) || + (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (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)) && (loc->GetRCType() != RCTYPE_FREESTANDING || From 82b1733d9f302225beb318f4733f9be6ec5edf88 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Wed, 11 Jun 2025 01:47:29 +0000 Subject: [PATCH 07/12] golden skulltula tree qol --- soh/soh/Enhancements/randomizer/ShuffleTrees.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index aec3ab235..a5c70bf3e 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -122,6 +122,16 @@ void RegisterShuffleTrees() { 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; } }); From 22a52cb60fb671e7eb7f6c41083448caa4ca215d Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Fri, 13 Jun 2025 01:00:37 +0000 Subject: [PATCH 08/12] post-rebase --- .../game-interactor/vanilla-behavior/GIVanillaBehavior.h | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index ea20b398f..562aac9e5 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2155,6 +2155,7 @@ typedef enum { // - `*EnWood02` VB_TREE_DROP_COLLECTIBLE, + // #### `result` // ```c // true // ``` From 67668fd603e6211b6cc187e322fc42207fe3d3eb Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Fri, 13 Jun 2025 02:27:36 +0000 Subject: [PATCH 09/12] trust -129 --- .../Enhancements/randomizer/randomizer.cpp | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 8286fa2cd..14a06f0a4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3749,20 +3749,13 @@ TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { sceneNum = SCENE_MARKET_DAY; } - for (int x = -1; x <= 1; x++) { - for (int z = -1; z <= 1; z++) { - s32 actorParams = TWO_ACTOR_PARAMS(posX + x, posZ + z); - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams); - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { - if (location->GetRCType() == RCTYPE_NLTREE && - CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) { - break; - } - treeIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - treeIdentity.randomizerCheck = location->GetRandomizerCheck(); - return treeIdentity; - } - } + 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; From 631882028e1514d02831fa5a37ae7fe72b7996a7 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 21 Jun 2025 14:14:48 +0000 Subject: [PATCH 10/12] remove tree graphic, crate csmc --- .../objects/object_rando_tree/gRandoTreeDL | 12 -- .../gRandoTreeDLTriforceTexture32.rgba16 | Bin 2140 -> 0 bytes .../object_rando_tree/gRandoTreeDL_tri_0 | 12 -- .../object_rando_tree/gRandoTreeDL_tri_1 | 9 -- .../object_rando_tree/gRandoTreeDL_vtx_0 | 32 ----- .../object_rando_tree/gRandoTreeDL_vtx_1 | 18 --- .../object_rando_tree/gRandoTreeDL_vtx_cull | 10 -- .../mat_gRandoTreeDL_treeTexMaterial | 16 --- .../mat_gRandoTreeDL_triforceTexMaterial | 16 --- .../mat_revert_gRandoTreeDL_treeTexMaterial | 6 - ...at_revert_gRandoTreeDL_triforceTexMaterial | 6 - soh/assets/soh_assets.h | 3 - .../Enhancements/randomizer/ShuffleTrees.cpp | 109 ++++++++++++------ 13 files changed, 73 insertions(+), 176 deletions(-) delete mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL delete mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDLTriforceTexture32.rgba16 delete mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 delete mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 delete mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 delete mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 delete mode 100644 soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull delete mode 100644 soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial delete mode 100644 soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial delete mode 100644 soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial delete mode 100644 soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL deleted file mode 100644 index 8ab80efae..000000000 --- a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDLTriforceTexture32.rgba16 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDLTriforceTexture32.rgba16 deleted file mode 100644 index 256efd65a2a477f136c33b04119d02f306594ded..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2140 zcma)7J&Wr`6!l~fj@e@W!YjRFiPg zF$iOVN^j}%wdqploRPiTq{v?MVa+}F+`0GM+1YG1`!)ULXMyM6fBtdhh1dW6_Z>Vx z-L47r+YhrDuJ32FM8-b$iA?0uFY!iO4lw-s^dH9WFnR==5CQdppQ7Bo0^;s*!%tCg zS5irh3zmla^e&W)eQ7#fx~GVFB@x$kqZ>TaL@NG{CX_a|(Wy4dyvITmZQ6dUF1-zV zi9Mt1)NT=D%l+yme^4oL!QijJddmfGo4(TntTPERxMfQJR5#$4w#m+kdB+>e41f=2 ztZOS^fgh{qNQFIUQ#|C0d|`ptCOhYgC!uTNEOSV+6SKCdt!?A5_o0I6!Hl&%vrkGE z547wY_e$oA;vo^t9sVg%*_p9ejWQh!b04b_5#FNRmNiQvdoDj`r+lGL$}kf}BpI9R z1UxQs7xTR%p6C(#@66bgE8@L&2RvoSA6UlFrqtl}qhs9$eH2Ha$v;-#^x7eV z6|_bk?4Olj-CTK8{@6a`%JK)>uD6j)u-}Irkp6boO5BvfdqhicEJMj*7^Cm8R z;D&O;8+35!+p4WD)jxe{s9d7#srU(~b6}tF__}jf@zR&N6vexhg1@r96o>u@-9o!5 zs$S=J{w8ZIrV8qeF21eSm37u>je4NU!6aF-VN+dYnJzJl&@XqvSwL4%kyR4K{>5Kq z>(@FPup1Y$qq6xII)~c0(P_+6?5P=bW58raNu;qhy1jeWU{AB5TotQgjyOK_EiFvz zj`AuUy2w3H2Vvr%D=1UGiZ?L;@0|6_tei7KnPwjS!u<!6I$p^6dk;mn{av7e}r ztU9&+RTh|D>a2*0`Fcwp>(>4iDj29NfACP+N=5WhX*|S(b}#-m?a1*NePmsVc~)Uo zSXtws!w%XS-JmZ$l(a$wscW3OI7c^rgkC}fGgL>p#@Pqnn)^e)!QLW14Eb>`_gG~W zY!d^m%^u%E{-TpuM-@uWOHfN-hl(aubx`Hlzkz`#tTM|Xkj*pjv_Nn4rlxm7}}LSL!&mp6sD^A71e07ck+;%s7FVK|Fb(1O6(m z;#n4EgTC&~p+EF{oDh3t(+1SUb?B!^w^h`Y9`yVQ{%48v$HCAkbb~tLbfIQ9Lw+js zfZxM<1U1w|V73~CsZmyMKTO$Vp3LvR^T+&AZ6^;!ufO!xj`^eB{fHHs-aR2gJYafu d%EEJ};SYPiKQSvr43Ssp_I%=?>hOPU_!m^vAPxWk diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 deleted file mode 100644 index 16bbada99..000000000 --- a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_0 +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 deleted file mode 100644 index 136154b4c..000000000 --- a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_tri_1 +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 deleted file mode 100644 index e92b51e78..000000000 --- a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_0 +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 deleted file mode 100644 index adf256fc1..000000000 --- a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_1 +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull b/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull deleted file mode 100644 index ea47c02e0..000000000 --- a/soh/assets/custom/objects/object_rando_tree/gRandoTreeDL_vtx_cull +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial deleted file mode 100644 index 219a71f77..000000000 --- a/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_treeTexMaterial +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial deleted file mode 100644 index a95fff2b0..000000000 --- a/soh/assets/custom/objects/object_rando_tree/mat_gRandoTreeDL_triforceTexMaterial +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial deleted file mode 100644 index ee8de0c37..000000000 --- a/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_treeTexMaterial +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial b/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial deleted file mode 100644 index ee8de0c37..000000000 --- a/soh/assets/custom/objects/object_rando_tree/mat_revert_gRandoTreeDL_triforceTexMaterial +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index e3e2f4780..3c3ddcf5a 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -77,9 +77,6 @@ static const ALIGN_ASSET(2) char gBossSoulSkullDL[] = dgBossSoulSkullDL; #define dgRandoPotDL "__OTR__objects/gameplay_dangeon_keep/gRandoPotDL" static const ALIGN_ASSET(2) char gRandoPotDL[] = dgRandoPotDL; -#define dgRandoTreeDL "__OTR__objects/object_rando_tree/gRandoTreeDL" -static const ALIGN_ASSET(2) char gRandoTreeDL[] = dgRandoTreeDL; - #define dgRandoBushDL "__OTR__objects/gameplay_field_keep/gFieldBushRandomDL" static const ALIGN_ASSET(2) char gRandoBushDL[] = dgRandoBushDL; diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index a5c70bf3e..502a91d99 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -6,6 +6,7 @@ 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*); } @@ -41,45 +42,82 @@ uint8_t EnWood02_RandomizerHoldsItem(EnWood02* treeActor, PlayState* play) { } extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) { - EnWood02* thisy = (EnWood02*)thisx; - s16 type = thisy->actor.params; - u8 red; - u8 green; - u8 blue; + GetItemCategory getItemCategory; + auto treeActor = (EnWood02*)thisx; + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); - if ((type == WOOD_TREE_OVAL_GREEN_SPAWNER) || (type == WOOD_TREE_OVAL_GREEN_SPAWNED) || - (type == WOOD_TREE_OVAL_GREEN) || (type == WOOD_LEAF_GREEN)) { - red = 50; - green = 170; - blue = 70; - } else if ((type == WOOD_TREE_OVAL_YELLOW_SPAWNER) || (type == WOOD_TREE_OVAL_YELLOW_SPAWNED) || - (type == WOOD_LEAF_YELLOW)) { - red = 180; - green = 155; - blue = 0; - } else { - red = green = blue = 255; + 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; } - OPEN_DISPS(play->state.gfxCtx); - Gfx_SetupDL_25Xlu(play->state.gfxCtx); - if ((thisy->actor.params == WOOD_LEAF_GREEN) || (thisy->actor.params == WOOD_LEAF_YELLOW)) { - Gfx_SetupDL_25Opa(play->state.gfxCtx); - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 127); - Gfx_DrawDListOpa(play, (Gfx*)gRandoTreeDL); - } else if (D_80B3BF70[thisy->drawType & 0xF] != NULL) { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 0); - Gfx_DrawDListOpa(play, (Gfx*)gRandoTreeDL); - gDPSetEnvColor(POLY_XLU_DISP++, red, green, blue, 0); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_80B3BF70[thisy->drawType & 0xF]); - } - CLOSE_DISPS(play->state.gfxCtx); + GetItemEntry smallCrateItem = + Rando::Context::GetInstance()->GetFinalGIEntry(treeActor->treeId.randomizerCheck, true, GI_NONE); + getItemCategory = smallCrateItem.getItemCategory; - if (!EnWood02_RandomizerHoldsItem(thisy, gPlayState)) { - thisy->actor.draw = (ActorFunc)EnWood02_Draw; + // 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) { @@ -113,8 +151,7 @@ void RegisterShuffleTrees() { COND_VB_SHOULD(VB_TREE_SETUP_DRAW, shouldRegister, { EnWood02* treeActor = va_arg(args, EnWood02*); if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { - treeActor->actor.draw = (ActorFunc)EnWood02_RandomizerDraw; - *should = false; + EnWood02_RandomizerDraw(&treeActor->actor, gPlayState); } }); From 309b45f0e41bfa67f64ab70952f19cd5373c7079 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Thu, 26 Jun 2025 05:17:08 +0000 Subject: [PATCH 11/12] format --- .../randomizer/randomizer_check_tracker.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d9dce55c2..8849d2ea3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1579,28 +1579,27 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && - (loc->GetRCType() != RCTYPE_FREESTANDING || - (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || - rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled - rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off - ) && - (rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && - (rc != RC_TOT_MASTER_SWORD || showMasterSword) && (rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && - (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && (rc != RC_HC_MALON_EGG || showWeirdEgg) && - (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && - ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || - showStartingMapsCompasses) && - (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && - (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && - (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && - (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && - (rc != RC_KAK_100_GOLD_SKULLTULA_REWARD || show100SkullReward) && - (loc->GetRCType() != RCTYPE_GF_KEY && rc != RC_TH_FREED_CARPENTERS || - (showGerudoCard && rc == RC_TH_FREED_CARPENTERS) || - (fortressNormal && showGerudoFortressKeys && loc->GetRCType() == RCTYPE_GF_KEY) || - (fortressFast && showGerudoFortressKeys && rc == RC_TH_1_TORCH_CARPENTER)); + (loc->GetRCType() != RCTYPE_FREESTANDING || + (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || + rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled + rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off + ) && + (rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && (rc != RC_TOT_MASTER_SWORD || showMasterSword) && + (rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && + (rc != RC_HC_MALON_EGG || showWeirdEgg) && + (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && + ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && + (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && + (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && + (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && + (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && + (rc != RC_KAK_100_GOLD_SKULLTULA_REWARD || show100SkullReward) && + (loc->GetRCType() != RCTYPE_GF_KEY && rc != RC_TH_FREED_CARPENTERS || + (showGerudoCard && rc == RC_TH_FREED_CARPENTERS) || + (fortressNormal && showGerudoFortressKeys && loc->GetRCType() == RCTYPE_GF_KEY) || + (fortressFast && showGerudoFortressKeys && rc == RC_TH_1_TORCH_CARPENTER)); } else if (loc->IsVanillaCompletion()) { return (OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) || rc == RC_GIFT_FROM_RAURU) && rc != RC_LINKS_POCKET; From e1a90c699ca6938ddf4d7aebf5c44e9eab6265fc Mon Sep 17 00:00:00 2001 From: PurpleHato Date: Sat, 2 Aug 2025 16:16:33 +0200 Subject: [PATCH 12/12] French Translation --- .../hint_list/hint_list_exclude_overworld.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 3314d6872..6876a58d4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -2084,27 +2084,27 @@ void StaticData::HintTable_Init_Exclude_Overworld() { hintTextTable[RHT_TREE_HYRULE_FIELD] = HintText(CustomMessage("They say that a #tree in Hyrule Field# contains #[[1]]#.", /*german*/ "", - /*french*/ "", { QM_RED, QM_GREEN })); + /*french*/ "Selon moi, un #arbre dans la Plaine d'Hyrule# cache #[[1]]#.", { 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 })); + /*french*/ "Selon moi, un #arbre sur la Place du Marché# cache #[[1]]#.", { 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 })); + /*french*/ "Selon moi, un #arbre au Château d'Hyrule# cache #[[1]]#.", { 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 })); + /*french*/ "Selon moi, un #arbre à la Rivière Zora# cache #[[1]]#.", { 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 })); + /*french*/ "Selon moi, un #arbre à la Fontaine Zora# cache #[[1]]#.", { 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 })); + /*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN })); // clang-format on } } // namespace Rando