Freestanding Shuffle fixes & extract to separate file (#4808)

* Freestanding fixes

* Copy paste fail

* Temporary vanilla items fix
This commit is contained in:
aMannus 2025-01-05 19:10:46 +01:00 committed by GitHub
parent 700c1a808d
commit 23466e5a5e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 143 additions and 72 deletions

View File

@ -1354,13 +1354,15 @@ void GenerateItemPool() {
PlaceVanillaDekuScrubItems(ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF));
}
bool overworldFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_FREESTANDING_OVERWORLD) ||
ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_FREESTANDING_ALL);
bool dungeonFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_FREESTANDING_DUNGEONS) ||
ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_FREESTANDING_ALL);
if (overworldFreeStandingActive || dungeonFreeStandingActive) {
// RANDOTODO: Don't add freestanding locations to the seed at all in the first place so this check
// can be put back in place, and not place the vanilla items in PlaceItemsForType.
bool overworldFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_OVERWORLD) ||
ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL);
bool dungeonFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_DUNGEONS) ||
ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL);
//if (overworldFreeStandingActive || dungeonFreeStandingActive) {
PlaceItemsForType(RCTYPE_FREESTANDING, overworldFreeStandingActive, dungeonFreeStandingActive, true);
}
//}
AddItemsToPool(ItemPool, alwaysItems);
AddItemsToPool(ItemPool, dungeonRewards);

View File

@ -0,0 +1,45 @@
#include "ShuffleFreestanding.h"
extern "C" {
#include "functions.h";
extern PlayState* gPlayState;
}
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) {
va_list args;
va_copy(args, originalArgs);
if (id == VB_ITEM00_DESPAWN) {
EnItem00* item00 = va_arg(args, EnItem00*);
// Heart pieces and small keys are handled by default non-freestanding shuffles.
if (item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY) {
return;
}
uint32_t params = TWO_ACTOR_PARAMS((int32_t)item00->actor.world.pos.x, (int32_t)item00->actor.world.pos.z);
Rando::Location* loc = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params);
uint8_t isDungeon = loc->IsDungeon();
uint8_t freestandingSetting =
Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FREESTANDING).GetContextOptionIndex();
RandomizerCheck randomizerCheck = loc->GetRandomizerCheck();
bool checkObtained = Rando::Context::GetInstance()->GetItemLocation(randomizerCheck)->HasObtained();
// Don't change to randomized item if current freestanding item isn't shuffled or already obtained.
if ((freestandingSetting == RO_SHUFFLE_FREESTANDING_OVERWORLD && isDungeon) ||
(freestandingSetting == RO_SHUFFLE_FREESTANDING_DUNGEONS && !isDungeon) ||
checkObtained || randomizerCheck == RC_UNKNOWN_CHECK) {
return;
}
item00->randoInf = static_cast<RandomizerInf>(loc->GetCollectionCheck().flag);
item00->randoCheck = randomizerCheck;
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(randomizerCheck, true);
item00->actor.params = ITEM00_SOH_DUMMY;
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
*should = false;
}
}

View File

@ -0,0 +1,9 @@
#ifndef SHUFFLE_FREESTANDING_H
#define SHUFFLE_FREESTANDING_H
#include <z64.h>
#include <soh/OTRGlobals.h>
void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs);
#endif

View File

