Skip to content

Commit

Permalink
Freestanding Rupees/Hearts Shuffle (HarbourMasters#4686)
Browse files Browse the repository at this point in the history
* Enable freestanding items other than heart pieces and keys

* Add option to disable freestanding rupee & heart shuffle

* Add items to pool

* Actually add shuffle setting

* Define overworld locations

* Add logic for overworld freestanding checks

* Add freestanding items for child dungeons.

* Add checks for Ice Cavern and Bottom of the Well

* Add checks for Forest Temple and Gerudo Training Grounds

* Add checks for Fire Temple and Water Temple

* Add Shadow Temple checks

This does not include the spinning pots rupees, even though
they're included with freestanding rupees in the N64 randomizer
as they would require dedicated overrides for the code for
the pots in question.

* Define Spirit Temple and Ganon's Castle hearts

* Add remaining checks to dungeon definitions

* Fix missing logic

* Add freestanding checks to Save Flags Editor

* Fix flags for Zora Fountain underwater rupees

* Add option to enable freestanding shuffle for either dungeons or overworld

* Add missing MQ checks and fix mac & windows compile error

* Improve description and add hint text

* Update logic for Bombchu fixes

* Add missing Spirit Temple MQ hearts

* Add missing settings entries

* Actually add Forest Temple trick to the tricks menu.

* Re-add Ice Cavern lobby rupee

* go over MQ logic

* review logic on non-MQ checks

* convert all freestandings to location based

* add option enum and fix jabu exit logic

* fix mislocated freestandings

* fix mislocted freestandings

* Fix some mislocationed checks

---------

Co-authored-by: Angel Bulfone <mbulfone@gmail.com>
  • Loading branch information
Pepper0ni and boomshroom authored Dec 22, 2024
1 parent ff24581 commit 9ea9100
Show file tree
Hide file tree
Showing 34 changed files with 1,545 additions and 156 deletions.
1 change: 0 additions & 1 deletion soh/include/z64actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ typedef struct EnItem00 {
/* 0x15C */ f32 scale;
/* 0x160 */ ColliderCylinder collider;
// #region SOH [Randomizer]
GetItemEntry randoGiEntry;
RandomizerCheck randoCheck;
RandomizerInf randoInf;
/* */ s16 ogParams;
Expand Down
175 changes: 175 additions & 0 deletions soh/soh/Enhancements/debugger/debugSaveEditor.h

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() {
/*french*/ "Selon moi, la #peste Mojo dans l'Arbre Mojo# vend #[[1]]#.", {QM_RED, QM_GREEN}));
// /*spanish*/ Según dicen, un #deku del Gran Árbol Deku# vende #[[1]]#.

hintTextTable[RHT_DEKU_TREE_HEART] = HintText(CustomMessage("They say that a #heart in the Deku Tree# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| DODONGOS CAVERN |
---------------------------*/
Expand Down Expand Up @@ -279,6 +283,10 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_DODONGOS_CAVERN_HEART] = HintText(CustomMessage("They say that a #heart in Dodongo's Cavern# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| JABU JABUS BELLY |
---------------------------*/
Expand Down Expand Up @@ -430,6 +438,15 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));


hintTextTable[RHT_JABU_JABU_RUPEE] = HintText(CustomMessage("They say that #underwater in Jabu-Jabu's Belly# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_JABU_JABU_HEART] = HintText(CustomMessage("They say that near a #central lift in Jabu-Jabu's Belly# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| FOREST TEMPLE |
---------------------------*/
Expand Down Expand Up @@ -657,6 +674,10 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The
/*french*/ "", {QM_RED, QM_GREEN}));


hintTextTable[RHT_FOREST_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Forest Temple# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| FIRE TEMPLE |
---------------------------*/
Expand Down Expand Up @@ -849,6 +870,10 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_FIRE_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Fire Temple# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| WATER TEMPLE |
---------------------------*/
Expand Down Expand Up @@ -980,6 +1005,10 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_WATER_TEMPLE_HEART] = HintText(CustomMessage("They say that in a #river in the Water Temple# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| SPIRIT TEMPLE |
---------------------------*/
Expand Down Expand Up @@ -1217,6 +1246,14 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_SPIRIT_TEMPLE_HEART] = HintText(CustomMessage("They say that on a #small platform# in the Spirit Temple lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_SPIRIT_TEMPLE_MQ_HEART] = HintText(CustomMessage("They say that guarded by a #ring of flame# in the Spirit Temple is #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| SHADOW TEMPLE |
---------------------------*/
Expand Down Expand Up @@ -1464,6 +1501,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_SHADOW_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Shadow Temple# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| BOTTOM OF THE WELL |
---------------------------*/
Expand Down Expand Up @@ -1586,6 +1627,14 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_BOTTOM_OF_THE_WELL_HEART] = HintText(CustomMessage("They say that a #heart within the well# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_BOTTOM_OF_THE_WELL_RUPEE] = HintText(CustomMessage("They say that a #hidden path through the floor# the well# leads to #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| ICE CAVERN |
---------------------------*/
Expand Down Expand Up @@ -1663,6 +1712,14 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*german*/ "",
/*french*/ "", { QM_RED, QM_GREEN }));

hintTextTable[RHT_ICE_CAVERN_HEART] = HintText(CustomMessage("They say that atop on a #frozen pillar# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_ICE_CAVERN_RUPEE] = HintText(CustomMessage("They say that a #rupee in a frozen cavern# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| Gerudo Training Ground |
---------------------------*/
Expand Down Expand Up @@ -1841,6 +1898,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
/*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN}));
// /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#.

hintTextTable[RHT_GERUDO_TRAINING_GROUNDS_HEART] = HintText(CustomMessage("They say that a watching a #trial with Dinalfos# is #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

/*--------------------------
| GANONS CASTLE |
---------------------------*/
Expand Down Expand Up @@ -2037,5 +2098,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th
hintTextTable[RHT_POT_GANONS_CASTLE] = HintText(CustomMessage("They say that a #pot in Ganon's Castle# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

hintTextTable[RHT_GANONS_CASTLE_HEART] = HintText(CustomMessage("They say that a #heart in Ganon's Castle# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1542,5 +1542,65 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
hintTextTable[RHT_POT_HYRULE_CASTLE] = HintText(CustomMessage("They say that a #pot in Hyrule Castle# contains #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
hintTextTable[RHT_KOKIRI_FOREST_RUPEE] = HintText(CustomMessage("They say that a rupee in a #tranquil forest# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_KOKIRI_FOREST_HEART] = HintText(CustomMessage("They say that a heart in a #tranquil forest# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_SARIAS_HOUSE_HEART] = HintText(CustomMessage("They say that a heart in a #dear friend's home# hides #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_LOST_WOODS_RUPEE] = HintText(CustomMessage("They say that under a #boulder in the woods# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_LOST_WOODS_SHORTCUT_RUPEE] = HintText(CustomMessage("They say that in a #pool of water in the woods# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_LAKE_HYLIA_RUPEE] = HintText(CustomMessage("They say that just off the #coast of a lake# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_LABORATORY_RUPEE] = HintText(CustomMessage("They say that at the #bottom of a tank# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_DAMPES_GRAVE_RUPEE] = HintText(CustomMessage("They say that within a #quick-footed spirit's grave# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_GERUDO_VALLEY_GROTTO_RUPEE] = HintText(CustomMessage("They say that an Octarok in an #underground spring# guards #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_RUPEE] = HintText(CustomMessage("They say that beneath a boulder on a #mountain's cliffside# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART] = HintText(CustomMessage("They say that accompanying a #cow in a small cave# is #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE] = HintText(CustomMessage("They say that accompanying a #cow in a small cave# is #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_DEATH_MOUNTAIN_CRATER_RUPEE] = HintText(CustomMessage("They say that on a #small platform suspended above lava# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_ZORAS_RIVER_WATERFALL_RUPEE] = HintText(CustomMessage("They say that beneath a #waterfall feeding a narrow river# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
hintTextTable[RHT_ZORAS_FOUNTAIN_RUPEE] = HintText(CustomMessage("They say that at the bottom of a #partially-frozen spring# lies #[[1]]#.",
/*german*/ "",
/*french*/ "", {QM_RED, QM_GREEN}));
// /*spanish*/
}
}
26 changes: 26 additions & 0 deletions soh/soh/Enhancements/randomizer/3drando/item_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,30 @@ static void PlaceVanillaOverworldFish() {
}
}

static void PlaceFreestandingItems() {
auto ctx = Rando::Context::GetInstance();
auto option = ctx->GetOption(RSK_SHUFFLE_FREESTANDING);
for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_FREESTANDING)) {
RandomizerGet vanillaItem = Rando::StaticData::GetLocation(loc)->GetVanillaItem();
if (option.Is(RO_FREESTANDING_OVERWORLD) || option.Is(RO_FREESTANDING_ALL)) {
AddItemToMainPool(vanillaItem);
} else {
ctx->PlaceItemInLocation(loc, vanillaItem, false, true);
}
}

for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) {
for (RandomizerCheck loc : ctx->GetLocations(dungeon->GetDungeonLocations(), RCTYPE_FREESTANDING)) {
RandomizerGet vanillaItem = Rando::StaticData::GetLocation(loc)->GetVanillaItem();
if (option.Is(RO_FREESTANDING_DUNGEONS) || option.Is(RO_FREESTANDING_ALL)) {
AddItemToMainPool(vanillaItem);
} else {
ctx->PlaceItemInLocation(loc, vanillaItem, false, true);
}
}
}
}

static void SetScarceItemPool() {
ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 3);
ReplaceMaxItem(RG_BOMBCHU_5, 1);
Expand Down Expand Up @@ -1255,6 +1279,8 @@ void GenerateItemPool() {
PlaceVanillaDekuScrubItems(ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF));
}

PlaceFreestandingItems();

AddItemsToPool(ItemPool, alwaysItems);
AddItemsToPool(ItemPool, dungeonRewards);

Expand Down
Loading

0 comments on commit 9ea9100

Please sign in to comment.