Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potfreefairy #35

Open
wants to merge 60 commits into
base: potsanity_v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
ed92bb7
Enable freestanding items other than heart pieces and keys
boomshroom Aug 8, 2024
edcf859
Add option to disable freestanding rupee & heart shuffle
boomshroom Aug 8, 2024
a535f59
Add items to pool
boomshroom Aug 8, 2024
fb8e2bd
Actually add shuffle setting
boomshroom Aug 8, 2024
9c3827e
Define overworld locations
boomshroom Aug 8, 2024
f5bf045
Add logic for overworld freestanding checks
boomshroom Aug 8, 2024
0cac9ca
Add freestanding items for child dungeons.
boomshroom Aug 8, 2024
169580e
Add checks for Ice Cavern and Bottom of the Well
boomshroom Aug 13, 2024
ae17244
Add checks for Forest Temple and Gerudo Training Grounds
boomshroom Aug 14, 2024
2a58e47
Add checks for Fire Temple and Water Temple
boomshroom Aug 14, 2024
2f463c1
Add Shadow Temple checks
boomshroom Aug 15, 2024
ead0bba
Define Spirit Temple and Ganon's Castle hearts
boomshroom Aug 15, 2024
f8c438e
Add remaining checks to dungeon definitions
boomshroom Aug 15, 2024
00b8c86
Fix missing logic
boomshroom Aug 15, 2024
5ec64f8
Merge remote-tracking branch 'origin/develop-rando' into shuffle_free…
boomshroom Aug 15, 2024
066004a
Add freestanding checks to Save Flags Editor
boomshroom Aug 16, 2024
7affcb4
Fix flags for Zora Fountain underwater rupees
boomshroom Aug 16, 2024
0075f26
Add option to enable freestanding shuffle for either dungeons or over…
boomshroom Aug 16, 2024
6dfb5c7
Add missing MQ checks and fix mac & windows compile error
boomshroom Aug 16, 2024
bcc10ea
Improve description and add hint text
boomshroom Aug 16, 2024
56a8f2d
Merge remote-tracking branch 'origin/develop-rando' into shuffle_free…
boomshroom Aug 18, 2024
298cec2
Update logic for Bombchu fixes
boomshroom Aug 18, 2024
54cc685
Merge remote-tracking branch 'origin/develop-rando' into shuffle_free…
boomshroom Aug 23, 2024
1e9092c
Add missing Spirit Temple MQ hearts
boomshroom Aug 23, 2024
5819cd4
Add missing settings entries
boomshroom Aug 28, 2024
e430514
Merge remote-tracking branch 'origin/develop-rando' into shuffle_free…
boomshroom Aug 29, 2024
b50d14d
Actually add Forest Temple trick to the tricks menu.
boomshroom Aug 29, 2024
1f85420
Additions for the German translation in two files (#4304)
Extloga Sep 2, 2024
075b28c
Define VB for fairy group spawning
boomshroom Sep 4, 2024
a263d45
Add skeleton of new files for fairy shuffle
boomshroom Sep 4, 2024
792515d
Add option to enable/disable fairy shuffle
boomshroom Sep 4, 2024
e655f2e
Add field to fairy entities to hold randomizer data
boomshroom Sep 4, 2024
59222c8
Expose the current grotto id, or find it if not shuffled
boomshroom Sep 5, 2024
987f4ce
Initialise fairy groups if detected
boomshroom Sep 5, 2024
d4f2c0d
Randomize first set of fairies
boomshroom Sep 5, 2024
8d13e1d
Make randomized fairies collectible
boomshroom Sep 5, 2024
3c9bc5f
VBify fairy healing customization
boomshroom Sep 5, 2024
0e5c64b
Add remaining grotto fairies
boomshroom Sep 5, 2024
e1df531
Add remaining fairy group spawns
boomshroom Sep 5, 2024
e1d1557
Override bean sprouts spawning fairies
boomshroom Sep 6, 2024
96055ff
Define bean sprout fairy checks
boomshroom Sep 6, 2024
41d10c3
Add HasItem and CanUse entries for magic beans.
boomshroom Sep 6, 2024
1598ce3
Define logic for bean sprout fairies
boomshroom Sep 6, 2024
12c4bb4
Enabling looking up fairies by z coordinate
boomshroom Sep 6, 2024
fb5e1bc
Add Temple of Time Gossip Stones
boomshroom Sep 6, 2024
3552242
Disable quick age change around gossip stones to simplify logic
boomshroom Sep 7, 2024
16da42c
Add remaining gossip stone fairies
boomshroom Sep 8, 2024
4e4fa63
Finish gossip stone fairies
boomshroom Sep 9, 2024
174554c
Add Desert Colossus Oasis
boomshroom Sep 10, 2024
d5dc2bd
Restrict fairy type
boomshroom Sep 10, 2024
0e83131
Add overworld special fairy spots
boomshroom Sep 12, 2024
d31b791
Add mini-dungeon fairy song spots
boomshroom Sep 13, 2024
727202c
Add remaining dungeons except Shadow
boomshroom Sep 13, 2024
97d2acc
Add Shadow Temple fairies
boomshroom Sep 13, 2024
ac0dd73
Add fairy check flags to the save editor
boomshroom Sep 13, 2024
ffb5e8e
Filter fairy checks from check tracker
boomshroom Sep 13, 2024
8356a3a
Add hints for fairy checks
boomshroom Sep 14, 2024
702578a
freestanding_shuffle merge
Caladius Sep 19, 2024
cf26087
Fairy Shuffle Merge
Caladius Sep 20, 2024
59351bc
Fairy Shuffle
Caladius Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion soh/include/z64actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ typedef struct EnItem00 {
/* 0x15C */ f32 scale;
/* 0x160 */ ColliderCylinder collider;
// #region SOH [Randomizer]
GetItemEntry randoGiEntry;
RandomizerCheck randoCheck;
RandomizerInf randoInf;
/* */ s16 ogParams;
Expand Down
2 changes: 1 addition & 1 deletion soh/include/z64save.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ typedef struct {
// #endregion
// #region SOH [Randomizer]
// Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer
/* */ u16 randomizerInf[RAND_INF_MAX / 16];
/* */ u16 randomizerInf[(RAND_INF_MAX + 15) / 16];
/* */ u8 mqDungeonCount;
/* */ u16 adultTradeItems;
/* */ u8 triforcePiecesCollected;
Expand Down
390 changes: 389 additions & 1 deletion soh/soh/Enhancements/debugger/debugSaveEditor.h

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions soh/soh/Enhancements/game-interactor/GameInteractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,14 @@ typedef enum {
// Vanilla condition: true
VB_PHANTOM_GANON_DEATH_SCENE,
VB_NABOORU_KNUCKLE_DEATH_SCENE,

/*** Fairy Shuffle ***/
// Opt: *EnElf
VB_SPAWN_FAIRY_GROUP,
// Opt: *EnElf
VB_FAIRY_HEAL,
// Opt: *ObjBean
VB_BEAN_SPAWN_FAIRIES,
} GIVanillaBehavior;

#ifdef __cplusplus
Expand Down
27 changes: 26 additions & 1 deletion soh/soh/Enhancements/mods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h"
#include "src/overlays/actors/ovl_En_Door/z_en_door.h"
#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "objects/object_link_boy/object_link_boy.h"
#include "objects/object_link_child/object_link_child.h"

Expand Down Expand Up @@ -274,13 +275,14 @@ void RegisterOcarinaTimeTravel() {
Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f);
Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f);
Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f);
Actor* nearbyGossipStone = Actor_FindNearby(gPlayState, player, ACTOR_EN_GS, ACTORCAT_NPC, 300.0f);
uint8_t hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
uint8_t hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
// If TimeTravel + Player have the Ocarina of Time + Have Master Sword + is in proper range
// TODO: Once Swordless Adult is fixed: Remove the Master Sword check
if (((CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 1 && hasOcarinaOfTime) || CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2) && hasMasterSword &&
gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock &&
!nearbyOcarinaSpot && !nearbyFrogs) {
!nearbyOcarinaSpot && !nearbyFrogs && !nearbyGossipStone) {

if (IS_RANDO) {
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1);
Expand Down Expand Up @@ -1779,6 +1781,28 @@ void RegisterSkeletonKey() {
});
}