@ -9,6 +9,7 @@
#include "soh/Enhancements/randomizer/fishsanity.h"
#include "soh/Enhancements/randomizer/static_data.h"
#include "soh/Enhancements/randomizer/ShufflePots.h"
#include "soh/Enhancements/randomizer/ShuffleFreestanding.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ImGuiUtils.h"
@ -878,39 +879,18 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break;
case VB_ITEM00_DESPAWN: {
EnItem00* item00 = va_arg(args, EnItem00*);
item00->randoInf = RAND_INF_MAX;
item00->randoCheck = RC_UNKNOWN_CHECK;
auto pos = item00->actor.world.pos;
uint32_t params = item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY ? item00->ogParams : TWO_ACTOR_PARAMS((int32_t)pos.x, (int32_t)pos.z);
Rando::Location* loc = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params);
if (loc && loc->GetRandomizerCheck() != RC_UNKNOWN_CHECK) {
auto ctx = Rando::Context::GetInstance();
bool freestanding_mode = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_FREESTANDING_ALL);
if (!freestanding_mode) {
if (loc->IsOverworld()) {
freestanding_mode = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_FREESTANDING_OVERWORLD);
} else {
freestanding_mode = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_FREESTANDING_DUNGEONS);
}
}
// Spawn vanilla item if collected and renewable
if (
(freestanding_mode || item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY) &&
(loc->GetCollectionCheck().type != SPOILER_CHK_RANDOMIZER_INF || !Rando::Context::GetInstance()->GetItemLocation(loc->GetRandomizerCheck())->HasObtained())
) {
item00->randoCheck = loc->GetRandomizerCheck();
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(loc->GetRandomizerCheck(), true);
if (item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY) {
RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(
item00->actor.id, gPlayState->sceneNum, item00->ogParams);
if (rc != RC_UNKNOWN_CHECK) {
item00->actor.params = ITEM00_SOH_DUMMY;
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(
rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem());
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
if (loc->GetCollectionCheck().type == SPOILER_CHK_RANDOMIZER_INF) {
item00->randoInf = static_cast<RandomizerInf>(loc->GetCollectionCheck().flag);
*should = Rando::Context::GetInstance()->GetItemLocation(rc)->HasObtained();
}
*should = Rando::Context::GetInstance()->GetItemLocation(loc->GetRandomizerCheck())->HasObtained();
}
} else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY || item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) {
} else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY ||
item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) {
GetItemEntry itemEntry = randomizerQueuedItemEntry;
item00->itemEntry = itemEntry;
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
@ -2364,6 +2344,8 @@ void RandomizerRegisterHooks() {
static uint32_t shufflePotsOnActorInitHook = 0;
static uint32_t shufflePotsOnVanillaBehaviorHook = 0;
static uint32_t shuffleFreestandingOnVanillaBehaviorHook = 0;
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
randomizerQueuedChecks = std::queue<RandomizerCheck>();
randomizerQueuedCheck = RC_UNKNOWN_CHECK;
@ -2395,6 +2377,8 @@ void RandomizerRegisterHooks() {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(shufflePotsOnActorInitHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(shufflePotsOnVanillaBehaviorHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(shuffleFreestandingOnVanillaBehaviorHook);
onFlagSetHook = 0;
onSceneFlagSetHook = 0;
onPlayerUpdateForRCQueueHook = 0;
@ -2421,6 +2405,8 @@ void RandomizerRegisterHooks() {
shufflePotsOnActorInitHook = 0;
shufflePotsOnVanillaBehaviorHook = 0;
shuffleFreestandingOnVanillaBehaviorHook = 0;
ShuffleFairies_UnregisterHooks();
if (!IS_RANDO) return;
@ -2466,6 +2452,10 @@ void RandomizerRegisterHooks() {
shufflePotsOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(ShufflePots_OnVanillaBehaviorHandler);
}
if (RAND_GET_OPTION(RSK_SHUFFLE_FREESTANDING) != RO_SHUFFLE_FREESTANDING_OFF) {
shuffleFreestandingOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(ShuffleFreestanding_OnVanillaBehaviorHandler);
}
if (RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES)) {
ShuffleFairies_RegisterHooks();
}

View File

@ -1826,13 +1826,13 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1458), "MQ Basement Sun's Song Fairy", "MQ Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY));
// Freestanding Hearts and Rupees
locationTable[RC_KF_BOULDER_RUPEE_2] = Location::Collectable(RC_KF_BOULDER_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-712, 1857), 0x0E, "Boulder Maze Second Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_KF_BOULDER_RUPEE_1] = Location::Collectable(RC_KF_BOULDER_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-1009, 1556), 0x0F, "Boulder Maze First Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_KF_BRIDGE_RUPEE] = Location::Collectable(RC_KF_BRIDGE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(2, -45), 0x11, "Bridge Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_KF_BEHIND_MIDOS_RUPEE] = Location::Collectable(RC_KF_BEHIND_MIDOS_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-364, -783), 0x12, "Behind Mido's House Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_KF_SARIAS_ROOF_WEST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_WEST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(451, 810), 0x1C, "Saria's Roof West Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART);
locationTable[RC_KF_SARIAS_ROOF_EAST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_EAST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(567, 819), 0x1D, "Saria's Roof East Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART);
locationTable[RC_KF_SARIAS_ROOF_NORTH_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_NORTH_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(509, 725), 0x1E, "Saria's Roof North Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART);
locationTable[RC_KF_BOULDER_RUPEE_2] = Location::Collectable(RC_KF_BOULDER_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-712, 1857), "Boulder Maze Second Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BOULDER_RUPEE_2));
locationTable[RC_KF_BOULDER_RUPEE_1] = Location::Collectable(RC_KF_BOULDER_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-1009, 1556), "Boulder Maze First Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BOULDER_RUPEE_1));
locationTable[RC_KF_BRIDGE_RUPEE] = Location::Collectable(RC_KF_BRIDGE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(2, -45), "Bridge Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BRIDGE_RUPEE));
locationTable[RC_KF_BEHIND_MIDOS_RUPEE] = Location::Collectable(RC_KF_BEHIND_MIDOS_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-364, -783), "Behind Mido's House Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEHIND_MIDOS_RUPEE));
locationTable[RC_KF_SARIAS_ROOF_WEST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_WEST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(451, 810), "Saria's Roof West Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_ROOF_WEST_HEART));
locationTable[RC_KF_SARIAS_ROOF_EAST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_EAST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(567, 819), "Saria's Roof East Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_ROOF_EAST_HEART));
locationTable[RC_KF_SARIAS_ROOF_NORTH_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_NORTH_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(509, 725), "Saria's Roof North Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_ROOF_NORTH_HEART));
locationTable[RC_KF_SOUTH_GRASS_WEST_RUPEE] = Location::Collectable(RC_KF_SOUTH_GRASS_WEST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-537, 194), "South Grass West Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE));
locationTable[RC_KF_NORTH_GRASS_WEST_RUPEE] = Location::Collectable(RC_KF_NORTH_GRASS_WEST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(35, -418), "North Grass West Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_NORTH_GRASS_WEST_RUPEE));
locationTable[RC_KF_NORTH_GRASS_EAST_RUPEE] = Location::Collectable(RC_KF_NORTH_GRASS_EAST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(107, -418), "North Grass East Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_NORTH_GRASS_EAST_RUPEE));
@ -1863,9 +1863,9 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_LH_FRONT_RUPEE] = Location::Collectable(RC_LH_FRONT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-940, 3968), "Underwater Front Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_FRONT_RUPEE));
locationTable[RC_LH_MIDDLE_RUPEE] = Location::Collectable(RC_LH_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-868, 4090), "Underwater Middle Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_MIDDLE_RUPEE));
locationTable[RC_LH_BACK_RUPEE] = Location::Collectable(RC_LH_BACK_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-861, 4212), "Underwater Back Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BACK_RUPEE));
locationTable[RC_LH_LAB_FRONT_RUPEE] = Location::Collectable(RC_LH_LAB_FRONT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(68, -207), 0x01, "Lab Front Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE);
locationTable[RC_LH_LAB_LEFT_RUPEE] = Location::Collectable(RC_LH_LAB_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-52, -32), 0x02, "Lab Left Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE);
locationTable[RC_LH_LAB_RIGHT_RUPEE] = Location::Collectable(RC_LH_LAB_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-169, -124), 0x03, "Lab Right Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE);
locationTable[RC_LH_LAB_FRONT_RUPEE] = Location::Collectable(RC_LH_LAB_FRONT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(68, -207), "Lab Front Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_FRONT_RUPEE));
locationTable[RC_LH_LAB_LEFT_RUPEE] = Location::Collectable(RC_LH_LAB_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-52, -32), "Lab Left Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_LEFT_RUPEE));
locationTable[RC_LH_LAB_RIGHT_RUPEE] = Location::Collectable(RC_LH_LAB_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-169, -124), "Lab Right Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_RIGHT_RUPEE));
locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_1] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(385, -2766), "Dampe's Grave Rupee 1", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1));
locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_2] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(528, -3216), "Dampe's Grave Rupee 2", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2));
@ -1885,8 +1885,8 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 784), "Octorok Grotto Back Right Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE));
locationTable[RC_GV_OCTOROK_GROTTO_RED_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(32, 852), "Octorok Grotto Red Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE));
locationTable[RC_DMT_RED_RUPEE] = Location::Collectable(RC_DMT_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-625, -55), 0x0A, "Red Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_RED_RUPEE);
locationTable[RC_DMT_BLUE_RUPEE] = Location::Collectable(RC_DMT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1060, -51), 0x07, "Blue Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_DMT_RED_RUPEE] = Location::Collectable(RC_DMT_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-625, -55), "Red Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_RED_RUPEE));
locationTable[RC_DMT_BLUE_RUPEE] = Location::Collectable(RC_DMT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1060, -51), "Blue Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BLUE_RUPEE));
locationTable[RC_DMT_COW_GROTTO_LEFT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2287, -412), "Cow Grotto Left Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_LEFT_HEART));
locationTable[RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2371, -532), "Cow Grotto Middle Left Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART));
locationTable[RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2449, -534), "Cow Grotto Middle Right Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART));
@ -1945,7 +1945,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-820, -76), "Final Room Left Back Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART));
locationTable[RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-354, -206), "Final Room Right Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART));
locationTable[RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), 0x18, "Lower Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART);
locationTable[RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), "Lower Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART));
locationTable[RC_DODONGOS_CAVERN_BLADE_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2039, -317), "Blade Room Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART));
locationTable[RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3553, -1962), "Upper Lizalfos Room Left Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART));
locationTable[RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3580, -2004), "Upper Lizalfos Room Right Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART));
@ -1978,15 +1978,15 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3473, -927), "After Ship Upper Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART));
locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3164, -646), "After Ship Lower Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART));
locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(708, 227), 0x01, "Adult Climb Left Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART);
locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(661, 227), 0x02, "Adult Climb Right Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART);
locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(708, 227), "Adult Climb Left Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART));
locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(661, 227), "Adult Climb Right Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART));
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-67, -748), 0x05, "Basement Platform Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-19, -828), 0x06, "Basement Platform Back Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(47, -805), 0x02, "Basement Platform Middle Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(94, -762), 0x03, "Basement Platform Back Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-85, -710), 0x04, "Basement Platform Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE);
locationTable[RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-1947, -625), 0x1F, "Coffin Room Front Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART);
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-67, -748), "Basement Platform Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE));
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-19, -828), "Basement Platform Back Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE));
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(47, -805), "Basement Platform Middle Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE));
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(94, -762), "Basement Platform Back Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE));
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-85, -710), "Basement Platform Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE));
locationTable[RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-1947, -625), "Coffin Room Front Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART));
locationTable[RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-2144, -859), "Coffin Room Middle Right Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART));
locationTable[RC_ICE_CAVERN_LOBBY_RUPEE] = Location::Collectable(RC_ICE_CAVERN_LOBBY_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-105, 854), "Lobby Rupee", RHT_ICE_CAVERN_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_RUPEE));
@ -2014,12 +2014,12 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-820, -76), "MQ Final Room Left Back Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART));
locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-354, -206), "MQ Final Room Right Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART));
locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), 0x18, "MQ Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART);
locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), "MQ Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART));
locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1955, -596), "MQ Torch Room Invisible Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART));
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-390, -1695), 0x01, "MQ Lift Room Underwater Rupee 1", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE);
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-487, -1701), 0x02, "MQ Lift Room Underwater Rupee 2", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE);
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-549, -1709), 0x03, "MQ Lift Room Underwater Rupee 3", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE);
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-390, -1695), "MQ Lift Room Underwater Rupee 1", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1));
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-487, -1701), "MQ Lift Room Underwater Rupee 2", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2));
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-549, -1709), "MQ Lift Room Underwater Rupee 3", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3));
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-217, -1620), "MQ Lift Room Heart 1", RHT_JABU_JABU_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1));
locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-206, -1797), "MQ Lift Room Heart 2", RHT_JABU_JABU_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2));

View File

@ -5625,10 +5625,10 @@ typedef enum {
//Freestanding Hearts/Rupees settings (off, dungeons, overworld, all)
typedef enum {
RO_FREESTANDING_OFF,
RO_FREESTANDING_DUNGEONS,
RO_FREESTANDING_OVERWORLD,
RO_FREESTANDING_ALL,
RO_SHUFFLE_FREESTANDING_OFF,
RO_SHUFFLE_FREESTANDING_DUNGEONS,
RO_SHUFFLE_FREESTANDING_OVERWORLD,
RO_SHUFFLE_FREESTANDING_ALL,
} RandoOptionFreestanding;
// Shuffle Pots settings (off, dungeons, overworld, all)

View File

@ -164,10 +164,10 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == RO_TOKENSANITY_DUNGEONS) &&
RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) &&
(location.GetRCType() != RCTYPE_FREESTANDING ||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_FREESTANDING_OFF) == RO_FREESTANDING_ALL) ||
((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_FREESTANDING_OFF) == RO_FREESTANDING_OVERWORLD) &&
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_ALL) ||
((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_OVERWORLD) &&
RandomizerCheckObjects::AreaIsOverworld(location.GetArea())) ||
((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_FREESTANDING_OFF) == RO_FREESTANDING_DUNGEONS) &&
((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_DUNGEONS) &&
RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) &&
(location.GetRCType() != RCTYPE_BEEHIVE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_COW || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_NO)) &&