#define FAIRY_FLAG_BIG (1 << 9)
void RegisterFairyCustomization() {
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_FAIRY_HEAL, [](GIVanillaBehavior id, bool* should, void* refActor) {
EnElf* enElf = static_cast<EnElf*>(refActor);
// Don't trigger if fairy is shuffled
if (!IS_RANDO || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) || enElf->sohFairyIdentity.randomizerInf == RAND_INF_MAX) {
if (CVarGetInteger(CVAR_ENHANCEMENT("FairyEffect"), 0) && !(enElf->fairyFlags & FAIRY_FLAG_BIG))
{
if (CVarGetInteger(CVAR_ENHANCEMENT("FairyPercentRestore"), 0))
{
Health_ChangeBy(gPlayState, (gSaveContext.healthCapacity * CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 100) / 100 + 15) / 16 * 16);
}
else
{
Health_ChangeBy(gPlayState, CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 8) * 16);
}
*should = false;
}
}
});
}

void InitMods() {
RandomizerRegisterHooks();
TimeSaverRegisterHooks();
Expand Down Expand Up @@ -1830,4 +1854,5 @@ void InitMods() {
RegisterPauseMenuHooks();
RegisterSkeletonKey();
RegisterShufflePots();
RegisterFairyCustomization();
}
2 changes: 2 additions & 0 deletions soh/soh/Enhancements/randomizer/3drando/category.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ enum class Category {
cAdultTrade,
cPot,
cBeehive,
cFreestanding,
cFairy,
};

enum class OptionCategory {
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

119 changes: 119 additions & 0 deletions soh/soh/Enhancements/randomizer/3drando/item_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,102 @@ static void PlaceVanillaOverworldFish() {
}
}

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

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

static void PlaceVanillaFairies() {
auto ctx = Rando::Context::GetInstance();
for (auto rc : Rando::StaticData::overworldFairyLocations) {
ctx->PlaceItemInLocation(rc, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) {
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::WATER_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ()) {
ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, GetJunkItem(), false, true);
ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, GetJunkItem(), false, true);
} else {
ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla()) {
ctx->PlaceItemInLocation(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->IsVanilla()) {
ctx->PlaceItemInLocation(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, GetJunkItem(), false, true);
}
if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla()) {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, GetJunkItem(), false, true);
}
}

static void SetScarceItemPool() {
ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 3);
ReplaceMaxItem(RG_BOMBCHU_5, 1);
Expand Down Expand Up @@ -1192,6 +1288,27 @@ void GenerateItemPool() {
AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees
}

//Fairysanity
if (ctx->GetOption(RSK_SHUFFLE_FAIRIES)) {
for (auto rc : Rando::StaticData::overworldFairyLocations) {
AddItemToMainPool(GetJunkItem());
}
// 8 extra for Ganon's Castle + 2 Dodongo's Cavern Gossip Stone + 3 Shadow Temple
int extra = 13;
extra += ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla() ? 0 : 2;
extra += ctx->GetDungeon(Rando::WATER_TEMPLE)->IsVanilla() ? 0 : 3;
extra += ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsVanilla() ? 2 : 1;
extra += ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() ? 1 : 2;
extra += ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla() ? 1 : 0;
extra += ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->IsVanilla() ? 1 : 0;
extra += ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla() ? 1 : 0;
for (int i = 0; i < extra; i++) {
AddItemToMainPool(GetJunkItem());
}
} else {
PlaceVanillaFairies();
}

//Scrubsanity
if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).IsNot(RO_SCRUBS_OFF)) {
//Deku Tree
Expand Down Expand Up @@ -1236,6 +1353,8 @@ void GenerateItemPool() {
PlaceVanillaDekuScrubItems();
}

PlaceFreestandingItems();

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ void AreaTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, logic->CanBreakPots),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, logic->CanBreakPots),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, logic->CanBreakPots),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_ZELDAS_LULLABY)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))),
LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_ZELDAS_LULLABY)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))),
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}),
Expand All @@ -81,6 +89,14 @@ void AreaTable_Init_BottomOfTheWell() {
//Trick: logic->HasExplosives || (LogicBotWMQDeadHandKey && logic->Boomerang)
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanChildAttack),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanChildAttack && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, true),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, true),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, true),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}),
Expand All @@ -95,6 +111,7 @@ void AreaTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, true),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->CanChildAttack && (randoCtx->GetTrickOption(RT_BOTW_MQ_PITS) || logic->HasExplosives)),
//Trick: logic->CanChildAttack && (LogicBotWMQPits || logic->HasExplosives)
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ void AreaTable_Init_CastleTown() {
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}),
}, {
//Locations
LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, logic->CanSummonGossipFairyWithoutSuns || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, logic->CanSummonGossipFairyWithoutSuns || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, logic->CanSummonGossipFairyWithoutSuns || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, logic->CanSummonGossipFairyWithoutSuns || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)),
LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE, true),
LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE, true),
LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, true),
Expand Down Expand Up @@ -89,6 +97,10 @@ void AreaTable_Init_CastleTown() {
//Locations
LOCATION(RC_HC_MALON_EGG, true),
LOCATION(RC_HC_GS_TREE, logic->CanChildAttack),
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CanSummonGossipFairy),
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CanSummonGossipFairy),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_MALON_GOSSIP_STONE, true),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true),
}, {
Expand Down Expand Up @@ -126,6 +138,8 @@ void AreaTable_Init_CastleTown() {
}, {
//Locations
LOCATION(RC_HC_GS_STORMS_GROTTO, (logic->CanBlastOrSmash && logic->HookshotOrBoomerang) || (logic->Boomerang && randoCtx->GetTrickOption(RT_HC_STORMS_GS))),
LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CanBlastOrSmash && logic->CanSummonGossipFairy),
LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanBlastOrSmash && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, logic->CanBlastOrSmash),
LOCATION(RC_HC_STORMS_GROTTO_POT_1, logic->CanBlastOrSmash && logic->CanBreakPots),
LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBlastOrSmash && logic->CanBreakPots),
Expand Down
Loading
Loading