View File

@ -1261,15 +1261,15 @@ void LoadSettings() {
if (IS_RANDO) {
switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FREESTANDING)) {
case RO_FREESTANDING_ALL:
case RO_SHUFFLE_FREESTANDING_ALL:
showOverworldFreestanding = true;
showDungeonFreestanding = true;
break;
case RO_FREESTANDING_OVERWORLD:
case RO_SHUFFLE_FREESTANDING_OVERWORLD:
showOverworldFreestanding = true;
showDungeonFreestanding = false;
break;
case RO_FREESTANDING_DUNGEONS:
case RO_SHUFFLE_FREESTANDING_DUNGEONS:
showOverworldFreestanding = false;
showDungeonFreestanding = true;
break;

View File

@ -851,6 +851,13 @@ typedef enum {
RAND_INF_CHILD_TRADES_MASK_GERUDO,
RAND_INF_CHILD_TRADES_MASK_TRUTH,
RAND_INF_KF_BOULDER_RUPEE_2,
RAND_INF_KF_BOULDER_RUPEE_1,
RAND_INF_KF_BRIDGE_RUPEE,
RAND_INF_KF_BEHIND_MIDOS_RUPEE,
RAND_INF_KF_SARIAS_ROOF_WEST_HEART,
RAND_INF_KF_SARIAS_ROOF_EAST_HEART,
RAND_INF_KF_SARIAS_ROOF_NORTH_HEART,
RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE,
RAND_INF_KF_NORTH_GRASS_WEST_RUPEE,
RAND_INF_KF_NORTH_GRASS_EAST_RUPEE,
@ -877,6 +884,9 @@ typedef enum {
RAND_INF_LH_FRONT_RUPEE,
RAND_INF_LH_MIDDLE_RUPEE,
RAND_INF_LH_BACK_RUPEE,
RAND_INF_LH_LAB_FRONT_RUPEE,
RAND_INF_LH_LAB_LEFT_RUPEE,
RAND_INF_LH_LAB_RIGHT_RUPEE,
RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1,
RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2,
RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3,
@ -895,6 +905,7 @@ typedef enum {
RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE,
RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE,
RAND_INF_DMT_RED_RUPEE,
RAND_INF_DMT_BLUE_RUPEE,
RAND_INF_DMT_COW_GROTTO_LEFT_HEART,
RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART,
@ -907,6 +918,7 @@ typedef enum {
RAND_INF_DMT_COW_GROTTO_RUPEE_5,
RAND_INF_DMT_COW_GROTTO_RUPEE_6,
RAND_INF_DMT_COW_GROTTO_RED_RUPEE,
RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE,
RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE,
RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1,
@ -951,6 +963,7 @@ typedef enum {
RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART,
RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART,
RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART,
RAND_INF_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART,
RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART,
RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART,
RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART,
@ -978,6 +991,8 @@ typedef enum {
RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART,
RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART,
RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART,
RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART,
RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART,
RAND_INF_ICE_CAVERN_LOBBY_RUPEE,
RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART,
RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART,
@ -985,6 +1000,12 @@ typedef enum {
RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1,
RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2,
RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3,
RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE,
RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE,
RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE,
RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE,
RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE,
RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART,
RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART,
RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART,
RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART,
@ -1001,7 +1022,11 @@ typedef enum {
RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART,
RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART,
RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART,
RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART,
RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART,
RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1,
RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2,
RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3,
RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1,
RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2,
RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART,

View File

@ -221,7 +221,7 @@ void Settings::CreateOptions() {
mOptions[RSK_SHUFFLE_BOSS_SOULS] = Option::U8("Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox);
mOptions[RSK_SHUFFLE_DEKU_STICK_BAG] = Option::Bool("Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
mOptions[RSK_SHUFFLE_DEKU_NUT_BAG] = Option::Bool("Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
mOptions[RSK_SHUFFLE_FREESTANDING] = Option::U8("Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WidgetType::Combobox, RO_FREESTANDING_OFF);
mOptions[RSK_SHUFFLE_FREESTANDING] = Option::U8("Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WidgetType::Combobox, RO_SHUFFLE_FREESTANDING_OFF);
mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF);
mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE);
mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]);