Bombchu logic fixes, Add BetterBombchShopping enhancment and some adjacent cleanups (#3733)

* Initial Bombchu rework implementation

* Finish bombchus in logic overhaul

* address reviews

* Post resolution fixes

* fix git being dumb

* Readd Child Wallet To Bombchu Bowling Logic

* post merge fixes

* fix some oversights in bombchu shopping logic

* doesn't work, linker errors

* cleanup old reviews

* Make it build, likely broken by VB

* attempt to fix carpet man second purchse text

* commit to change branch

* mostly have carpet guy working

* badly fix carpet salesman

* fix better bombchu shopping

* fix bombchu drops

* remember you need bombchus in inventory to get drops

* Address reviews

* post-SCL clean up and redo the bombchu ammo logic to apply better to the spirit edge case

* fix oversight which could have allowed for bombchus to logical exist when they shouldn't

* Remove special bombchu playthrough checks which are causing bugs and no longer needed

* fix Slingshot logic reset

* Convert helpers I touched into CanUse and HasItem

* last cleanups
This commit is contained in:
Pepper0ni 2024-08-18 00:10:11 +01:00 committed by GitHub
parent d3edbcd042
commit 9c2e773ce4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 521 additions and 414 deletions

1
.gitignore vendored
View File

@ -41,6 +41,7 @@ tools/asmsplitter/c/*
ctx.c ctx.c
tools/*dSYM/ tools/*dSYM/
graphs/ graphs/
.netcoredbg_hist
# Assets # Assets
*.png *.png

View File

@ -15,10 +15,10 @@ typedef enum {
TEXT_CHEST_GAME_REAL_GAMBLER = 0x006E, TEXT_CHEST_GAME_REAL_GAMBLER = 0x006E,
TEXT_ITEM_COMPASS = 0x0067, TEXT_ITEM_COMPASS = 0x0067,
TEXT_CHEST_GAME_THANKS_A_LOT = 0x0084, TEXT_CHEST_GAME_THANKS_A_LOT = 0x0084,
TEXT_BUY_BOMBCHU_10_PROMPT = 0x008C, TEXT_BUY_BOMBCHUS_10_PROMPT = 0x008C,
TEXT_GS_NO_FREEZE = 0x00B4, TEXT_GS_NO_FREEZE = 0x00B4,
TEXT_GS_FREEZE = 0x00B5, TEXT_GS_FREEZE = 0x00B5,
TEXT_BUY_BOMBCHU_10_DESC = 0x00BC, TEXT_BUY_BOMBCHUS_10_DESC = 0x00BC,
TEXT_HEART_PIECE = 0x00C2, TEXT_HEART_PIECE = 0x00C2,
TEXT_HEART_CONTAINER = 0x00C6, TEXT_HEART_CONTAINER = 0x00C6,
TEXT_ITEM_KEY_BOSS = 0x00C7, TEXT_ITEM_KEY_BOSS = 0x00C7,
@ -161,6 +161,7 @@ typedef enum {
TEXT_HBA_INITIAL_EXPLAINATION = 0x6040, TEXT_HBA_INITIAL_EXPLAINATION = 0x6040,
TEXT_HBA_WANT_TO_TRY_AGAIN_YES_NO = 0x6041, TEXT_HBA_WANT_TO_TRY_AGAIN_YES_NO = 0x6041,
TEXT_HBA_ALREADY_HAVE_1000 = 0x6042, TEXT_HBA_ALREADY_HAVE_1000 = 0x6042,
TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY = 0x6073,
TEXT_CARPET_SALESMAN_1 = 0x6077, TEXT_CARPET_SALESMAN_1 = 0x6077,
TEXT_CARPET_SALESMAN_2 = 0x6078, TEXT_CARPET_SALESMAN_2 = 0x6078,
TEXT_MARKET_GUARD_NIGHT = 0x7003, TEXT_MARKET_GUARD_NIGHT = 0x7003,

View File

@ -313,6 +313,7 @@ typedef enum {
VB_GIVE_ITEM_FROM_GORON, VB_GIVE_ITEM_FROM_GORON,
// Opt: *EnJs // Opt: *EnJs
VB_GIVE_ITEM_FROM_CARPET_SALESMAN, VB_GIVE_ITEM_FROM_CARPET_SALESMAN,
VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN,
// Opt: *EnGm // Opt: *EnGm
VB_GIVE_ITEM_FROM_MEDIGORON, VB_GIVE_ITEM_FROM_MEDIGORON,
// Opt: *EnMs // Opt: *EnMs

View File

@ -344,7 +344,7 @@ void AutoSave(GetItemEntry itemEntry) {
case ITEM_BOMBCHU: case ITEM_BOMBCHU:
case ITEM_BOMBCHUS_5: case ITEM_BOMBCHUS_5:
case ITEM_BOMBCHUS_20: case ITEM_BOMBCHUS_20:
if (!CVarGetInteger(CVAR_ENHANCEMENT("BombchuDrops"), 0)) { if (!CVarGetInteger(CVAR_ENHANCEMENT("EnableBombchuDrops"), 0)) {
performSave = true; performSave = true;
} }
break; break;

View File

@ -99,7 +99,7 @@ const std::vector<const char*> enhancementsCvars = {
CVAR_ENHANCEMENT("BonkDamageMult"), CVAR_ENHANCEMENT("BonkDamageMult"),
CVAR_ENHANCEMENT("NoRandomDrops"), CVAR_ENHANCEMENT("NoRandomDrops"),
CVAR_ENHANCEMENT("NoHeartDrops"), CVAR_ENHANCEMENT("NoHeartDrops"),
CVAR_ENHANCEMENT("BombchuDrops"), CVAR_ENHANCEMENT("EnableBombchuDrops"),
CVAR_ENHANCEMENT("GoronPot"), CVAR_ENHANCEMENT("GoronPot"),
CVAR_ENHANCEMENT("FullHealthSpawn"), CVAR_ENHANCEMENT("FullHealthSpawn"),
CVAR_ENHANCEMENT("DampeWin"), CVAR_ENHANCEMENT("DampeWin"),
@ -218,6 +218,7 @@ const std::vector<const char*> enhancementsCvars = {
CVAR_ENHANCEMENT("BowSlingshotAmmoFix"), CVAR_ENHANCEMENT("BowSlingshotAmmoFix"),
CVAR_ENHANCEMENT("BetterFarore"), CVAR_ENHANCEMENT("BetterFarore"),
CVAR_ENHANCEMENT("DisableFirstPersonChus"), CVAR_ENHANCEMENT("DisableFirstPersonChus"),
CVAR_ENHANCEMENT("BetterBombchuShopping"),
CVAR_ENHANCEMENT("HyperBosses"), CVAR_ENHANCEMENT("HyperBosses"),
CVAR_ENHANCEMENT("RupeeDash"), CVAR_ENHANCEMENT("RupeeDash"),
CVAR_ENHANCEMENT("RupeeDashInterval"), CVAR_ENHANCEMENT("RupeeDashInterval"),
@ -713,6 +714,9 @@ const std::vector<PresetEntry> enhancedPresetEntries = {
// Autosave // Autosave
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS),
// Bombchu shop doesn't sell out, and 10 bombchus cost 99 instead of 100
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterBombchuShopping"), 1),
}; };
const std::vector<PresetEntry> randomizerPresetEntries = { const std::vector<PresetEntry> randomizerPresetEntries = {

View File

@ -201,8 +201,8 @@ std::vector<RandomizerCheck> GetAllEmptyLocations() {
} }
bool IsBombchus(RandomizerGet item, bool includeShops = false){ bool IsBombchus(RandomizerGet item, bool includeShops = false){
return (item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_DROP) || item == RG_PROGRESSIVE_BOMBCHUS || return (item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS ||
(includeShops && (item == RG_BUY_BOMBCHU_10 || item == RG_BUY_BOMBCHU_20)); (includeShops && (item == RG_BUY_BOMBCHUS_10 || item == RG_BUY_BOMBCHUS_20));
} }
bool IsBeatableWithout(RandomizerCheck excludedCheck, bool replaceItem, RandomizerGet ignore = RG_NONE){ //RANDOTODO make excludCheck an ItemLocation bool IsBeatableWithout(RandomizerCheck excludedCheck, bool replaceItem, RandomizerGet ignore = RG_NONE){ //RANDOTODO make excludCheck an ItemLocation
@ -244,7 +244,6 @@ std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<Randomizer
//Variables for playthrough //Variables for playthrough
int gsCount = 0; int gsCount = 0;
const int maxGsCount = mode == SearchMode::GeneratePlaythrough ? GetMaxGSCount() : 0; //If generating playthrough want the max that's possibly useful, else doesn't matter const int maxGsCount = mode == SearchMode::GeneratePlaythrough ? GetMaxGSCount() : 0; //If generating playthrough want the max that's possibly useful, else doesn't matter
bool bombchusFound = false;
std::vector<LogicVal> buyIgnores; std::vector<LogicVal> buyIgnores;
//Variables for search //Variables for search
@ -384,29 +383,23 @@ std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<Randomizer
//Item is an advancement item, figure out if it should be added to this sphere //Item is an advancement item, figure out if it should be added to this sphere
if (!ctx->playthroughBeatable && location->GetPlacedItem().IsAdvancement()) { if (!ctx->playthroughBeatable && location->GetPlacedItem().IsAdvancement()) {
ItemType type = location->GetPlacedItem().GetItemType(); ItemType type = location->GetPlacedItem().GetItemType();
bool bombchus = IsBombchus(locItem, true); //Is a bombchu location
//Decide whether to exclude this location //Decide whether to exclude this location
//This preprocessing is done to reduce the amount of searches performed in PareDownPlaythrough //This preprocessing is done to reduce the amount of searches performed in PareDownPlaythrough
//Want to exclude: //Want to exclude:
//1) Tokens after the last potentially useful one (the last one that gives an advancement item or last for token bridge) //1) Tokens after the last potentially useful one (the last one that gives an advancement item or last for token bridge)
//2) Bombchus after the first (including buy bombchus) //2) Buy items of the same type, after the first (So only see Buy Deku Nut of any amount once)
//3) Buy items of the same type, after the first (So only see Buy Deku Nut of any amount once)
bool exclude = true; bool exclude = true;
//Exclude tokens after the last possibly useful one //Exclude tokens after the last possibly useful one
if (type == ITEMTYPE_TOKEN && gsCount < maxGsCount) { if (type == ITEMTYPE_TOKEN && gsCount < maxGsCount) {
gsCount++; gsCount++;
exclude = false; exclude = false;
} }
//Only print first bombchu location found
else if (bombchus && !bombchusFound) {
bombchusFound = true;
exclude = false;
}
//Handle buy items //Handle buy items
//If ammo drops are off, don't do this step, since buyable ammo becomes logically important //If ammo drops are off, don't do this step, since buyable ammo becomes logically important
// TODO: Reimplement Ammo Drops setting // TODO: Reimplement Ammo Drops setting
else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ !(bombchus && bombchusFound) && type == ITEMTYPE_SHOP) { else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ type == ITEMTYPE_SHOP) {
//Only check each buy item once //Only check each buy item once
auto buyItem = location->GetPlacedItem().GetLogicVal(); auto buyItem = location->GetPlacedItem().GetLogicVal();
//Buy item not in list to ignore, add it to list and write to playthrough //Buy item not in list to ignore, add it to list and write to playthrough
@ -416,7 +409,7 @@ std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<Randomizer
} }
} }
//Add all other advancement items //Add all other advancement items
else if (!bombchus && type != ITEMTYPE_TOKEN && (/*AmmoDrops.Is(AMMODROPS_NONE) ||*/ type != ITEMTYPE_SHOP)) { else if (type != ITEMTYPE_TOKEN && (/*AmmoDrops.Is(AMMODROPS_NONE) ||*/ type != ITEMTYPE_SHOP)) {
exclude = false; exclude = false;
} }
//Has not been excluded, add to playthrough //Has not been excluded, add to playthrough

View File

@ -1776,7 +1776,7 @@ void StaticData::HintTable_Init_Item() {
CustomMessage("plenty of blast balls", /*german*/"viele Explosionsbälle", /*french*/"une abondance de boules bleues")}); CustomMessage("plenty of blast balls", /*german*/"viele Explosionsbälle", /*french*/"une abondance de boules bleues")});
// /*spanish*/bastantes estallidos // /*spanish*/bastantes estallidos
hintTextTable[RHT_BOMBCHU_5] = HintText(CustomMessage("Bombchus (5 pieces)", /*german*/"Krabbelminen (5 Stück)", /*french*/"une demi-dizaine de Missiles"), hintTextTable[RHT_BOMBCHUS_5] = HintText(CustomMessage("Bombchus (5 pieces)", /*german*/"Krabbelminen (5 Stück)", /*french*/"une demi-dizaine de Missiles"),
// /*spanish*/unos (5) bombchus // /*spanish*/unos (5) bombchus
{ {
CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"),
@ -1793,7 +1793,7 @@ void StaticData::HintTable_Init_Item() {
CustomMessage("a few trail blazers", /*german*/"ein paar Vorreiter", /*french*/"une poignée de zigzags éclatants")}); CustomMessage("a few trail blazers", /*german*/"ein paar Vorreiter", /*french*/"une poignée de zigzags éclatants")});
// /*spanish*/un par de ratas propulsadas // /*spanish*/un par de ratas propulsadas
hintTextTable[RHT_BOMBCHU_10] = HintText(CustomMessage("Bombchus (10 pieces)", /*german*/"Krabbelminen (10 Stück)", /*french*/"une dizaine de Missiles"), hintTextTable[RHT_BOMBCHUS_10] = HintText(CustomMessage("Bombchus (10 pieces)", /*german*/"Krabbelminen (10 Stück)", /*french*/"une dizaine de Missiles"),
// /*spanish*/unos (10) bombchus // /*spanish*/unos (10) bombchus
{ {
CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"),
@ -1810,7 +1810,7 @@ void StaticData::HintTable_Init_Item() {
CustomMessage("some trail blazers", /*german*/"einige Vorreiter", /*french*/"un paquet de zigzags éclatants")}); CustomMessage("some trail blazers", /*german*/"einige Vorreiter", /*french*/"un paquet de zigzags éclatants")});
// /*spanish*/unas cuantas ratas propulsadas // /*spanish*/unas cuantas ratas propulsadas
hintTextTable[RHT_BOMBCHU_20] = HintText(CustomMessage("Bombchus (20 pieces)", /*german*/"Krabbelminen (20 Stück)", /*french*/"une vingtaine de Missiles"), hintTextTable[RHT_BOMBCHUS_20] = HintText(CustomMessage("Bombchus (20 pieces)", /*german*/"Krabbelminen (20 Stück)", /*french*/"une vingtaine de Missiles"),
// /*spanish*/unos (20) bombchus // /*spanish*/unos (20) bombchus
{ {
CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"),

View File

@ -723,7 +723,6 @@ void GenerateItemPool() {
//Fixed item locations //Fixed item locations
ctx->PlaceItemInLocation(RC_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER); ctx->PlaceItemInLocation(RC_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER);
ctx->PlaceItemInLocation(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RG_BOMBCHU_DROP);
if (ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) { if (ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) {
AddItemToMainPool(RG_KOKIRI_SWORD); AddItemToMainPool(RG_KOKIRI_SWORD);

View File

@ -69,11 +69,6 @@ bool LocationAccess::CanBuy() const {
placed == RG_BUY_FAIRYS_SPIRIT) { placed == RG_BUY_FAIRYS_SPIRIT) {
OtherCondition = logic->HasBottle; OtherCondition = logic->HasBottle;
} }
// If bombchus in logic, need to have found chus to buy; if not just need bomb bag
else if (placed == RG_BUY_BOMBCHU_10 || placed == RG_BUY_BOMBCHU_20) {
OtherCondition =
(!ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->Bombs) || (ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->FoundBombchus);
}
return SufficientWallet && OtherCondition; return SufficientWallet && OtherCondition;
} }

View File

@ -10,7 +10,7 @@ void AreaTable_Init_BottomOfTheWell() {
---------------------------*/ ---------------------------*/
areaTable[RR_BOTTOM_OF_THE_WELL_ENTRYWAY] = Area("Bottom of the Well Entryway", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_BOTTOM_OF_THE_WELL_ENTRYWAY] = Area("Bottom of the Well Entryway", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_BOTTOM_OF_THE_WELL_MAIN_AREA, {[]{return randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild && (logic->CanChildAttack || logic->Nuts);}}), Entrance(RR_BOTTOM_OF_THE_WELL_MAIN_AREA, {[]{return randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild && (logic->CanChildAttack || logic->CanUse(RG_NUTS));}}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->IsChild;}}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->IsChild;}}),
Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}),
}); });
@ -31,12 +31,12 @@ void AreaTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
LOCATION(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), LOCATION(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)),
LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives), LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives),
LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->Swim || logic->CanUse(RG_ZELDAS_LULLABY)) && logic->Sticks || logic->CanUse(RG_DINS_FIRE)), LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->Swim || logic->CanUse(RG_ZELDAS_LULLABY)) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)),
LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->KokiriSword || (logic->Sticks && randoCtx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)))), LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->KokiriSword || (logic->CanUse(RG_STICKS) && randoCtx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)))),
LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)),
LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasExplosives || (((logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))) || logic->CanUse(RG_DINS_FIRE) || (logic->Sticks && randoCtx->GetTrickOption(RT_BOTW_BASEMENT))) && logic->GoronBracelet)), LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasExplosives || (((logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))) || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && randoCtx->GetTrickOption(RT_BOTW_BASEMENT))) && logic->GoronBracelet)),
LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->Boomerang && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)), LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->Boomerang && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)),
@ -57,7 +57,7 @@ void AreaTable_Init_BottomOfTheWell() {
//EventAccess(&WallFairy, {[]{return WallFairy || logic->Slingshot;}}), //EventAccess(&WallFairy, {[]{return WallFairy || logic->Slingshot;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->KokiriSword || (logic->Sticks && randoCtx->GetTrickOption(RT_BOTW_CHILD_DEADHAND))), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->KokiriSword || (logic->CanUse(RG_STICKS) && randoCtx->GetTrickOption(RT_BOTW_CHILD_DEADHAND))),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, logic->HasExplosives || (randoCtx->GetTrickOption(RT_BOTW_MQ_DEADHAND_KEY) && logic->Boomerang)), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, logic->HasExplosives || (randoCtx->GetTrickOption(RT_BOTW_MQ_DEADHAND_KEY) && logic->Boomerang)),
//Trick: logic->HasExplosives || (LogicBotWMQDeadHandKey && logic->Boomerang) //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_BASEMENT, logic->CanChildAttack),

View File

@ -208,11 +208,13 @@ void AreaTable_Init_CastleTown() {
Entrance(RR_THE_MARKET, {[]{return true;}}), Entrance(RR_THE_MARKET, {[]{return true;}}),
}); });
areaTable[RR_MARKET_BOMBCHU_BOWLING] = Area("Market Bombchu Bowling", "Market Bombchu Bowling", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_MARKET_BOMBCHU_BOWLING] = Area("Market Bombchu Bowling", "Market Bombchu Bowling", RA_NONE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->CouldPlayBowling, {[]{return (logic->ChildsWallet);}}),
}, {
//Locations //Locations
LOCATION(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, logic->CanPlayBowling), LOCATION(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled),
LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->CanPlayBowling), LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled),
LOCATION(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, logic->CanPlayBowling),
}, { }, {
//Exits //Exits
Entrance(RR_THE_MARKET, {[]{return true;}}), Entrance(RR_THE_MARKET, {[]{return true;}}),

View File

@ -94,7 +94,7 @@ void AreaTable_Init_DeathMountain() {
LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (randoCtx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives && logic->CanUse(RG_HOVER_BOOTS))), LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (randoCtx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives && logic->CanUse(RG_HOVER_BOOTS))),
LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS)),
LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS)),
LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->Bombs || (logic->GoronBracelet && randoCtx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->HasBombchus && randoCtx->GetTrickOption(RT_GC_POT)))), LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->Bombs || (logic->GoronBracelet && randoCtx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_GC_POT)))),
LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives || (logic->GoronBracelet && randoCtx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives || (logic->GoronBracelet && randoCtx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))),
LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult), LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult),
LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->CanBlastOrSmash), LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->CanBlastOrSmash),
@ -183,7 +183,7 @@ void AreaTable_Init_DeathMountain() {
//Exits //Exits
Entrance(RR_DMC_UPPER_NEARBY, {[]{return true;}}), Entrance(RR_DMC_UPPER_NEARBY, {[]{return true;}}),
Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer >= 16 || logic->Hearts >= 3;}}), Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer >= 16 || logic->Hearts >= 3;}}),
Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth > 2) || (logic->Fairy && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}}), Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}}),
Entrance(RR_DMC_LOWER_NEARBY, {[]{return false;}}), Entrance(RR_DMC_LOWER_NEARBY, {[]{return false;}}),
}); });

View File

@ -31,7 +31,7 @@ void AreaTable_Init_DekuTree() {
Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}), Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}),
Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, {[]{return true;}}), Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, {[]{return true;}}),
Entrance(RR_DEKU_TREE_COMPASS_ROOM, {[]{return true;}}), Entrance(RR_DEKU_TREE_COMPASS_ROOM, {[]{return true;}}),
Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return Here(RR_DEKU_TREE_LOBBY, []{return logic->CanAdultAttack || logic->CanChildAttack || logic->Nuts;});}}), Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return Here(RR_DEKU_TREE_LOBBY, []{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);});}}),
Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}),
Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}),
}); });
@ -180,7 +180,7 @@ void AreaTable_Init_DekuTree() {
//Locations //Locations
LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, true), LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, true),
LOCATION(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, logic->HookshotOrBoomerang && LOCATION(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, logic->HookshotOrBoomerang &&
Here(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->HasBombchus || Here(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->CanUse(RG_BOMBCHU_5) ||
(logic->Bombs && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult)) || (logic->Bombs && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult)) ||
(logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));})), (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));})),
}, { }, {
@ -206,7 +206,7 @@ void AreaTable_Init_DekuTree() {
Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) ||
Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS);});}) && Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS);});}) &&
Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) ||
logic->CanUseProjectile || (logic->Nuts && logic->CanUse(RG_STICKS));});}}), logic->CanUseProjectile || (logic->CanUse(RG_NUTS) && logic->CanUse(RG_STICKS));});}}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return true;}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return true;}}),
}); });
@ -217,7 +217,7 @@ void AreaTable_Init_DekuTree() {
}, { }, {
//Exits //Exits
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->IsChild;}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->IsChild;}}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUseProjectile || (logic->Nuts && (logic->IsChild && logic->CanUse(RG_STICKS)));}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUseProjectile || (logic->CanUse(RG_NUTS) && (logic->IsChild && logic->CanUse(RG_STICKS)));}}),
}); });
areaTable[RR_DEKU_TREE_MQ_BASEMENT_LEDGE] = Area("Deku Tree MQ Basement Ledge", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_DEKU_TREE_MQ_BASEMENT_LEDGE] = Area("Deku Tree MQ Basement Ledge", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {
@ -258,7 +258,7 @@ void AreaTable_Init_DekuTree() {
// Events // Events
EventAccess(&logic->DekuTreeClear, { [] { EventAccess(&logic->DekuTreeClear, { [] {
return logic->DekuTreeClear || (logic->HasBossSoul(RG_GOHMA_SOUL) && return logic->DekuTreeClear || (logic->HasBossSoul(RG_GOHMA_SOUL) &&
(logic->CanJumpslash && (logic->Nuts || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanJumpslash && (logic->CanUse(RG_NUTS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) ||
logic->HookshotOrBoomerang))); logic->HookshotOrBoomerang)));
}}), }}),
}, },

View File

@ -223,7 +223,7 @@ void AreaTable_Init_DodongosCavern() {
}, { }, {
//Locations //Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, true), LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, true),
LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, logic->CanAdultAttack || logic->CanChildAttack || logic->Nuts), LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS)),
LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->HasFireSource), LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->HasFireSource),
LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, logic->CanBlastOrSmash || (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || (logic->IsAdult && (randoCtx->GetTrickOption(RT_DC_JUMP) || logic->HoverBoots || logic->Hookshot))), LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, logic->CanBlastOrSmash || (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || (logic->IsAdult && (randoCtx->GetTrickOption(RT_DC_JUMP) || logic->HoverBoots || logic->Hookshot))),
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanChildAttack || logic->CanAdultAttack)), LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanChildAttack || logic->CanAdultAttack)),

View File

@ -22,7 +22,7 @@ void AreaTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_FIRST_ROOM] = Area("Forest Temple First Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FOREST_TEMPLE_FIRST_ROOM] = Area("Forest Temple First Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, true), LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, true),
LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->Bombs) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->HasBombchus || logic->CanUse(RG_DINS_FIRE) || (randoCtx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslash || (logic->IsChild && logic->Bombs)))), LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->Bombs) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (randoCtx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslash || (logic->IsChild && logic->Bombs)))),
}, { }, {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}),
@ -32,7 +32,7 @@ void AreaTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_SOUTH_CORRIDOR] = Area("Forest Temple South Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_FOREST_TEMPLE_SOUTH_CORRIDOR] = Area("Forest Temple South Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, {[]{return true;}}),
Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->Nuts;}}), Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}),
}); });
areaTable[RR_FOREST_TEMPLE_LOBBY] = Area("Forest Temple Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { areaTable[RR_FOREST_TEMPLE_LOBBY] = Area("Forest Temple Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {
@ -127,11 +127,11 @@ void AreaTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_MAP_ROOM] = Area("Forest Temple Map Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FOREST_TEMPLE_MAP_ROOM] = Area("Forest Temple Map Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->Nuts || logic->HookshotOrBoomerang || logic->CanShield));})), LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));})),
}, { }, {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->Nuts || logic->HookshotOrBoomerang || logic->CanShield));});}}), Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));});}}),
Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->Nuts || logic->HookshotOrBoomerang || logic->CanShield));});}}), Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));});}}),
}); });
areaTable[RR_FOREST_TEMPLE_SEWER] = Area("Forest Temple Sewer", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FOREST_TEMPLE_SEWER] = Area("Forest Temple Sewer", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
@ -145,7 +145,7 @@ void AreaTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Area("Forest Temple Below Boss Key Chest", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Area("Forest Temple Below Boss Key Chest", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->Nuts || logic->HookshotOrBoomerang || logic->CanShield));});}}), Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));});}}),
}); });
areaTable[RR_FOREST_TEMPLE_FLOORMASTER_ROOM] = Area("Forest Temple Floormaster Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FOREST_TEMPLE_FLOORMASTER_ROOM] = Area("Forest Temple Floormaster Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
@ -159,7 +159,7 @@ void AreaTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_WEST_CORRIDOR] = Area("Forest Temple West Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_FOREST_TEMPLE_WEST_CORRIDOR] = Area("Forest Temple West Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1, 5);}}), Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1, 5);}}),
Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->Nuts;}}), Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}),
}); });
areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Area("Forest Temple Block Push Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Area("Forest Temple Block Push Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
@ -259,8 +259,8 @@ void AreaTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_EAST_CORRIDOR] = Area("Forest Temple East Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_FOREST_TEMPLE_EAST_CORRIDOR] = Area("Forest Temple East Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->Nuts;}}), Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}),
Entrance(RR_FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->Nuts;}}), Entrance(RR_FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}),
}); });
areaTable[RR_FOREST_TEMPLE_BOSS_REGION] = Area("Forest Temple Boss Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FOREST_TEMPLE_BOSS_REGION] = Area("Forest Temple Boss Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
@ -280,12 +280,12 @@ void AreaTable_Init_ForestTemple() {
if (randoCtx->GetDungeon(FOREST_TEMPLE)->IsMQ()) { if (randoCtx->GetDungeon(FOREST_TEMPLE)->IsMQ()) {
areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Area("Forest Temple MQ Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Area("Forest Temple MQ Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanJumpslash || logic->Bombs || logic->CanUse(RG_STICKS) || logic->Nuts || logic->HookshotOrBoomerang || logic->CanUse(RG_DINS_FIRE) || logic->KokiriSword || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOVER_BOOTS)), LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanJumpslash || logic->Bombs || logic->CanUse(RG_STICKS) || logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanUse(RG_DINS_FIRE) || logic->KokiriSword || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang), LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang),
}, { }, {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}),
Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1) && (logic->CanAdultAttack || logic->CanChildAttack || logic->Nuts);}}), Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1) && (logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS));}}),
}); });
areaTable[RR_FOREST_TEMPLE_MQ_CENTRAL_AREA] = Area("Forest Temple MQ Central Area", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { areaTable[RR_FOREST_TEMPLE_MQ_CENTRAL_AREA] = Area("Forest Temple MQ Central Area", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {
@ -299,8 +299,8 @@ void AreaTable_Init_ForestTemple() {
//Exits //Exits
Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}),
Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), //This is as far as child can get Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), //This is as far as child can get
Entrance(RR_FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, {[]{return logic->IsAdult && (logic->GoronBracelet || (randoCtx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->HasBombchus && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)));}}), Entrance(RR_FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, {[]{return logic->IsAdult && (logic->GoronBracelet || (randoCtx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)));}}),
//Trick: logic->IsAdult && (logic->GoronBracelet || (LogicForestMQBlockPuzzle && logic->HasBombchus && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))) //Trick: logic->IsAdult && (logic->GoronBracelet || (LogicForestMQBlockPuzzle && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)))
Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return (randoCtx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (randoCtx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (randoCtx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return (randoCtx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (randoCtx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (randoCtx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}),
//Trick (logic->Hookshot trick not added to either n64 or oot3d rando as of yet, to enable in SoH needs uncommenting in randomizer_tricks.cpp): (LogicForestMQHallwaySwitchJS && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (LogicForestMQHallwaySwitchHookshot && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) //Trick (logic->Hookshot trick not added to either n64 or oot3d rando as of yet, to enable in SoH needs uncommenting in randomizer_tricks.cpp): (LogicForestMQHallwaySwitchJS && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (LogicForestMQHallwaySwitchHookshot && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))
Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, {[]{return logic->ForestTempleJoAndBeth && logic->ForestTempleAmyAndMeg;}}), Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, {[]{return logic->ForestTempleJoAndBeth && logic->ForestTempleAmyAndMeg;}}),

View File

@ -87,12 +87,12 @@ void AreaTable_Init_GanonsCastle() {
areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Area("Ganon's Castle Spirit Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Area("Ganon's Castle Spirit Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->NutPot, {[]{return logic->NutPot || (((randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash) || logic->CanUse(RG_HOOKSHOT)) && logic->HasBombchus && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}), EventAccess(&logic->NutPot, {[]{return logic->NutPot || (((randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}),
EventAccess(&logic->SpiritTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || randoCtx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->HasBombchus && ((randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash) || logic->CanUse(RG_HOOKSHOT));}}), EventAccess(&logic->SpiritTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || randoCtx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash) || logic->CanUse(RG_HOOKSHOT));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanJumpslash), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanJumpslash),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->HasBombchus && (randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))),
}, {}); }, {});
areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Area("Ganon's Castle Light Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Area("Ganon's Castle Light Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {
@ -127,7 +127,7 @@ void AreaTable_Init_GanonsCastle() {
LOCATION(RC_SHEIK_HINT_MQ_GC, true), LOCATION(RC_SHEIK_HINT_MQ_GC, true),
}, { }, {
//Exits //Exits
Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return (logic->CanUse(RG_MASTER_SWORD) || (logic->HasExplosives || ((logic->Nuts || logic->Boomerang) && (logic->Sticks || logic->KokiriSword))));}}), Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return (logic->CanUse(RG_MASTER_SWORD) || (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword))));}}),
Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL, {[]{return true;}}),
Entrance(RR_GANONS_CASTLE_MQ_FIRE_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_FIRE_TRIAL, {[]{return true;}}),
Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL, {[]{return true;}}),
@ -193,16 +193,16 @@ void AreaTable_Init_GanonsCastle() {
areaTable[RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL] = Area("Ganon's Castle MQ Spirit Castle", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL] = Area("Ganon's Castle MQ Spirit Castle", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->SpiritTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->Hammer && logic->HasBombchus && ((logic->FireArrows && logic->MirrorShield) || randoCtx->GetOption(RSK_SUNLIGHT_ARROWS));}}), EventAccess(&logic->SpiritTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->FireArrows && logic->MirrorShield) || randoCtx->GetOption(RSK_SUNLIGHT_ARROWS));}}),
EventAccess(&logic->NutPot, {[]{return logic->NutPot || (logic->Hammer && logic->HasBombchus && logic->IsAdult && ((logic->CanUse(RG_FIRE_ARROWS) && logic->MirrorShield) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}), EventAccess(&logic->NutPot, {[]{return logic->NutPot || (logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && ((logic->CanUse(RG_FIRE_ARROWS) && logic->MirrorShield) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, logic->IsAdult && (logic->Bow || randoCtx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->Hammer), LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, logic->IsAdult && (logic->Bow || randoCtx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->Hammer),
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, logic->IsAdult && (logic->Bow || randoCtx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->Hammer && logic->HasBombchus && (randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, logic->IsAdult && (logic->Bow || randoCtx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && (randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, logic->IsAdult && logic->Hammer && logic->HasBombchus && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, logic->IsAdult && logic->Hammer && logic->HasBombchus && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->IsAdult && logic->Hammer && logic->HasBombchus && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, logic->IsAdult && logic->Hammer && logic->HasBombchus && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
}, {}); }, {});
areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL] = Area("Ganon's Castle MQ Light Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL] = Area("Ganon's Castle MQ Light Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {

View File

@ -143,12 +143,13 @@ void AreaTable_Init_GerudoValley() {
areaTable[RR_HAUNTED_WASTELAND] = Area("Haunted Wasteland", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, { areaTable[RR_HAUNTED_WASTELAND] = Area("Haunted Wasteland", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->FairyPot, {[]{return true;}}),
EventAccess(&logic->NutPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}),
EventAccess(&logic->CarpetMerchant, {[]{return logic->AdultsWallet && (logic->CanJumpslash || logic->CanUse(RG_HOVER_BOOTS));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource), LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource),
LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->AdultsWallet && (logic->CanJumpslash || logic->CanUse(RG_HOVER_BOOTS)) ), LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CarpetMerchant),
LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang), LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang),
}, { }, {
//Exits //Exits

View File

@ -128,7 +128,7 @@ void AreaTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_BIGOCTO_ROOM] = Area("Jabu Jabus Belly Bigocto Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_JABU_JABUS_BELLY_BIGOCTO_ROOM] = Area("Jabu Jabus Belly Bigocto Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}),
Entrance(RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, {[]{return Here(RR_JABU_JABUS_BELLY_BIGOCTO_ROOM, []{return (logic->CanUse(RG_BOOMERANG) || logic->Nuts) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS));});}}), Entrance(RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, {[]{return Here(RR_JABU_JABUS_BELLY_BIGOCTO_ROOM, []{return (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_NUTS)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS));});}}),
}); });
areaTable[RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO] = Area("Jabu Jabus Belly Above Bigocto", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { areaTable[RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO] = Area("Jabu Jabus Belly Above Bigocto", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {
@ -152,7 +152,7 @@ void AreaTable_Init_JabuJabusBelly() {
}, { }, {
//Exits //Exits
Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}),
Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_BOOMERANG) || (randoCtx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && ((logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW))) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)))) || (randoCtx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->HasBombchus || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->Bombs)));}}), Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_BOOMERANG) || (randoCtx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && ((logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW))) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)))) || (randoCtx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->Bombs)));}}),
}); });
} }
@ -177,7 +177,8 @@ void AreaTable_Init_JabuJabusBelly() {
//Locations //Locations
LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true),
LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))) || ChildCanAccess(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA)), LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))) || ChildCanAccess(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->IsChild || logic->CanDive || logic->CanUse(RG_IRON_BOOTS) || randoCtx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->HasBombchus || (randoCtx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG)))), LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->IsChild || logic->CanDive || logic->CanUse(RG_IRON_BOOTS) ||
randoCtx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (randoCtx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG)))),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true), LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true),
@ -193,12 +194,12 @@ void AreaTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_MQ_DEPTHS] = Area("Jabu Jabus Belly MQ Depths", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_JABU_JABUS_BELLY_MQ_DEPTHS] = Area("Jabu Jabus Belly MQ Depths", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, true), LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, true),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->Swim && (logic->Sticks || logic->CanUse(RG_DINS_FIRE))), LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->Swim && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, (randoCtx->GetTrickOption(RT_LENS_JABU_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) || Here(RR_JABU_JABUS_BELLY_MQ_MAIN, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT);})), LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, (randoCtx->GetTrickOption(RT_LENS_JABU_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) || Here(RR_JABU_JABUS_BELLY_MQ_MAIN, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT);})),
}, { }, {
//Exits //Exits
Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}),
Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return logic->Sticks || (logic->CanUse(RG_DINS_FIRE) && logic->KokiriSword);}}), Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return logic->CanUse(RG_STICKS) || (logic->CanUse(RG_DINS_FIRE) && logic->KokiriSword);}}),
}); });
areaTable[RR_JABU_JABUS_BELLY_MQ_BOSS_AREA] = Area("Jabu Jabus Belly MQ Boss Area", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { areaTable[RR_JABU_JABUS_BELLY_MQ_BOSS_AREA] = Area("Jabu Jabus Belly MQ Boss Area", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {

View File

@ -19,7 +19,7 @@ void AreaTable_Init_Kakariko() {
LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS),
LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS),
LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS),
LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->Slingshot || logic->HasBombchus || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslash)) && logic->AtNight && logic->CanGetNightTimeGS), LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->Slingshot || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslash)) && logic->AtNight && logic->CanGetNightTimeGS),
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}),
@ -33,7 +33,7 @@ void AreaTable_Init_Kakariko() {
Entrance(RR_KAK_POTION_SHOP_FRONT, {[]{return logic->AtDay || logic->IsChild;}}), Entrance(RR_KAK_POTION_SHOP_FRONT, {[]{return logic->AtDay || logic->IsChild;}}),
Entrance(RR_KAK_REDEAD_GROTTO, {[]{return logic->CanOpenBombGrotto;}}), Entrance(RR_KAK_REDEAD_GROTTO, {[]{return logic->CanOpenBombGrotto;}}),
Entrance(RR_KAK_IMPAS_LEDGE, {[]{return (logic->IsChild && logic->AtDay) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && randoCtx->GetTrickOption(RT_VISIBLE_COLLISION));}}), Entrance(RR_KAK_IMPAS_LEDGE, {[]{return (logic->IsChild && logic->AtDay) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && randoCtx->GetTrickOption(RT_VISIBLE_COLLISION));}}),
Entrance(RR_KAK_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && (logic->IsAdult || logic->AtDay || logic->Slingshot || logic->HasBombchus || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)));}}), Entrance(RR_KAK_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && (logic->IsAdult || logic->AtDay || logic->Slingshot || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)));}}),
Entrance(RR_KAK_IMPAS_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}}), Entrance(RR_KAK_IMPAS_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}}),
Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), Entrance(RR_THE_GRAVEYARD, {[]{return true;}}),
Entrance(RR_KAK_BEHIND_GATE, {[]{return logic->IsAdult || (logic->KakarikoVillageGateOpen);}}), Entrance(RR_KAK_BEHIND_GATE, {[]{return logic->IsAdult || (logic->KakarikoVillageGateOpen);}}),

View File

@ -153,7 +153,7 @@ void AreaTable_Init_LostWoods() {
//Locations //Locations
LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku), LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku),
LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku), LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku),
LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAdultAttack) || (randoCtx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->HasBombchus || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS), LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAdultAttack) || (randoCtx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS),
LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanPlantBugs && (logic->CanChildAttack || (randoCtx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->DekuShield))), LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanPlantBugs && (logic->CanChildAttack || (randoCtx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->DekuShield))),
}, { }, {
//Exits //Exits
@ -231,7 +231,7 @@ void AreaTable_Init_LostWoods() {
areaTable[RR_SFM_WOLFOS_GROTTO] = Area("SFM Wolfos Grotto", "SFM Wolfos Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SFM_WOLFOS_GROTTO] = Area("SFM Wolfos Grotto", "SFM Wolfos Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->IsAdult || logic->Slingshot || logic->Sticks || logic->KokiriSword || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->IsAdult || logic->Slingshot || logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), //RANDOTODO is this meant to auto-pass as adult?
}, { }, {
//Exits //Exits
Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}),

View File

@ -54,7 +54,7 @@ void AreaTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet),
LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet),
LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Hookshot && (logic->Bombs || logic->GoronBracelet || (randoCtx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->HasBombchus))), LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Hookshot && (logic->Bombs || logic->GoronBracelet || (randoCtx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))),
LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslash), LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslash),
LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->Hookshot || (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->HoverBoots)), LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->Hookshot || (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->HoverBoots)),
LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Hookshot), LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Hookshot),
@ -82,7 +82,7 @@ void AreaTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->CanAdultAttack), LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->CanAdultAttack),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->HasBombchus)) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS) && logic->BossKeyShadowTemple;}}) Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS) && logic->BossKeyShadowTemple;}})
}); });
} }
@ -106,9 +106,9 @@ void AreaTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Area("Shadow Temple MQ First Beamos", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Area("Shadow Temple MQ First Beamos", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanAdultAttack || logic->Nuts), LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanAdultAttack || logic->CanUse(RG_NUTS)),
LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanJumpslash), LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanJumpslash),
LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, logic->CanAdultAttack || logic->Nuts), LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, logic->CanAdultAttack || logic->CanUse(RG_NUTS)),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}), Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}),
@ -159,11 +159,11 @@ void AreaTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Area("Shadow Temple MQ Beyond Boat", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Area("Shadow Temple MQ Beyond Boat", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, true), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, true),
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->Bow || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->HasBombchus)), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->Bow || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->Bow && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}), Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->Bow && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}),
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->HasBombchus)) && logic->CanUse(RG_HOVER_BOOTS) && logic->BossKeyShadowTemple;}}), Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_HOVER_BOOTS) && logic->BossKeyShadowTemple;}}),
}); });
areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Area("Shadow Temple MQ Invisible Maze", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Area("Shadow Temple MQ Invisible Maze", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -31,9 +31,9 @@ void AreaTable_Init_SpiritTemple() {
EventAccess(&logic->NutCrate, {[]{return true;}}), EventAccess(&logic->NutCrate, {[]{return true;}}),
}, { }, {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->Boomerang || logic->Slingshot || (logic->HasBombchus && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->Nuts || logic->Boomerang) && (logic->Sticks || logic->KokiriSword || logic->Slingshot)))), LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->Boomerang || logic->Slingshot || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->Slingshot)))),
LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->Boomerang || logic->Slingshot || (logic->HasBombchus && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->Nuts || logic->Boomerang) && (logic->Sticks || logic->KokiriSword || logic->Slingshot))) && (logic->Sticks || logic->CanUse(RG_DINS_FIRE))), LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->Boomerang || logic->Slingshot || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->Slingshot))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))),
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->Boomerang || logic->Slingshot || (logic->HasBombchus && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->Nuts || logic->Boomerang) && (logic->Sticks || logic->KokiriSword || logic->Slingshot)))), LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->Boomerang || logic->Slingshot || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->Slingshot)))),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}),
@ -41,12 +41,12 @@ void AreaTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Area("Child Spirit Temple Climb", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Area("Child Spirit Temple Climb", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))),
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))),
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, logic->HasProjectile(HasProjectileAge::Both) || logic->CanUse(RG_DINS_FIRE) || LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, logic->HasProjectile(HasProjectileAge::Both) || logic->CanUse(RG_DINS_FIRE) ||
(logic->CanTakeDamage && (logic->CanJumpslash || logic->HasProjectile(HasProjectileAge::Child))) || (logic->CanTakeDamage && (logic->CanJumpslash || logic->HasProjectile(HasProjectileAge::Child))) ||
(logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) || (logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) ||
((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->CanTakeDamage && logic->CanJumpslash)))), ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->CanTakeDamage && logic->CanJumpslash)))),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->HasExplosives || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}), Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->HasExplosives || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}),
@ -55,10 +55,10 @@ void AreaTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_EARLY_ADULT] = Area("Early Adult Spirit Temple", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_EARLY_ADULT] = Area("Early Adult Spirit Temple", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)), LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)),
LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasBombchus || (logic->Bombs && logic->IsAdult && randoCtx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash)), LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->Bombs && logic->IsAdult && randoCtx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash)),
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)),
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)),
LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->Bow || logic->Hookshot || logic->HasBombchus || (logic->Bombs && randoCtx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))), LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->Bow || logic->Hookshot || logic->CanUse(RG_BOMBCHU_5) || (logic->Bombs && randoCtx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}),
@ -66,34 +66,27 @@ void AreaTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Area("Spirit Temple Central Chamber", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Area("Spirit Temple Central Chamber", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
(logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || randoCtx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->Bow && logic->CanUse(RG_STICKS) ))) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives && logic->CanUse(RG_STICKS)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->Bow)) && logic->CanUse(RG_SILVER_GAUNTLETS))),
LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
(logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || randoCtx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->Bow && logic->CanUse(RG_STICKS) ))) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives && logic->CanUse(RG_STICKS)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->Bow)) && logic->CanUse(RG_SILVER_GAUNTLETS))),
(logic->CanUse(RG_DINS_FIRE) ||
(((logic->MagicMeter && logic->FireArrows) || randoCtx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->Bow && logic->Sticks))) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives &&
logic->CanUse(RG_STICKS)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) &&
(logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->Bow)) &&
logic->CanUse(RG_SILVER_GAUNTLETS))),
LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
(logic->CanUse(RG_DINS_FIRE) ||
(((logic->MagicMeter && logic->FireArrows) || randoCtx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->Bow && logic->Sticks))) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives &&
logic->CanUse(RG_STICKS)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) &&
(logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->Bow)) &&
logic->CanUse(RG_SILVER_GAUNTLETS))),
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY)), LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY)),
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))), LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))),
LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives && logic->Boomerang && logic->Hookshot) || LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives && logic->Boomerang && logic->Hookshot) ||
(logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives) || (logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives) ||
(logic->Hookshot && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->Hookshot && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) &&
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || logic->Boomerang && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))))),
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && logic->Boomerang && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))))),
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->Boomerang && (logic->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->Boomerang && (logic->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) ||
(randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives && logic->CanUse(RG_BOOMERANG)) || (randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives && logic->CanUse(RG_BOOMERANG)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))), (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return logic->CanJumpslash || logic->HasExplosives;}}), Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return logic->CanJumpslash || logic->HasExplosives;}}),
@ -117,7 +110,7 @@ void AreaTable_Init_SpiritTemple() {
LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives), LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (randoCtx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->HasBombchus || ((logic->Bombs || logic->Nuts || logic->CanUse(RG_DINS_FIRE)) && (logic->Bow || logic->CanUse(RG_HOOKSHOT) || logic->Hammer)));}}), Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (randoCtx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->Bombs || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->Bow || logic->CanUse(RG_HOOKSHOT) || logic->Hammer)));}}),
}); });
areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Final Locked Door", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Final Locked Door", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
@ -146,27 +139,27 @@ void AreaTable_Init_SpiritTemple() {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true),
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanBlastOrSmash;}) && ((logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)))), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanBlastOrSmash;}) && ((logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)))),
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->HasBombchus || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))) || (logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)))), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))) || (logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)))),
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}),
Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD, {[]{return logic->IsChild;}}), Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD, {[]{return logic->IsChild;}}),
Entrance(RR_SPIRIT_TEMPLE_MQ_ADULT, {[]{return logic->HasBombchus && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), Entrance(RR_SPIRIT_TEMPLE_MQ_ADULT, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS);}}),
}); });
areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD] = Area("Spirit Temple MQ Child", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, { areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD] = Area("Spirit Temple MQ Child", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->KokiriSword && logic->HasBombchus && logic->Slingshot);}}), EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->KokiriSword && logic->CanUse(RG_BOMBCHU_5) && logic->Slingshot);}}),
}, { }, {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer;})), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer;})),
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->KokiriSword && logic->HasBombchus && logic->Slingshot && logic->CanUse(RG_DINS_FIRE)), LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->KokiriSword && logic->CanUse(RG_BOMBCHU_5) && logic->Slingshot && logic->CanUse(RG_DINS_FIRE)),
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->KokiriSword || logic->Bombs), LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->KokiriSword || logic->Bombs),
LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->HasBombchus && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Slingshot && (logic->CanUse(RG_DINS_FIRE) || (Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)));})))), LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Slingshot && (logic->CanUse(RG_DINS_FIRE) || (Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)));})))),
//Trick: logic->HasBombchus && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Slingshot && (logic->CanUse(RG_DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQFrozenEye && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME))))) //Trick: logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Slingshot && (logic->CanUse(RG_DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQFrozenEye && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)))))
}, { }, {
//Exits //Exits
Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return logic->HasBombchus && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}), Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}),
}); });
areaTable[RR_SPIRIT_TEMPLE_MQ_ADULT] = Area("Spirit Temple MQ Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_MQ_ADULT] = Area("Spirit Temple MQ Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -134,7 +134,7 @@ void AreaTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_DRAGON_ROOM] = Area("Water Temple Dragon Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_WATER_TEMPLE_DRAGON_ROOM] = Area("Water Temple Dragon Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && randoCtx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HasBombchus)) || (logic->IsChild && randoCtx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasBombchus))) && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS))) || LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && randoCtx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMBCHU_5))) || (logic->IsChild && randoCtx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5)))) && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS))) ||
Here(RR_WATER_TEMPLE_RIVER, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((randoCtx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS))) || randoCtx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE));})), Here(RR_WATER_TEMPLE_RIVER, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((randoCtx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS))) || randoCtx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE));})),
}, { }, {
//Exits //Exits

View File

@ -163,7 +163,7 @@ void AreaTable_Init_ZorasDomain() {
}, { }, {
//Exits //Exits
Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}), Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}),
Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return (logic->IsChild && logic->Fish);}}), Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}}),
Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return logic->IsAdult;}}), Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return logic->IsAdult;}}),
Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives;}}), Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives;}}),
}); });

View File

@ -45,10 +45,10 @@ std::vector<RandomizerGet> GetMinVanillaShopItems(int total_replaced) {
RG_BUY_ARROWS_10, RG_BUY_ARROWS_10,
RG_BUY_ARROWS_30, RG_BUY_ARROWS_30,
RG_BUY_ARROWS_50, RG_BUY_ARROWS_50,
RG_BUY_BOMBCHU_10, RG_BUY_BOMBCHUS_10,
RG_BUY_BOMBCHU_10, RG_BUY_BOMBCHUS_10,
RG_BUY_BOMBCHU_10, RG_BUY_BOMBCHUS_10,
RG_BUY_BOMBCHU_20, RG_BUY_BOMBCHUS_20,
RG_BUY_BOMBS_525, RG_BUY_BOMBS_525,
RG_BUY_BOMBS_535, RG_BUY_BOMBS_535,
RG_BUY_BOMBS_10, RG_BUY_BOMBS_10,
@ -67,15 +67,15 @@ std::vector<RandomizerGet> GetMinVanillaShopItems(int total_replaced) {
//^First 32 items: Always guaranteed //^First 32 items: Always guaranteed
RG_BUY_BLUE_FIRE, RG_BUY_BLUE_FIRE,
RG_BUY_FISH, RG_BUY_FISH,
RG_BUY_BOMBCHU_10, RG_BUY_BOMBCHUS_10,
RG_BUY_DEKU_NUTS_5, RG_BUY_DEKU_NUTS_5,
RG_BUY_ARROWS_10, RG_BUY_ARROWS_10,
RG_BUY_BOMBCHU_20, RG_BUY_BOMBCHUS_20,
RG_BUY_BOMBS_535, RG_BUY_BOMBS_535,
RG_BUY_RED_POTION_30, RG_BUY_RED_POTION_30,
//^First 40 items: Exist on shopsanity 3 or less //^First 40 items: Exist on shopsanity 3 or less
RG_BUY_BOMBS_30, RG_BUY_BOMBS_30,
RG_BUY_BOMBCHU_20, RG_BUY_BOMBCHUS_20,
RG_BUY_DEKU_NUTS_5, RG_BUY_DEKU_NUTS_5,
RG_BUY_ARROWS_10, RG_BUY_ARROWS_10,
RG_BUY_DEKU_NUTS_5, RG_BUY_DEKU_NUTS_5,
@ -83,7 +83,7 @@ std::vector<RandomizerGet> GetMinVanillaShopItems(int total_replaced) {
RG_BUY_RED_POTION_40, RG_BUY_RED_POTION_40,
RG_BUY_FISH, RG_BUY_FISH,
//^First 48 items: Exist on shopsanity 2 or less //^First 48 items: Exist on shopsanity 2 or less
RG_BUY_BOMBCHU_20, RG_BUY_BOMBCHUS_20,
RG_BUY_ARROWS_30, RG_BUY_ARROWS_30,
RG_BUY_RED_POTION_50, RG_BUY_RED_POTION_50,
RG_BUY_ARROWS_30, RG_BUY_ARROWS_30,

View File

@ -186,10 +186,7 @@ void WriteIngameSpoilerLog() {
if (key == RC_GANON) { if (key == RC_GANON) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_NEVER; spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_NEVER;
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS; spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
} else if (key == RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS) { }
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_REPEATABLE;
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
}
// Shops // Shops
else if (loc->IsShop()) { else if (loc->IsShop()) {
if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) {

View File

@ -781,7 +781,6 @@ void Context::ApplyItemEffect(Item& item, bool state) {
case RG_BOMBCHU_5: case RG_BOMBCHU_5:
case RG_BOMBCHU_10: case RG_BOMBCHU_10:
case RG_BOMBCHU_20: case RG_BOMBCHU_20:
case RG_BOMBCHU_DROP:
SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU));
break; break;
} }
@ -880,7 +879,6 @@ void Context::ApplyItemEffect(Item& item, bool state) {
case RG_BOMBCHU_5: case RG_BOMBCHU_5:
case RG_BOMBCHU_10: case RG_BOMBCHU_10:
case RG_BOMBCHU_20: case RG_BOMBCHU_20:
case RG_BOMBCHU_DROP:
SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU));
break; break;
} }

View File

@ -261,7 +261,6 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() {
rc != RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && rc != RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST &&
rc != RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE && rc != RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE &&
rc != RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE && rc != RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE &&
rc != RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS &&
// Always show ItemGet animation for ice traps // Always show ItemGet animation for ice traps
!(getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId == RG_ICE_TRAP) && !(getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId == RG_ICE_TRAP) &&
( (
@ -835,6 +834,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN);
break; break;
} }
case VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN: {
*should = RAND_GET_OPTION(RSK_BOMBCHUS_IN_LOGIC) == false || INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU;
break;
}
case VB_GIVE_ITEM_FROM_MEDIGORON: { case VB_GIVE_ITEM_FROM_MEDIGORON: {
// fallthrough // fallthrough
case VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE: case VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE:
@ -1435,7 +1438,7 @@ void RandomizerOnActorInitHandler(void* actorRef) {
break; break;
case EXITEM_BOMBCHUS_COUNTER: case EXITEM_BOMBCHUS_COUNTER:
case EXITEM_BOMBCHUS_BOWLING: case EXITEM_BOMBCHUS_BOWLING:
rc = RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS; //RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS was removed as a 3DS holdover not in anyones near term plans due to being pretty useless.
break; break;
case EXITEM_BULLET_BAG: case EXITEM_BULLET_BAG:
rc = RC_LW_TARGET_IN_WOODS; rc = RC_LW_TARGET_IN_WOODS;

View File

@ -205,10 +205,9 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_BOMBS_5] = Item(RG_BOMBS_5, Text{ "Bombs (5)", "Bombes (5)", "Bomben (5)" }, ITEMTYPE_REFILL, GI_BOMBS_5, false, LOGIC_NONE, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBS_5] = Item(RG_BOMBS_5, Text{ "Bombs (5)", "Bombes (5)", "Bomben (5)" }, ITEMTYPE_REFILL, GI_BOMBS_5, false, LOGIC_NONE, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBS_10] = Item(RG_BOMBS_10, Text{ "Bombs (10)", "Bombes (10)", "Bomben (10)" }, ITEMTYPE_REFILL, GI_BOMBS_10, false, LOGIC_NONE, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBS_10] = Item(RG_BOMBS_10, Text{ "Bombs (10)", "Bombes (10)", "Bomben (10)" }, ITEMTYPE_REFILL, GI_BOMBS_10, false, LOGIC_NONE, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBS_20] = Item(RG_BOMBS_20, Text{ "Bombs (20)", "Bombes (20)", "Bomben (20)" }, ITEMTYPE_REFILL, GI_BOMBS_20, false, LOGIC_NONE, RHT_BOMBS_20, ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBS_20] = Item(RG_BOMBS_20, Text{ "Bombs (20)", "Bombes (20)", "Bomben (20)" }, ITEMTYPE_REFILL, GI_BOMBS_20, false, LOGIC_NONE, RHT_BOMBS_20, ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_5] = Item(RG_BOMBCHU_5, Text{ "Bombchus (5)", "Missiles (5)", "Krabbelminen (5)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_5, true, LOGIC_BOMBCHUS_5, RHT_BOMBCHU_5, ITEM_BOMBCHUS_5, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBCHU_5] = Item(RG_BOMBCHU_5, Text{ "Bombchus (5)", "Missiles (5)", "Krabbelminen (5)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_5, true, LOGIC_BOMBCHUS, RHT_BOMBCHUS_5, ITEM_BOMBCHUS_5, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_10] = Item(RG_BOMBCHU_10, Text{ "Bombchus (10)", "Missiles (10)", "Krabbelminen (10)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_10, true, LOGIC_BOMBCHUS_10, RHT_BOMBCHU_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBCHU_10] = Item(RG_BOMBCHU_10, Text{ "Bombchus (10)", "Missiles (10)", "Krabbelminen (10)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_10, true, LOGIC_BOMBCHUS, RHT_BOMBCHUS_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_20] = Item(RG_BOMBCHU_20, Text{ "Bombchus (20)", "Missiles (20)", "Krabbelminen (20)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_20, true, LOGIC_BOMBCHUS_20, RHT_BOMBCHU_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBCHU_20] = Item(RG_BOMBCHU_20, Text{ "Bombchus (20)", "Missiles (20)", "Krabbelminen (20)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_20, true, LOGIC_BOMBCHUS, RHT_BOMBCHUS_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_DROP] = Item(RG_BOMBCHU_DROP, Text{ "Bombchu Drop", "Drop Missiles", "Krabbelminen" }, ITEMTYPE_DROP, GI_BOMBCHUS_10, true, LOGIC_BOMBCHU_DROP, RHT_NONE, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_ARROWS_5] = Item(RG_ARROWS_5, Text{ "Arrows (5)", "Flèches (5)", "Pfeile (5)" }, ITEMTYPE_REFILL, GI_ARROWS_SMALL, false, LOGIC_NONE, RHT_ARROWS_5, ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_ARROWS_5] = Item(RG_ARROWS_5, Text{ "Arrows (5)", "Flèches (5)", "Pfeile (5)" }, ITEMTYPE_REFILL, GI_ARROWS_SMALL, false, LOGIC_NONE, RHT_ARROWS_5, ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_ARROWS_10] = Item(RG_ARROWS_10, Text{ "Arrows (10)", "Flèches (10)", "Pfeile (10)" }, ITEMTYPE_REFILL, GI_ARROWS_MEDIUM, false, LOGIC_NONE, RHT_ARROWS_10, ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_ARROWS_10] = Item(RG_ARROWS_10, Text{ "Arrows (10)", "Flèches (10)", "Pfeile (10)" }, ITEMTYPE_REFILL, GI_ARROWS_MEDIUM, false, LOGIC_NONE, RHT_ARROWS_10, ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_ARROWS_30] = Item(RG_ARROWS_30, Text{ "Arrows (30)", "Flèches (30)", "Pfeile (30)" }, ITEMTYPE_REFILL, GI_ARROWS_LARGE, false, LOGIC_NONE, RHT_ARROWS_30, ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_ARROWS_30] = Item(RG_ARROWS_30, Text{ "Arrows (30)", "Flèches (30)", "Pfeile (30)" }, ITEMTYPE_REFILL, GI_ARROWS_LARGE, false, LOGIC_NONE, RHT_ARROWS_30, ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
@ -239,8 +238,8 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_BUY_GORON_TUNIC] = Item(RG_BUY_GORON_TUNIC, Text{ "Buy Goron Tunic", "Acheter: Tunique Goron", "Goronen-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 200); itemTable[RG_BUY_GORON_TUNIC] = Item(RG_BUY_GORON_TUNIC, Text{ "Buy Goron Tunic", "Acheter: Tunique Goron", "Goronen-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 200);
itemTable[RG_BUY_ZORA_TUNIC] = Item(RG_BUY_ZORA_TUNIC, Text{ "Buy Zora Tunic", "Acheter: Tunique Zora", "Zora-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 300); itemTable[RG_BUY_ZORA_TUNIC] = Item(RG_BUY_ZORA_TUNIC, Text{ "Buy Zora Tunic", "Acheter: Tunique Zora", "Zora-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 300);
itemTable[RG_BUY_HEART] = Item(RG_BUY_HEART, Text{ "Buy Heart", "Acheter: Coeur de Vie", "Herz kaufen" }, ITEMTYPE_SHOP, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 10); itemTable[RG_BUY_HEART] = Item(RG_BUY_HEART, Text{ "Buy Heart", "Acheter: Coeur de Vie", "Herz kaufen" }, ITEMTYPE_SHOP, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 10);
itemTable[RG_BUY_BOMBCHU_10] = Item(RG_BUY_BOMBCHU_10, Text{ "Buy Bombchu (10)", "Acheter: Missiles (10)", "Krabbelminen kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_10, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHU_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 99); itemTable[RG_BUY_BOMBCHUS_10] = Item(RG_BUY_BOMBCHUS_10, Text{ "Buy Bombchu (10)", "Acheter: Missiles (10)", "Krabbelminen kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_10, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHUS_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 99);
itemTable[RG_BUY_BOMBCHU_20] = Item(RG_BUY_BOMBCHU_20, Text{ "Buy Bombchu (20)", "Acheter: Missiles (20)", "Krabbelminen kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_20, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHU_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 180); itemTable[RG_BUY_BOMBCHUS_20] = Item(RG_BUY_BOMBCHUS_20, Text{ "Buy Bombchu (20)", "Acheter: Missiles (20)", "Krabbelminen kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_20, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHUS_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 180);
itemTable[RG_BUY_DEKU_SEEDS_30] = Item(RG_BUY_DEKU_SEEDS_30, Text{ "Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Deku-Samen kaufen (30)" }, ITEMTYPE_SHOP, GI_SEEDS_30, true, LOGIC_BUY_SEED, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30); itemTable[RG_BUY_DEKU_SEEDS_30] = Item(RG_BUY_DEKU_SEEDS_30, Text{ "Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Deku-Samen kaufen (30)" }, ITEMTYPE_SHOP, GI_SEEDS_30, true, LOGIC_BUY_SEED, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
itemTable[RG_SOLD_OUT] = Item(RG_SOLD_OUT, Text{ "Sold Out", "Rupture de stock", "Ausverkauft" }, ITEMTYPE_SHOP, RG_SOLD_OUT, false, LOGIC_NONE, RHT_NONE, false, 0); itemTable[RG_SOLD_OUT] = Item(RG_SOLD_OUT, Text{ "Sold Out", "Rupture de stock", "Ausverkauft" }, ITEMTYPE_SHOP, RG_SOLD_OUT, false, LOGIC_NONE, RHT_NONE, false, 0);
itemTable[RG_BUY_BLUE_FIRE] = Item(RG_BUY_BLUE_FIRE, Text{ "Buy Blue Fire", "Acheter: Flamme Bleue", "Blaues Feuer kaufen" }, ITEMTYPE_SHOP, GI_BLUE_FIRE, true, LOGIC_BLUE_FIRE_ACCESS, RHT_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 300); itemTable[RG_BUY_BLUE_FIRE] = Item(RG_BUY_BLUE_FIRE, Text{ "Buy Blue Fire", "Acheter: Flamme Bleue", "Blaues Feuer kaufen" }, ITEMTYPE_SHOP, GI_BLUE_FIRE, true, LOGIC_BLUE_FIRE_ACCESS, RHT_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 300);

View File

@ -201,7 +201,6 @@ std::vector<RandomizerCheck> Rando::StaticData::overworldLocations = {
RC_MARKET_TREASURE_CHEST_GAME_REWARD, RC_MARKET_TREASURE_CHEST_GAME_REWARD,
RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE,
RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE,
RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS,
RC_MARKET_LOST_DOG, RC_MARKET_LOST_DOG,
RC_MARKET_SHOOTING_GALLERY_REWARD, RC_MARKET_SHOOTING_GALLERY_REWARD,
RC_MARKET_10_BIG_POES, RC_MARKET_10_BIG_POES,
@ -672,7 +671,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_GF_SOUTH_F2_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3857, 0x0F, "GF South F2 Carpenter", RHT_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); locationTable[RC_GF_SOUTH_F2_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3857, 0x0F, "GF South F2 Carpenter", RHT_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true);
// Haunted Wasteland // Haunted Wasteland
locationTable[RC_WASTELAND_CHEST] = Location::Chest(RC_WASTELAND_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, 0x00, "Chest", RHT_WASTELAND_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[RC_WASTELAND_CHEST] = Location::Chest(RC_WASTELAND_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, 0x00, "Chest", RHT_WASTELAND_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, 0x03, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, { Category::cMerchant }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, 0x03, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BUY_BOMBCHUS_10, { Category::cMerchant }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
// Desert Colossus // Desert Colossus
locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true);
locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), 0x39, "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), 0x39, "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
@ -681,7 +680,6 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x0A, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(27), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x0A, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(27), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x33, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x33, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x00, "Bombchu Bowling Bombchus", RHT_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RG_BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_191), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_191), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
@ -1415,14 +1413,14 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, 0x3F, "Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, 0x3F, "Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
// Market // Market
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, 0x30, "Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, 0x30, "Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, 0x31, "Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, 0x31, "Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, 0x32, "Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, 0x32, "Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, 0x33, "Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHU_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, 0x33, "Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, 0x34, "Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, 0x34, "Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, 0x35, "Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, 0x35, "Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, 0x36, "Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, 0x36, "Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, 0x37, "Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHU_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, 0x37, "Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, 0x30, "Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, 0x30, "Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, 0x31, "Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, 0x31, "Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, 0x32, "Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, 0x32, "Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);

View File

@ -56,7 +56,10 @@ namespace Rando {
case RG_LIGHT_ARROWS: case RG_LIGHT_ARROWS:
return ctx->CheckInventory(ITEM_ARROW_LIGHT, true); return ctx->CheckInventory(ITEM_ARROW_LIGHT, true);
case RG_PROGRESSIVE_BOMBCHUS: case RG_PROGRESSIVE_BOMBCHUS:
return ctx->CheckInventory(ITEM_BOMBCHU, true); case RG_BOMBCHU_5:
case RG_BOMBCHU_10:
case RG_BOMBCHU_20:
return (BombchusEnabled && BuyBombchus) || ctx->CheckInventory(ITEM_BOMBCHU, true);
case RG_FAIRY_SLINGSHOT: case RG_FAIRY_SLINGSHOT:
return ctx->CheckInventory(ITEM_SLINGSHOT, true); return ctx->CheckInventory(ITEM_SLINGSHOT, true);
case RG_BOOMERANG: case RG_BOOMERANG:
@ -202,6 +205,18 @@ namespace Rando {
case RG_EYEDROPS: case RG_EYEDROPS:
case RG_CLAIM_CHECK: case RG_CLAIM_CHECK:
return ctx->HasAdultTrade(StaticData::RetrieveItem(itemName).GetGIEntry()->itemId); return ctx->HasAdultTrade(StaticData::RetrieveItem(itemName).GetGIEntry()->itemId);
case RG_BOTTLE_WITH_BIG_POE:
case RG_BOTTLE_WITH_BLUE_FIRE:
case RG_BOTTLE_WITH_BLUE_POTION:
case RG_BOTTLE_WITH_BUGS:
case RG_BOTTLE_WITH_FAIRY:
case RG_BOTTLE_WITH_FISH:
case RG_BOTTLE_WITH_GREEN_POTION:
case RG_BOTTLE_WITH_MILK:
case RG_BOTTLE_WITH_POE:
case RG_BOTTLE_WITH_RED_POTION:
case RG_EMPTY_BOTTLE:
return HasBottle;
} }
SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}", static_cast<uint32_t>(itemName)); SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}", static_cast<uint32_t>(itemName));
assert(false); assert(false);
@ -256,12 +271,19 @@ namespace Rando {
return IsChild;// || BoomerangAsAdult; return IsChild;// || BoomerangAsAdult;
case RG_KOKIRI_SWORD: case RG_KOKIRI_SWORD:
return IsChild;// || KokiriSwordAsAdult; return IsChild;// || KokiriSwordAsAdult;
case RG_NUTS:
return (NutPot || NutCrate || DekuBabaNuts) && AmmoCanDrop; //RANDOTODO BuyNuts currently mixed in with Nuts, should be seperate as BuyNuts are also a Nuts source
case RG_STICKS: case RG_STICKS:
return IsChild;// || StickAsAdult; return IsChild /* || StickAsAdult;*/&& (StickPot || DekuBabaSticks);
case RG_DEKU_SHIELD: case RG_DEKU_SHIELD:
return IsChild;// || DekuShieldAsAdult; return IsChild;// || DekuShieldAsAdult;
case RG_WEIRD_EGG: case RG_WEIRD_EGG:
return IsChild; return IsChild;
case RG_PROGRESSIVE_BOMBCHUS:
case RG_BOMBCHU_5:
case RG_BOMBCHU_10:
case RG_BOMBCHU_20:
return BombchuRefill && BombchusEnabled;
case RG_RUTOS_LETTER: case RG_RUTOS_LETTER:
return IsChild; return IsChild;
@ -317,6 +339,16 @@ namespace Rando {
case RG_FISHING_POLE: case RG_FISHING_POLE:
return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies
// Bottle Items
case RG_BOTTLE_WITH_BUGS:
return BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS);
case RG_BOTTLE_WITH_FISH:
return LoneFish || FishGroup || GetInLogic(LOGIC_FISH_ACCESS); //is there any need to care about lone vs group?
case RG_BOTTLE_WITH_BLUE_FIRE: //RANDOTODO should probably be better named to
return BlueFireAccess || GetInLogic(LOGIC_BLUE_FIRE_ACCESS);
case RG_BOTTLE_WITH_FAIRY:
return FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || GetInLogic(LOGIC_FAIRY_ACCESS);
// Magic items // Magic items
default: default:
return MagicMeter && (IsMagicItem(itemName) || (IsMagicArrow(itemName) && CanUse(RG_FAIRY_BOW))); return MagicMeter && (IsMagicItem(itemName) || (IsMagicArrow(itemName) && CanUse(RG_FAIRY_BOW)));
@ -375,7 +407,7 @@ namespace Rando {
return ((IsAdult && HasItem(RG_DINS_FIRE)) || (IsChild && (HasItem(RG_STICKS) || HasItem(RG_DINS_FIRE)))) && false; //GlitchEquipSwapDins; return ((IsAdult && HasItem(RG_DINS_FIRE)) || (IsChild && (HasItem(RG_STICKS) || HasItem(RG_DINS_FIRE)))) && false; //GlitchEquipSwapDins;
case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child item equippable list case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child item equippable list
return ((IsAdult && (HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE))) || (IsChild && (HasItem(RG_STICKS) || return ((IsAdult && (HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE))) || (IsChild && (HasItem(RG_STICKS) ||
HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || HasBottle || Nuts || Ocarina || HasItem(RG_LENS_OF_TRUTH) || HasExplosives || HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || HasBottle || CanUse(RG_NUTS) || Ocarina || HasItem(RG_LENS_OF_TRUTH) || HasExplosives ||
ctx->GetAmmo(ITEM_BEAN) > 0 || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap; ctx->GetAmmo(ITEM_BEAN) > 0 || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap;
} }
@ -398,7 +430,7 @@ namespace Rando {
return true; return true;
} }
if (enemy == "Big Skulltula"){ if (enemy == "Big Skulltula"){
return Nuts || CanUse(RG_BOOMERANG); return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG);
} }
return false; return false;
} }
@ -427,12 +459,10 @@ namespace Rando {
(HasItem(RG_OCARINA_C_DOWN_BUTTON) ? 1 : 0); (HasItem(RG_OCARINA_C_DOWN_BUTTON) ? 1 : 0);
ZeldasLetter = HasItem(RG_ZELDAS_LETTER); ZeldasLetter = HasItem(RG_ZELDAS_LETTER);
WeirdEgg = CanUse(RG_WEIRD_EGG); WeirdEgg = CanUse(RG_WEIRD_EGG);
Bombchus = HasItem(RG_PROGRESSIVE_BOMBCHUS);
BuySeed = GetInLogic(LOGIC_BUY_SEED); BuySeed = GetInLogic(LOGIC_BUY_SEED);
BuyArrow = GetInLogic(LOGIC_BUY_ARROW); BuyArrow = GetInLogic(LOGIC_BUY_ARROW);
BuyBomb = GetInLogic(LOGIC_BUY_BOMB); BuyBomb = GetInLogic(LOGIC_BUY_BOMB);
BuyMagicPotion = GetInLogic(LOGIC_BUY_MAGIC_POTION); BuyMagicPotion = GetInLogic(LOGIC_BUY_MAGIC_POTION);
BuyBombchus = GetInLogic(LOGIC_BUY_BOMBCHUS);
MagicBean = ctx->GetAmmo(ITEM_BEAN) > 0; MagicBean = ctx->GetAmmo(ITEM_BEAN) > 0;
RutosLetter = CanUse(RG_RUTOS_LETTER); RutosLetter = CanUse(RG_RUTOS_LETTER);
Boomerang = CanUse(RG_BOOMERANG); Boomerang = CanUse(RG_BOOMERANG);
@ -469,6 +499,8 @@ namespace Rando {
OcarinaOfTime = HasItem(RG_OCARINA_OF_TIME); OcarinaOfTime = HasItem(RG_OCARINA_OF_TIME);
MagicMeter = HasItem(RG_MAGIC_SINGLE) && (AmmoCanDrop || (HasBottle && BuyMagicPotion)); MagicMeter = HasItem(RG_MAGIC_SINGLE) && (AmmoCanDrop || (HasBottle && BuyMagicPotion));
BombBag = HasItem(RG_BOMB_BAG) && (BuyBomb || AmmoCanDrop); BombBag = HasItem(RG_BOMB_BAG) && (BuyBomb || AmmoCanDrop);
BombchusEnabled = ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) ? ctx->CheckInventory(ITEM_BOMBCHU, true) : BombBag;
BuyBombchus = (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant);
Hookshot = CanUse(RG_HOOKSHOT); Hookshot = CanUse(RG_HOOKSHOT);
Longshot = CanUse(RG_LONGSHOT); Longshot = CanUse(RG_LONGSHOT);
Bow = CanUse(RG_FAIRY_BOW) && (BuyArrow || AmmoCanDrop); Bow = CanUse(RG_FAIRY_BOW) && (BuyArrow || AmmoCanDrop);
@ -523,33 +555,16 @@ namespace Rando {
Scarecrow = Hookshot && ScarecrowSong; Scarecrow = Hookshot && ScarecrowSong;
DistantScarecrow = Longshot && ScarecrowSong; DistantScarecrow = Longshot && ScarecrowSong;
//Drop Access
DekuStickDrop = StickPot || DekuBabaSticks;
DekuNutDrop = (NutPot || NutCrate || DekuBabaNuts) && AmmoCanDrop;
BugsAccess = BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS);
FishAccess = LoneFish || FishGroup || GetInLogic(LOGIC_FISH_ACCESS);
FairyAccess = FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || GetInLogic(LOGIC_FAIRY_ACCESS);
//refills
Bombs = HasItem(RG_PROGRESSIVE_BOMB_BAG);
Nuts = DekuNutDrop || HasItem(RG_NUTS);
Sticks = DekuStickDrop || HasItem(RG_STICKS);
Bugs = HasBottle && BugsAccess;
BlueFireAccess = BlueFireAccess || GetInLogic(LOGIC_BLUE_FIRE_ACCESS);
BlueFire = (HasBottle && BlueFireAccess) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS));
Fish = HasBottle && FishAccess;
Fairy = HasBottle && FairyAccess;
FoundBombchus = Bombchus && (BombBag || ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC));
CanPlayBowling = ChildsWallet && ((ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && FoundBombchus) || (!ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && BombBag));
// TODO: Implement Ammo Drop Setting in place of bombchu drops // TODO: Implement Ammo Drop Setting in place of bombchu drops
HasBombchus = (BuyBombchus || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON/*_PLUS_BOMBCHU*/) && FoundBombchus)); BombchuRefill = BuyBombchus || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON/*_PLUS_BOMBCHU*/));
HasExplosives = Bombs || (ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && HasBombchus); //Usage
Bombs = HasItem(RG_PROGRESSIVE_BOMB_BAG);
BlueFire = CanUse(RG_BOTTLE_WITH_BLUE_FIRE) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS));
// TODO: Implement Ammo Drop Setting in place of bombchu drops
HasExplosives = Bombs || CanUse(RG_BOMBCHU_5);
HasBoots = IronBoots || HoverBoots; HasBoots = IronBoots || HoverBoots;
//Unshuffled adult trade quest //Unshuffled adult trade quest
ClaimCheck = CanUse(RG_CLAIM_CHECK); ClaimCheck = CanUse(RG_CLAIM_CHECK);
Eyedrops = CanUse(RG_EYEDROPS) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && ClaimCheck); Eyedrops = CanUse(RG_EYEDROPS) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && ClaimCheck);
@ -566,15 +581,15 @@ namespace Rando {
// IsAdult = Age == AGE_ADULT; // IsAdult = Age == AGE_ADULT;
CanBlastOrSmash = HasExplosives || CanUse(RG_MEGATON_HAMMER); CanBlastOrSmash = HasExplosives || CanUse(RG_MEGATON_HAMMER);
CanChildAttack = IsChild && (Slingshot || Boomerang || Sticks || KokiriSword || HasExplosives || CanUse(RG_DINS_FIRE) || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD)); CanChildAttack = IsChild && (Slingshot || Boomerang || CanUse(RG_STICKS) || KokiriSword || HasExplosives || CanUse(RG_DINS_FIRE) || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD));
CanChildDamage = IsChild && (Slingshot || Sticks || KokiriSword || HasExplosives || CanUse(RG_DINS_FIRE) || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD)); CanChildDamage = IsChild && (Slingshot || CanUse(RG_STICKS) || KokiriSword || HasExplosives || CanUse(RG_DINS_FIRE) || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD));
CanAdultAttack = IsAdult && (CanUse(RG_FAIRY_BOW) || CanUse(RG_BOOMERANG) || CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || HasExplosives || CanUse(RG_DINS_FIRE) || MasterSword || Hammer || BiggoronSword || Hookshot); CanAdultAttack = IsAdult && (CanUse(RG_FAIRY_BOW) || CanUse(RG_BOOMERANG) || CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || HasExplosives || CanUse(RG_DINS_FIRE) || MasterSword || Hammer || BiggoronSword || Hookshot);
CanAdultDamage = IsAdult && (CanUse(RG_FAIRY_BOW) || CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || HasExplosives || CanUse(RG_DINS_FIRE) || MasterSword || Hammer || BiggoronSword); CanAdultDamage = IsAdult && (CanUse(RG_FAIRY_BOW) || CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || HasExplosives || CanUse(RG_DINS_FIRE) || MasterSword || Hammer || BiggoronSword);
CanStunDeku = CanAdultAttack || CanChildAttack || Nuts || HasShield; CanStunDeku = CanAdultAttack || CanChildAttack || CanUse(RG_NUTS) || HasShield;
CanCutShrubs = CanUse(RG_KOKIRI_SWORD) || CanUse(RG_BOOMERANG) || HasExplosives || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD); CanCutShrubs = CanUse(RG_KOKIRI_SWORD) || CanUse(RG_BOOMERANG) || HasExplosives || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD);
CanDive = ProgressiveScale >= 2; CanDive = ProgressiveScale >= 2;
CanLeaveForest = ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || IsAdult || DekuTreeClear || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES); CanLeaveForest = ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || IsAdult || DekuTreeClear || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES);
CanPlantBugs = IsChild && Bugs; CanPlantBugs = IsChild && CanUse(RG_BOTTLE_WITH_BUGS);
CanRideEpona = IsAdult && Epona && CanUse(RG_EPONAS_SONG); CanRideEpona = IsAdult && Epona && CanUse(RG_EPONAS_SONG);
CanSummonGossipFairyWithoutSuns = CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME); CanSummonGossipFairyWithoutSuns = CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME);
CanSummonGossipFairy = CanSummonGossipFairyWithoutSuns || CanUse(RG_SUNS_SONG); CanSummonGossipFairy = CanSummonGossipFairyWithoutSuns || CanUse(RG_SUNS_SONG);
@ -584,13 +599,13 @@ namespace Rando {
WaterTimer = CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0; WaterTimer = CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0;
NeedNayrusLove = (EffectiveHealth == 1); NeedNayrusLove = (EffectiveHealth == 1);
CanSurviveDamage = !NeedNayrusLove || CanUse(RG_NAYRUS_LOVE); CanSurviveDamage = !NeedNayrusLove || CanUse(RG_NAYRUS_LOVE);
CanTakeDamage = Fairy || CanSurviveDamage; CanTakeDamage = CanUse(RG_BOTTLE_WITH_FAIRY) || CanSurviveDamage;
CanTakeDamageTwice = (Fairy && NumBottles >= 2) || ((EffectiveHealth == 2) && (CanUse(RG_NAYRUS_LOVE) || Fairy)) || (EffectiveHealth > 2); CanTakeDamageTwice = (CanUse(RG_BOTTLE_WITH_FAIRY) && NumBottles >= 2) || ((EffectiveHealth == 2) && (CanUse(RG_NAYRUS_LOVE) || CanUse(RG_BOTTLE_WITH_FAIRY))) || (EffectiveHealth > 2);
CanOpenBombGrotto = CanBlastOrSmash && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); CanOpenBombGrotto = CanBlastOrSmash && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY));
CanOpenStormGrotto = CanUse(RG_SONG_OF_STORMS) && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); CanOpenStormGrotto = CanUse(RG_SONG_OF_STORMS) && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY));
HookshotOrBoomerang = CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); HookshotOrBoomerang = CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG);
CanGetNightTimeGS = (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG)); CanGetNightTimeGS = (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG));
CanBreakUpperBeehives = HookshotOrBoomerang || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && HasBombchus); CanBreakUpperBeehives = HookshotOrBoomerang || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && CanUse(RG_BOMBCHU_5));
CanBreakLowerBeehives = CanBreakUpperBeehives || Bombs; CanBreakLowerBeehives = CanBreakUpperBeehives || Bombs;
CanFish = ChildsWallet && (HasItem(RG_FISHING_POLE) || !ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)); CanFish = ChildsWallet && (HasItem(RG_FISHING_POLE) || !ctx->GetOption(RSK_SHUFFLE_FISHING_POLE));
CanGetChildFish = CanFish && (IsChild || (IsAdult && !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))); CanGetChildFish = CanFish && (IsChild || (IsAdult && !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)));
@ -770,10 +785,6 @@ namespace Rando {
ZeldasLetter = false; ZeldasLetter = false;
WeirdEgg = false; WeirdEgg = false;
HasBottle = false; HasBottle = false;
Bombchus = false;
Bombchus5 = false;
Bombchus10 = false;
Bombchus20 = false;
MagicBean = false; MagicBean = false;
RutosLetter = false; RutosLetter = false;
Boomerang = false; Boomerang = false;
@ -927,36 +938,34 @@ namespace Rando {
CanSummonGanon = false; CanSummonGanon = false;
//Drops and Bottle Contents Access //Drops and Bottle Contents Access
DekuNutDrop = false;
NutPot = false; NutPot = false;
NutCrate = false; NutCrate = false;
DekuBabaNuts = false; DekuBabaNuts = false;
DekuStickDrop = false;
StickPot = false; StickPot = false;
DekuBabaSticks = false; DekuBabaSticks = false;
BugsAccess = false;
BugShrub = false; BugShrub = false;
WanderingBugs = false; WanderingBugs = false;
BugRock = false; BugRock = false;
BlueFireAccess = false; BlueFireAccess = false;
FishAccess = false;
FishGroup = false; FishGroup = false;
LoneFish = false; LoneFish = false;
FairyAccess = false;
GossipStoneFairy = false; GossipStoneFairy = false;
BeanPlantFairy = false; BeanPlantFairy = false;
ButterflyFairy = false; ButterflyFairy = false;
FairyPot = false; FairyPot = false;
FreeFairies = false; FreeFairies = false;
FairyPond = false; FairyPond = false;
BombchuDrop = false; BombchuRefill = false;
BombchusEnabled = false;
BuyBombchus = false; BuyBombchus = false;
BuySeed = false; BuySeed = false;
BuyArrow = false; BuyArrow = false;
BuyBomb = false; BuyBomb = false;
BuyMagicPotion = false; BuyMagicPotion = false;
MagicRefill = false; BuyFish = false;
BuyBugs = false;
BuyFairy = false;
PieceOfHeart = 0; PieceOfHeart = 0;
HeartContainer = 0; HeartContainer = 0;
@ -966,6 +975,7 @@ namespace Rando {
/* These are used to simplify reading the logic, but need to be updated /* These are used to simplify reading the logic, but need to be updated
/ every time a base value is updated. */ / every time a base value is updated. */
BulletBag = false;
Slingshot = false; Slingshot = false;
Ocarina = false; Ocarina = false;
OcarinaOfTime = false; OcarinaOfTime = false;
@ -973,6 +983,7 @@ namespace Rando {
MagicMeter = false; MagicMeter = false;
Hookshot = false; Hookshot = false;
Longshot = false; Longshot = false;
Quiver = false;
Bow = false; Bow = false;
GoronBracelet = false; GoronBracelet = false;
SilverGauntlets = false; SilverGauntlets = false;
@ -992,17 +1003,10 @@ namespace Rando {
Bombs = false; Bombs = false;
DekuShield = false; DekuShield = false;
HylianShield = false; HylianShield = false;
Nuts = false;
Sticks = false;
Bugs = false;
BlueFire = false; BlueFire = false;
Fish = false;
Fairy = false;
BottleWithBigPoe = false; BottleWithBigPoe = false;
FoundBombchus = false; CouldPlayBowling = false;
CanPlayBowling = false;
HasBombchus = false;
HasExplosives = false; HasExplosives = false;
HasBoots = false; HasBoots = false;
IsChild = false; IsChild = false;

View File

@ -32,13 +32,10 @@ class Logic {
// Child item logic // Child item logic
bool KokiriSword = false; bool KokiriSword = false;
bool BulletBag = false;
bool ZeldasLetter = false; bool ZeldasLetter = false;
bool WeirdEgg = false; bool WeirdEgg = false;
bool HasBottle = false; bool HasBottle = false;
bool Bombchus = false;
bool Bombchus5 = false;
bool Bombchus10 = false;
bool Bombchus20 = false;
bool MagicBean = false; bool MagicBean = false;
bool RutosLetter = false; bool RutosLetter = false;
bool Boomerang = false; bool Boomerang = false;
@ -171,37 +168,35 @@ class Logic {
bool NoBottles = false; bool NoBottles = false;
// Drops and Bottle Contents Access // Drops and Bottle Contents Access
bool DekuNutDrop = false;
bool NutPot = false; bool NutPot = false;
bool NutCrate = false; bool NutCrate = false;
bool DekuBabaNuts = false; bool DekuBabaNuts = false;
bool DekuStickDrop = false;
bool StickPot = false; bool StickPot = false;
bool DekuBabaSticks = false; bool DekuBabaSticks = false;
bool BugsAccess = false;
bool BugShrub = false; bool BugShrub = false;
bool WanderingBugs = false; bool WanderingBugs = false;
bool BugRock = false; bool BugRock = false;
bool BlueFireAccess = false; bool BlueFireAccess = false;
bool FishAccess = false;
bool FishGroup = false; bool FishGroup = false;
bool LoneFish = false; bool LoneFish = false;
bool FairyAccess = false;
bool GossipStoneFairy = false; bool GossipStoneFairy = false;
bool BeanPlantFairy = false; bool BeanPlantFairy = false;
bool ButterflyFairy = false; bool ButterflyFairy = false;
bool FairyPot = false; bool FairyPot = false;
bool FreeFairies = false; bool FreeFairies = false;
bool FairyPond = false; bool FairyPond = false;
bool BombchuDrop = false;
bool AmmoCanDrop = false; bool AmmoCanDrop = false;
bool BombchuRefill = false;
bool BombchusEnabled = false;
bool BuyBombchus = false; bool BuyBombchus = false;
bool BuySeed = false; bool BuySeed = false;
bool BuyArrow = false; bool BuyArrow = false;
bool BuyBomb = false; bool BuyBomb = false;
bool BuyMagicPotion = false; bool BuyMagicPotion = false;
bool MagicRefill = false; bool BuyFish = false;
bool BuyBugs = false;
bool BuyFairy = false;
uint8_t PieceOfHeart = 0; uint8_t PieceOfHeart = 0;
uint8_t HeartContainer = 0; uint8_t HeartContainer = 0;
@ -211,14 +206,13 @@ class Logic {
/* These are used to simplify reading the logic, but need to be updated /* These are used to simplify reading the logic, but need to be updated
/ every time a base value is updated. */ / every time a base value is updated. */
bool Slingshot = false;
bool Ocarina = false; bool Ocarina = false;
bool OcarinaOfTime = false; bool OcarinaOfTime = false;
bool BombBag = false; bool BombBag = false;
bool MagicMeter = false; bool MagicMeter = false;
bool Hookshot = false; bool Hookshot = false;
bool Longshot = false; bool Longshot = false;
bool Bow = false; bool Quiver = false;
bool GoronBracelet = false; bool GoronBracelet = false;
bool SilverGauntlets = false; bool SilverGauntlets = false;
bool GoldenGauntlets = false; bool GoldenGauntlets = false;
@ -234,15 +228,12 @@ class Logic {
bool Scarecrow = false; bool Scarecrow = false;
bool DistantScarecrow = false; bool DistantScarecrow = false;
bool Slingshot = false;
bool Bombs = false; bool Bombs = false;
bool Bow = false;
bool DekuShield = false; bool DekuShield = false;
bool HylianShield = false; bool HylianShield = false;
bool Nuts = false;
bool Sticks = false;
bool Bugs = false;
bool BlueFire = false; bool BlueFire = false;
bool Fish = false;
bool Fairy = false;
bool BottleWithBigPoe = false; bool BottleWithBigPoe = false;
bool OcarinaAButton = false; bool OcarinaAButton = false;
@ -251,9 +242,8 @@ class Logic {
bool OcarinaCUpButton = false; bool OcarinaCUpButton = false;
bool OcarinaCDownButton = false; bool OcarinaCDownButton = false;
bool FoundBombchus = false; bool CarpetMerchant = false;
bool CanPlayBowling = false; bool CouldPlayBowling = false;
bool HasBombchus = false;
bool HasExplosives = false; bool HasExplosives = false;
bool HasBoots = false; bool HasBoots = false;
bool IsChild = false; bool IsChild = false;

View File

@ -552,7 +552,8 @@ void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_MASK_SHOP_HINT] = "Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre."; mOptionDescriptions[RSK_MASK_SHOP_HINT] = "Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre.";
mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees."; mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees.";
mOptionDescriptions[RSK_BOMBCHUS_IN_LOGIC] = mOptionDescriptions[RSK_BOMBCHUS_IN_LOGIC] =
"Bombchus are properly considered in logic.\n" "Bombchus are properly considered in logic. Without this setting, any Bombchu requirement"
" is filled by Bomb Bag + a renewable source of Bombchus\n"
"\n" "\n"
"The first Bombchu pack will always be 20, and subsequent packs will be " "The first Bombchu pack will always be 20, and subsequent packs will be "
"5 or 10 based on how many you have.\n" "5 or 10 based on how many you have.\n"
@ -560,7 +561,10 @@ void Settings::CreateOptionDescriptions() {
"\n" "\n"
"Bombchu Bowling is opened by obtaining Bombchus."; "Bombchu Bowling is opened by obtaining Bombchus.";
mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS] = "Once you obtain bombchus for the first time, refills can be found " mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS] = "Once you obtain bombchus for the first time, refills can be found "
"in bushes and other places where bomb drops can normally spawn."; "in bushes and other places where bomb drops can normally spawn."
"\n"
"If you have Bombchus in Logic disabled, you will also need a"
"Bomb bag for bombchus to drop";
mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] = mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] =
"Ice Arrows act like Blue Fire, making them able to melt red ice. " "Ice Arrows act like Blue Fire, making them able to melt red ice. "
"Item placement logic will respect this option, so it might be required to use this to progress."; "Item placement logic will respect this option, so it might be required to use this to progress.";

View File

@ -273,9 +273,9 @@ std::unordered_map<RandomizerGet, EnGirlAShopItem> randomizerGetToEnGirlShopItem
{ RG_BUY_DEKU_SHIELD, SI_DEKU_SHIELD }, { RG_BUY_DEKU_SHIELD, SI_DEKU_SHIELD },
{ RG_BUY_GORON_TUNIC, SI_GORON_TUNIC }, { RG_BUY_GORON_TUNIC, SI_GORON_TUNIC },
{ RG_BUY_ZORA_TUNIC, SI_ZORA_TUNIC }, { RG_BUY_ZORA_TUNIC, SI_ZORA_TUNIC },
{ RG_BUY_HEART, SI_HEART }, { RG_BUY_HEART, SI_RECOVERY_HEART },
{ RG_BUY_BOMBCHU_10, SI_BOMBCHU_10_1 }, { RG_BUY_BOMBCHUS_10, SI_BOMBCHU_10_1 },
{ RG_BUY_BOMBCHU_20, SI_BOMBCHU_20_1 }, { RG_BUY_BOMBCHUS_20, SI_BOMBCHU_20_1 },
{ RG_BUY_DEKU_SEEDS_30, SI_DEKU_SEEDS_30 }, { RG_BUY_DEKU_SEEDS_30, SI_DEKU_SEEDS_30 },
{ RG_BUY_BLUE_FIRE, SI_BLUE_FIRE }, { RG_BUY_BLUE_FIRE, SI_BLUE_FIRE },
{ RG_BUY_BOTTLE_BUG, SI_BUGS }, { RG_BUY_BOTTLE_BUG, SI_BUGS },
@ -461,19 +461,10 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
case RG_BOMBCHU_5: case RG_BOMBCHU_5:
case RG_BOMBCHU_10: case RG_BOMBCHU_10:
case RG_BOMBCHU_20: case RG_BOMBCHU_20:
case RG_PROGRESSIVE_BOMBCHUS: case RG_BUY_BOMBCHUS_10:
case RG_BUY_BOMBCHUS_20:
case RG_PROGRESSIVE_BOMBCHUS: //RANDOTODO Do we want bombchu refills to exist seperatly from bombchu bags? If so, this needs changing.
return CAN_OBTAIN; return CAN_OBTAIN;
case RG_BUY_BOMBCHU_10:
case RG_BUY_BOMBCHU_20:
case RG_BOMBCHU_DROP:
// If Bombchus aren't in logic, you need a bomb bag to purchase them
// If they are in logic, you need to have already obtained them somewhere else
// Bombchu Drop is only used as a bowling reward, so it needs the same logic
if (GetRandoSettingValue(RSK_BOMBCHUS_IN_LOGIC)) {
return INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE;
} else {
return CUR_UPG_VALUE(UPG_BOMB_BAG) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE;
}
case RG_PROGRESSIVE_HOOKSHOT: case RG_PROGRESSIVE_HOOKSHOT:
switch (INV_CONTENT(ITEM_HOOKSHOT)) { switch (INV_CONTENT(ITEM_HOOKSHOT)) {
case ITEM_NONE: case ITEM_NONE:
@ -869,13 +860,11 @@ GetItemID Randomizer::GetItemIdFromRandomizerGet(RandomizerGet randoGet, GetItem
return GI_OCARINA_OOT; return GI_OCARINA_OOT;
} }
case RG_BOMBCHU_5: case RG_BOMBCHU_5:
case RG_BOMBCHU_DROP:
return GI_BOMBCHUS_5;
case RG_BOMBCHU_10: case RG_BOMBCHU_10:
case RG_BUY_BOMBCHU_10: case RG_BUY_BOMBCHUS_10:
return GI_BOMBCHUS_10; return GI_BOMBCHUS_10;
case RG_BOMBCHU_20: case RG_BOMBCHU_20:
case RG_BUY_BOMBCHU_20: case RG_BUY_BOMBCHUS_20:
return GI_BOMBCHUS_20; return GI_BOMBCHUS_20;
case RG_PROGRESSIVE_BOMBCHUS: case RG_PROGRESSIVE_BOMBCHUS:
if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) {
@ -1176,7 +1165,6 @@ bool Randomizer::IsItemVanilla(RandomizerGet randoGet) {
case RG_BOMBCHU_5: case RG_BOMBCHU_5:
case RG_BOMBCHU_10: case RG_BOMBCHU_10:
case RG_BOMBCHU_20: case RG_BOMBCHU_20:
case RG_BOMBCHU_DROP:
return true; return true;
case RG_PROGRESSIVE_BOMBCHUS: case RG_PROGRESSIVE_BOMBCHUS:
return INV_CONTENT(ITEM_BOMBCHU) != ITEM_NONE && !GetRandoSettingValue(RSK_INFINITE_UPGRADES); return INV_CONTENT(ITEM_BOMBCHU) != ITEM_NONE && !GetRandoSettingValue(RSK_INFINITE_UPGRADES);
@ -1208,8 +1196,8 @@ bool Randomizer::IsItemVanilla(RandomizerGet randoGet) {
case RG_BUY_GORON_TUNIC: case RG_BUY_GORON_TUNIC:
case RG_BUY_ZORA_TUNIC: case RG_BUY_ZORA_TUNIC:
case RG_BUY_HEART: case RG_BUY_HEART:
case RG_BUY_BOMBCHU_10: case RG_BUY_BOMBCHUS_10:
case RG_BUY_BOMBCHU_20: case RG_BUY_BOMBCHUS_20:
case RG_BUY_DEKU_SEEDS_30: case RG_BUY_DEKU_SEEDS_30:
case RG_SOLD_OUT: case RG_SOLD_OUT:
case RG_BUY_BLUE_FIRE: case RG_BUY_BLUE_FIRE:

View File

@ -169,10 +169,6 @@ typedef enum {
LOGIC_GREG, LOGIC_GREG,
LOGIC_PIECE_OF_HEART, LOGIC_PIECE_OF_HEART,
LOGIC_HEART_CONTAINER, LOGIC_HEART_CONTAINER,
LOGIC_BOMBCHUS_5,
LOGIC_BOMBCHUS_10,
LOGIC_BOMBCHUS_20,
LOGIC_BOMBCHU_DROP,
LOGIC_NUTS, LOGIC_NUTS,
LOGIC_BUY_ARROW, LOGIC_BUY_ARROW,
LOGIC_BUY_BOMB, LOGIC_BUY_BOMB,
@ -888,7 +884,6 @@ typedef enum {
RC_MARKET_SHOOTING_GALLERY_REWARD, RC_MARKET_SHOOTING_GALLERY_REWARD,
RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE,
RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE,
RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS,
RC_MARKET_LOST_DOG, RC_MARKET_LOST_DOG,
RC_MARKET_TREASURE_CHEST_GAME_REWARD, RC_MARKET_TREASURE_CHEST_GAME_REWARD,
RC_MARKET_10_BIG_POES, RC_MARKET_10_BIG_POES,
@ -2071,7 +2066,6 @@ typedef enum {
RG_BOMBCHU_5, RG_BOMBCHU_5,
RG_BOMBCHU_10, RG_BOMBCHU_10,
RG_BOMBCHU_20, RG_BOMBCHU_20,
RG_BOMBCHU_DROP,
RG_ARROWS_5, RG_ARROWS_5,
RG_ARROWS_10, RG_ARROWS_10,
RG_ARROWS_30, RG_ARROWS_30,
@ -2100,8 +2094,8 @@ typedef enum {
RG_BUY_GORON_TUNIC, RG_BUY_GORON_TUNIC,
RG_BUY_ZORA_TUNIC, RG_BUY_ZORA_TUNIC,
RG_BUY_HEART, RG_BUY_HEART,
RG_BUY_BOMBCHU_10, RG_BUY_BOMBCHUS_10,
RG_BUY_BOMBCHU_20, RG_BUY_BOMBCHUS_20,
RG_BUY_DEKU_SEEDS_30, RG_BUY_DEKU_SEEDS_30,
RG_SOLD_OUT, RG_SOLD_OUT,
RG_BUY_BLUE_FIRE, RG_BUY_BLUE_FIRE,
@ -3315,10 +3309,9 @@ typedef enum {
RHT_BOMBS_5, RHT_BOMBS_5,
RHT_BOMBS_10, RHT_BOMBS_10,
RHT_BOMBS_20, RHT_BOMBS_20,
RHT_BOMBCHU_5, RHT_BOMBCHUS_5,
RHT_BOMBCHU_10, RHT_BOMBCHUS_10,
RHT_BOMBCHU_20, RHT_BOMBCHUS_20,
RHT_BOMBCHU_DROP,
RHT_ARROWS_5, RHT_ARROWS_5,
RHT_ARROWS_10, RHT_ARROWS_10,
RHT_ARROWS_30, RHT_ARROWS_30,
@ -3347,8 +3340,8 @@ typedef enum {
RHT_BUY_GORON_TUNIC, RHT_BUY_GORON_TUNIC,
RHT_BUY_ZORA_TUNIC, RHT_BUY_ZORA_TUNIC,
RHT_BUY_HEART, RHT_BUY_HEART,
RHT_BUY_BOMBCHU_10, RHT_BUY_BOMBCHUS_10,
RHT_BUY_BOMBCHU_20, RHT_BUY_BOMBCHUS_20,
RHT_BUY_DEKU_SEEDS_30, RHT_BUY_DEKU_SEEDS_30,
RHT_SOLD_OUT, RHT_SOLD_OUT,
RHT_BUY_BLUE_FIRE, RHT_BUY_BLUE_FIRE,

View File

@ -1293,7 +1293,6 @@ bool IsCheckShuffled(RandomizerCheck rc) {
loc->GetQuest() == RCQUEST_VANILLA && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsVanilla() loc->GetQuest() == RCQUEST_VANILLA && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsVanilla()
) && ) &&
(loc->GetRCType() != RCTYPE_SHOP || (showShops && loc->GetActorParams() > 0x03)) && (loc->GetRCType() != RCTYPE_SHOP || (showShops && loc->GetActorParams() > 0x03)) &&
(loc->GetRandomizerCheck() != RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS) &&
(rc != RC_TRIFORCE_COMPLETED || !hideTriforceCompleted) && (rc != RC_TRIFORCE_COMPLETED || !hideTriforceCompleted) &&
(rc != RC_GIFT_FROM_SAGES || !IS_RANDO) && (rc != RC_GIFT_FROM_SAGES || !IS_RANDO) &&
(loc->GetRCType() != RCTYPE_SCRUB || (loc->GetRCType() != RCTYPE_SCRUB ||

View File

@ -2643,17 +2643,13 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
else if (textId == TEXT_MEDIGORON && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){ else if (textId == TEXT_MEDIGORON && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){
messageEntry = messageEntry = ctx->GetHint(RH_MEDIGORON)->GetHintMessage(MF_AUTO_FORMAT); messageEntry = messageEntry = ctx->GetHint(RH_MEDIGORON)->GetHintMessage(MF_AUTO_FORMAT);
} }
else if (textId == TEXT_CARPET_SALESMAN_1 && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){ else if (textId == TEXT_CARPET_SALESMAN_1 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN) && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){
messageEntry = messageEntry = ctx->GetHint(RH_CARPET_SALESMAN)->GetHintMessage(MF_AUTO_FORMAT); messageEntry = ctx->GetHint(RH_CARPET_SALESMAN)->GetHintMessage(MF_AUTO_FORMAT);
} }
else if (textId == TEXT_CARPET_SALESMAN_2 && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){ else if (textId == TEXT_CARPET_SALESMAN_2 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN) && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId);
} Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN);//set here so we can actually check if the text is run, not a good solution
else if ((textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT) } else if (textId == TEXT_SKULLTULA_PEOPLE_IM_CURSED) {
&& ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
}
else if (textId == TEXT_SKULLTULA_PEOPLE_IM_CURSED) {
actorParams = GET_PLAYER(play)->targetActor->params; actorParams = GET_PLAYER(play)->targetActor->params;
if (actorParams == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)){ if (actorParams == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)){
messageEntry = ctx->GetHint(RH_KAK_10_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT); messageEntry = ctx->GetHint(RH_KAK_10_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
@ -2768,6 +2764,9 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
} }
else if (textId == TEXT_HBA_ALREADY_HAVE_1000 && ctx->GetOption(RSK_HBA_HINT)) { else if (textId == TEXT_HBA_ALREADY_HAVE_1000 && ctx->GetOption(RSK_HBA_HINT)) {
messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 3); messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 3);
}
else if (textId == TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY){
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
} }
else if (textId == TEXT_MASK_SHOP_SIGN && ctx->GetOption(RSK_MASK_SHOP_HINT)) { else if (textId == TEXT_MASK_SHOP_SIGN && ctx->GetOption(RSK_MASK_SHOP_HINT)) {
messageEntry = ctx->GetHint(RH_MASK_SHOP_HINT)->GetHintMessage(MF_AUTO_FORMAT); messageEntry = ctx->GetHint(RH_MASK_SHOP_HINT)->GetHintMessage(MF_AUTO_FORMAT);
@ -2793,17 +2792,17 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0); s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0);
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
messageEntry.Replace("[[gsCount]]", std::to_string(gsCount)); messageEntry.Replace("[[gsCount]]", std::to_string(gsCount));
} }
} } else if ((IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0)) &&
if (textId == TEXT_HEART_CONTAINER && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) { (textId == TEXT_BUY_BOMBCHUS_10_DESC || textId == TEXT_BUY_BOMBCHUS_10_PROMPT)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
} else if (textId == TEXT_HEART_CONTAINER && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER);
messageEntry.Replace("[[heartContainerCount]]", std::to_string(gSaveContext.sohStats.heartContainers + 1)); messageEntry.Replace("[[heartContainerCount]]", std::to_string(gSaveContext.sohStats.heartContainers + 1));
} } else if (textId == TEXT_HEART_PIECE && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) {
if (textId == TEXT_HEART_PIECE && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE);
messageEntry.Replace("[[heartPieceCount]]", std::to_string(gSaveContext.sohStats.heartPieces + 1)); messageEntry.Replace("[[heartPieceCount]]", std::to_string(gSaveContext.sohStats.heartPieces + 1));
} } else if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger(CVAR_ENHANCEMENT("MarketSneak"), 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) {
if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger(CVAR_ENHANCEMENT("MarketSneak"), 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT);
} }
if (textId == TEXT_FISHERMAN_LEAVE && CVarGetInteger(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 0)) { if (textId == TEXT_FISHERMAN_LEAVE && CVarGetInteger(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 0)) {

View File

@ -794,6 +794,11 @@ void DrawEnhancementsMenu() {
UIWidgets::Tooltip("Explosions are now a static size, like in Majora's Mask and OoT3D. Makes bombchu hovering much easier."); UIWidgets::Tooltip("Explosions are now a static size, like in Majora's Mask and OoT3D. Makes bombchu hovering much easier.");
UIWidgets::PaddedEnhancementCheckbox("Prevent Bombchus Forcing First-Person", CVAR_ENHANCEMENT("DisableFirstPersonChus"), true, false); UIWidgets::PaddedEnhancementCheckbox("Prevent Bombchus Forcing First-Person", CVAR_ENHANCEMENT("DisableFirstPersonChus"), true, false);
UIWidgets::Tooltip("Prevent bombchus from forcing the camera into first-person mode when released."); UIWidgets::Tooltip("Prevent bombchus from forcing the camera into first-person mode when released.");
UIWidgets::PaddedEnhancementCheckbox("Better Bombchu Shopping", CVAR_ENHANCEMENT("BetterBombchuShopping"), true, false,
IS_RANDO, "This setting is forcefully enabled when you are playing a randomizer.", UIWidgets::CheckboxGraphics::Checkmark);
UIWidgets::Tooltip("Bombchus do not sell out when bought, and a 10 pack of bombchus costs 99 rupees instead of 100."
"\n"
"Toggling while inside the shop will not change prices or restock any SOLD OUTs");
UIWidgets::PaddedEnhancementCheckbox("Aiming reticle for the bow/slingshot", CVAR_ENHANCEMENT("BowReticle"), true, false); UIWidgets::PaddedEnhancementCheckbox("Aiming reticle for the bow/slingshot", CVAR_ENHANCEMENT("BowReticle"), true, false);
UIWidgets::Tooltip("Aiming with a bow or slingshot will display a reticle as with the hookshot when the projectile is ready to fire."); UIWidgets::Tooltip("Aiming with a bow or slingshot will display a reticle as with the hookshot when the projectile is ready to fire.");
if (UIWidgets::PaddedEnhancementCheckbox("Allow strength equipment to be toggled", CVAR_ENHANCEMENT("ToggleStrength"), true, false)) { if (UIWidgets::PaddedEnhancementCheckbox("Allow strength equipment to be toggled", CVAR_ENHANCEMENT("ToggleStrength"), true, false)) {
@ -1072,7 +1077,7 @@ void DrawEnhancementsMenu() {
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1; OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1;
static const char* forceEnableBombchuDropsText = static const char* forceEnableBombchuDropsText =
"This setting is forcefully enabled because a savefile\nwith \"Enable Bombchu Drops\" is loaded."; "This setting is forcefully enabled because a savefile\nwith \"Enable Bombchu Drops\" is loaded.";
UIWidgets::PaddedEnhancementCheckbox("Enable Bombchu Drops", CVAR_ENHANCEMENT("BombchuDrops"), true, false, UIWidgets::PaddedEnhancementCheckbox("Enable Bombchu Drops", CVAR_ENHANCEMENT("EnableBombchuDrops"), true, false,
forceEnableBombchuDrops, forceEnableBombchuDropsText, UIWidgets::CheckboxGraphics::Checkmark); forceEnableBombchuDrops, forceEnableBombchuDropsText, UIWidgets::CheckboxGraphics::Checkmark);
UIWidgets::Tooltip("Bombchus will sometimes drop in place of bombs"); UIWidgets::Tooltip("Bombchus will sometimes drop in place of bombs");
UIWidgets::PaddedEnhancementCheckbox("Trees Drop Sticks", CVAR_ENHANCEMENT("TreesDropSticks"), true, false); UIWidgets::PaddedEnhancementCheckbox("Trees Drop Sticks", CVAR_ENHANCEMENT("TreesDropSticks"), true, false);

View File

@ -152,7 +152,7 @@ extern "C" void OTRMessage_Init()
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r[[gsCount]]%w symboles en tout!", "Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r[[gsCount]]%w symboles en tout!",
TEXTBOX_TYPE_BLUE)); TEXTBOX_TYPE_BLUE));
CustomMessageManager::Instance->CreateMessage( CustomMessageManager::Instance->CreateMessage(
customMessageTableID, TEXT_BUY_BOMBCHU_10_DESC, customMessageTableID, TEXT_BUY_BOMBCHUS_10_DESC,
CustomMessage("\x08%rBombchu 10 pieces 99 Rupees&%wThis looks like a toy mouse, but&it's actually a " CustomMessage("\x08%rBombchu 10 pieces 99 Rupees&%wThis looks like a toy mouse, but&it's actually a "
"self-propelled time&bomb!\x09\x0A", "self-propelled time&bomb!\x09\x0A",
"\x08%rKrabbelmine 10 Stück 99 Rubine&%wDas ist eine praktische Zeitbombe,&die Du als " "\x08%rKrabbelmine 10 Stück 99 Rubine&%wDas ist eine praktische Zeitbombe,&die Du als "
@ -160,7 +160,7 @@ extern "C" void OTRMessage_Init()
"\x08%rMissile 10 unités 99 Rubis&%wProfilée comme une souris&mécanique, cette arme est " "\x08%rMissile 10 unités 99 Rubis&%wProfilée comme une souris&mécanique, cette arme est "
"&destructrice!!!\x09\x0A")); "&destructrice!!!\x09\x0A"));
CustomMessageManager::Instance->CreateMessage( CustomMessageManager::Instance->CreateMessage(
customMessageTableID, TEXT_BUY_BOMBCHU_10_PROMPT, customMessageTableID, TEXT_BUY_BOMBCHUS_10_PROMPT,
CustomMessage("\x08" CustomMessage("\x08"
"Bombchu 10 pieces 99 Rupees\x09&&\x1B%gBuy&Don't buy%w", "Bombchu 10 pieces 99 Rupees\x09&&\x1B%gBuy&Don't buy%w",
"\x08Krabbelmine 10 Stück 99 Rubine\x09&&\x1B%gKaufen!&Nicht kaufen!%w", "\x08Krabbelmine 10 Stück 99 Rubine\x09&&\x1B%gKaufen!&Nicht kaufen!%w",
@ -187,4 +187,10 @@ extern "C" void OTRMessage_Init()
CustomMessage("Hey! Hey!&You can't take the rod out of here!&I'm serious!^Do you want to quit?&\x1B&%gYes&No%w", CustomMessage("Hey! Hey!&You can't take the rod out of here!&I'm serious!^Do you want to quit?&\x1B&%gYes&No%w",
"Hey! Hey!&Du kannst die Angel doch nicht&einfach mitnehmen!&Ganz im Ernst!^Möchtest Du aufhören?&\x1B&%gJa&Nein%w", "Hey! Hey!&Du kannst die Angel doch nicht&einfach mitnehmen!&Ganz im Ernst!^Möchtest Du aufhören?&\x1B&%gJa&Nein%w",
"Holà! Holà!&Les cannes ne sortent pas d'ici!&Je suis sérieux!^Voulez-vous arrêter?&\x1B&%gOui&Non%w")); //TODO Used AI translation as placeholder "Holà! Holà!&Les cannes ne sortent pas d'ici!&Je suis sérieux!^Voulez-vous arrêter?&\x1B&%gOui&Non%w")); //TODO Used AI translation as placeholder
CustomMessageManager::Instance->CreateMessage(
customMessageTableID, TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY,
CustomMessage("I'm sorry I can't sell you&these fine specimens,&they need an %rexperienced owner%w.^"
"Come back when you have&had %gBombchus%w of your own.",
"",
""));
} }

View File

@ -1454,6 +1454,7 @@ void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) {
CLOSE_DISPS(play->state.gfxCtx); CLOSE_DISPS(play->state.gfxCtx);
} }
// #region [Randomizer] [Enchancment]
/** /**
* Sometimes convert the given drop ID into a bombchu. * Sometimes convert the given drop ID into a bombchu.
* Returns the new drop type ID. * Returns the new drop type ID.
@ -1483,6 +1484,7 @@ s16 EnItem00_ConvertBombDropToBombchu(s16 dropId) {
} }
} }
} }
// #endregion
/** /**
* Converts a given drop type ID based on link's current age, health and owned items. * Converts a given drop type ID based on link's current age, health and owned items.
@ -1501,11 +1503,14 @@ s16 func_8001F404(s16 dropId) {
} }
} }
if ((CVarGetInteger(CVAR_ENHANCEMENT("BombchuDrops"), 0) || // #region [Randomizer] [Enchancment]
if ((CVarGetInteger(CVAR_ENHANCEMENT("EnableBombchuDrops"), 0) ||
(IS_RANDO && Randomizer_GetSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1)) && (IS_RANDO && Randomizer_GetSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1)) &&
(dropId == ITEM00_BOMBS_A || dropId == ITEM00_BOMBS_B || dropId == ITEM00_BOMBS_SPECIAL)) { (dropId == ITEM00_BOMBS_A || dropId == ITEM00_BOMBS_B || dropId == ITEM00_BOMBS_SPECIAL) &&
(!IS_RANDO || Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) || INV_CONTENT(ITEM_BOMB) != ITEM_NONE)) {
dropId = EnItem00_ConvertBombDropToBombchu(dropId); dropId = EnItem00_ConvertBombDropToBombchu(dropId);
} }
// #endregion
// This is convoluted but it seems like it must be a single condition to match // This is convoluted but it seems like it must be a single condition to match
// clang-format off // clang-format off

View File

@ -1870,7 +1870,7 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
return; return;
} }
// Count any bombchu pack as bombchus // Count any bombchu pack as bombchus
if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_DROP) || item == RG_PROGRESSIVE_BOMBCHUS) { if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) {
if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = 0) { if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = 0) {
gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time; gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time;
} }

View File

@ -19,7 +19,7 @@ void EnGirlA_Update(Actor* thisx, PlayState* play);
void EnGirlA_SetItemOutOfStock(PlayState* play, EnGirlA* this); void EnGirlA_SetItemOutOfStock(PlayState* play, EnGirlA* this);
void EnGirlA_UpdateStockedItem(PlayState* play, EnGirlA* this); void EnGirlA_UpdateStockedItem(PlayState* play, EnGirlA* this);
void EnGirlA_InitializeItemAction(EnGirlA* this, PlayState* play); void EnGirlA_WaitForObject(EnGirlA* this, PlayState* play);
void EnGirlA_Update2(EnGirlA* this, PlayState* play); void EnGirlA_Update2(EnGirlA* this, PlayState* play);
void func_80A3C498(Actor* thisx, PlayState* play, s32 flags); void func_80A3C498(Actor* thisx, PlayState* play, s32 flags);
void EnGirlA_Draw(Actor* thisx, PlayState* play); void EnGirlA_Draw(Actor* thisx, PlayState* play);
@ -213,7 +213,7 @@ static ShopItemEntry shopItemEntries[] = {
/* SI_ZORA_TUNIC */ /* SI_ZORA_TUNIC */
{ OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, NULL, 300, 1, 0x00AB, 0x0094, GI_TUNIC_ZORA, EnGirlA_CanBuy_ZoraTunic, { OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, NULL, 300, 1, 0x00AB, 0x0094, GI_TUNIC_ZORA, EnGirlA_CanBuy_ZoraTunic,
EnGirlA_ItemGive_ZoraTunic, EnGirlA_BuyEvent_ZoraTunic }, EnGirlA_ItemGive_ZoraTunic, EnGirlA_BuyEvent_ZoraTunic },
/* SI_HEART */ /* SI_RECOVERY_HEART */
{ OBJECT_GI_HEART, GID_HEART, NULL, 10, 16, 0x00AC, 0x0095, GI_HEART, EnGirlA_CanBuy_Health, { OBJECT_GI_HEART, GID_HEART, NULL, 10, 16, 0x00AC, 0x0095, GI_HEART, EnGirlA_CanBuy_Health,
EnGirlA_ItemGive_Health, EnGirlA_BuyEvent_ShieldDiscount }, EnGirlA_ItemGive_Health, EnGirlA_BuyEvent_ShieldDiscount },
/* SI_MILK_BOTTLE */ /* SI_MILK_BOTTLE */
@ -327,78 +327,139 @@ void EnGirlA_SetupAction(EnGirlA* this, EnGirlAActionFunc func) {
this->actionFunc = func; this->actionFunc = func;
} }
s32 EnGirlA_TryChangeShopItem(EnGirlA* this, PlayState* play) { // #region SOH [Enhancement] [Randomizer]
s32 EnGirlA_TryChangeShopItemShip(EnGirlA* this, PlayState* play) {
if (!(IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0))){
switch (this->actor.params) {
case SI_BOMBCHU_10_2:
if (Flags_GetItemGetInf(ITEMGETINF_06)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
case SI_BOMBCHU_10_3:
if (Flags_GetItemGetInf(ITEMGETINF_07)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
case SI_BOMBCHU_20_3:
if (Flags_GetItemGetInf(ITEMGETINF_08)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
case SI_BOMBCHU_20_4:
if (Flags_GetItemGetInf(ITEMGETINF_09)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
case SI_BOMBCHU_10_4:
if (Flags_GetItemGetInf(ITEMGETINF_0A)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
case SI_BOMBCHU_10_1:
if (Flags_GetItemGetInf(ITEMGETINF_03)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
case SI_BOMBCHU_20_1:
if (Flags_GetItemGetInf(ITEMGETINF_04)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
case SI_BOMBCHU_20_2:
if (Flags_GetItemGetInf(ITEMGETINF_05)) {
this->actor.params = SI_SOLD_OUT;
return true;
}
break;
}
}
if (this->actor.params == SI_MILK_BOTTLE){
if (Flags_GetItemGetInf(ITEMGETINF_TALON_BOTTLE)) {
this->actor.params = SI_RECOVERY_HEART;
return true;
}
} else if (this->actor.params == SI_RANDOMIZED_ITEM) {
ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->randoSlotIndex);
if (Flags_GetRandomizerInf(shopItemIdentity.randomizerInf)) {
this->actor.params = SI_SOLD_OUT;
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId);
// Undo the rotation for spiritual stones
if (getItemEntry.getItemId >= RG_KOKIRI_EMERALD && getItemEntry.getItemId <= RG_ZORA_SAPPHIRE) {
this->actor.shape.rot.y = this->actor.shape.rot.y - 20000;
}
return true;
}
}
return false;
}
// #endregion
s32 EnGirlA_TryChangeShopItem(EnGirlA* this) {
switch (this->actor.params) { switch (this->actor.params) {
case SI_MILK_BOTTLE: case SI_MILK_BOTTLE:
if (Flags_GetItemGetInf(ITEMGETINF_TALON_BOTTLE)) { if (GET_ITEMGETINF(ITEMGETINF_TALON_BOTTLE)) {
this->actor.params = SI_HEART; this->actor.params = SI_RECOVERY_HEART;
return true; return true;
} }
break; break;
case SI_BOMBCHU_10_2: case SI_BOMBCHU_10_2:
if (Flags_GetItemGetInf(ITEMGETINF_06)) { if (GET_ITEMGETINF(ITEMGETINF_06)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_BOMBCHU_10_3: case SI_BOMBCHU_10_3:
if (Flags_GetItemGetInf(ITEMGETINF_07)) { if (GET_ITEMGETINF(ITEMGETINF_07)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_BOMBCHU_20_3: case SI_BOMBCHU_20_3:
if (Flags_GetItemGetInf(ITEMGETINF_08)) { if (GET_ITEMGETINF(ITEMGETINF_08)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_BOMBCHU_20_4: case SI_BOMBCHU_20_4:
if (Flags_GetItemGetInf(ITEMGETINF_09)) { if (GET_ITEMGETINF(ITEMGETINF_09)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_BOMBCHU_10_4: case SI_BOMBCHU_10_4:
if (Flags_GetItemGetInf(ITEMGETINF_0A)) { if (GET_ITEMGETINF(ITEMGETINF_0A)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_BOMBCHU_10_1: case SI_BOMBCHU_10_1:
if (Flags_GetItemGetInf(ITEMGETINF_03)) { if (GET_ITEMGETINF(ITEMGETINF_03)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_BOMBCHU_20_1: case SI_BOMBCHU_20_1:
if (Flags_GetItemGetInf(ITEMGETINF_04)) { if (GET_ITEMGETINF(ITEMGETINF_04)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_BOMBCHU_20_2: case SI_BOMBCHU_20_2:
if (Flags_GetItemGetInf(ITEMGETINF_05)) { if (GET_ITEMGETINF(ITEMGETINF_05)) {
this->actor.params = SI_SOLD_OUT; this->actor.params = SI_SOLD_OUT;
return true; return true;
} }
break; break;
case SI_RANDOMIZED_ITEM: {
ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->randoSlotIndex);
if (Flags_GetRandomizerInf(shopItemIdentity.randomizerInf)) {
this->actor.params = SI_SOLD_OUT;
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId);
// Undo the rotation for spiritual stones
if (getItemEntry.getItemId >= RG_KOKIRI_EMERALD && getItemEntry.getItemId <= RG_ZORA_SAPPHIRE) {
this->actor.shape.rot.y = this->actor.shape.rot.y - 20000;
}
return true;
}
break;
}
} }
return false; return false;
} }
@ -413,12 +474,12 @@ void EnGirlA_InitItem(EnGirlA* this, PlayState* play) {
osSyncPrintf("引数がおかしいよ(arg_data=%d)\n", this->actor.params); osSyncPrintf("引数がおかしいよ(arg_data=%d)\n", this->actor.params);
osSyncPrintf(VT_RST); osSyncPrintf(VT_RST);
assert((params >= SI_MAX) && (params < 0)); assert((params >= SI_MAX) && (params < 0));
//ASSERT(0, "0", "../z_en_girlA.c", 1421); zret assert, currently errors due to missing macro
return; return;
} }
if (!IS_RANDO || Randomizer_GetSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF) { // #region [Randomizer]
this->objBankIndex = Object_GetIndex(&play->objectCtx, shopItemEntries[params].objID); if (IS_RANDO && !Randomizer_GetSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF) {
} else {
s16 objectId = shopItemEntries[params].objID; s16 objectId = shopItemEntries[params].objID;
if (params == SI_RANDOMIZED_ITEM) { if (params == SI_RANDOMIZED_ITEM) {
@ -428,33 +489,48 @@ void EnGirlA_InitItem(EnGirlA* this, PlayState* play) {
objectId = getItemEntry.objectId; objectId = getItemEntry.objectId;
} }
this->objBankIndex = Object_GetIndex(&play->objectCtx, objectId); this->requiredObjectSlot = Object_GetIndex(&play->objectCtx, objectId);
// If the object isn't normally spawned by the shop scene, then spawn it now // If the object isn't normally spawned by the shop scene, then spawn it now
if (this->objBankIndex < 0) { if (this->requiredObjectSlot < 0) {
this->objBankIndex = Object_Spawn(&play->objectCtx, objectId); this->requiredObjectSlot = Object_Spawn(&play->objectCtx, objectId);
} }
} }
// #endregion
else {
this->requiredObjectSlot = Object_GetIndex(&play->objectCtx, shopItemEntries[params].objID);
}
if (this->objBankIndex < 0) { if (this->requiredObjectSlot < 0) {
Actor_Kill(&this->actor); Actor_Kill(&this->actor);
osSyncPrintf(VT_COL(RED, WHITE)); osSyncPrintf(VT_COL(RED, WHITE));
osSyncPrintf("バンクが無いよ!!(%s)\n", sShopItemDescriptions[params]); osSyncPrintf("バンクが無いよ!!(%s)\n", sShopItemDescriptions[params]);
osSyncPrintf(VT_RST); osSyncPrintf(VT_RST);
assert(this->objBankIndex < 0); //ASSERT(0, "0", "../z_en_girlA.c", 1434); zret assert, currently errors due to missing macro
return; return;
} }
this->actor.params = params; this->actor.params = params;
this->actionFunc2 = EnGirlA_InitializeItemAction; this->actionFunc2 = EnGirlA_WaitForObject;
} }
void EnGirlA_Init(Actor* thisx, PlayState* play) { void EnGirlA_Init(Actor* thisx, PlayState* play) {
EnGirlA* this = (EnGirlA*)thisx; // #region [Randomizer] [Enhancment]
if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0)){
EnGirlA* this = (EnGirlA*)thisx;
EnGirlA_TryChangeShopItem(this, play); EnGirlA_TryChangeShopItemShip(this, play);
EnGirlA_InitItem(this, play); EnGirlA_InitItem(this, play);
osSyncPrintf("%s(%2d)初期設定\n", sShopItemDescriptions[this->actor.params], this->actor.params); osSyncPrintf("%s(%2d)初期設定\n", sShopItemDescriptions[this->actor.params], this->actor.params);
}
// #endregion
else {
EnGirlA* this = (EnGirlA*)thisx;
EnGirlA_TryChangeShopItem(this);
EnGirlA_InitItem(this, play);
osSyncPrintf("%s(%2d)初期設定\n", sShopItemDescriptions[this->actor.params], this->actor.params);
}
} }
void EnGirlA_Destroy(Actor* thisx, PlayState* play) { void EnGirlA_Destroy(Actor* thisx, PlayState* play) {
@ -1035,10 +1111,12 @@ void EnGirlA_BuyEvent_ObtainBombchuPack(PlayState* play, EnGirlA* this) {
Rupees_ChangeBy(-this->basePrice); Rupees_ChangeBy(-this->basePrice);
// Normally, buying a bombchu pack sets a flag indicating the pack is now sold out // Normally, buying a bombchu pack sets a flag indicating the pack is now sold out
// If we're in rando, skip setting that flag so they can be purchased repeatedly // If they're in logic for rando, skip setting that flag so they can be purchased repeatedly
if (IS_RANDO) { // #region [Enhancment]
if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0)) {
return; return;
} }
// #endregion
switch (this->actor.params) { switch (this->actor.params) {
case SI_BOMBCHU_10_2: case SI_BOMBCHU_10_2:
@ -1153,21 +1231,35 @@ void EnGirlA_SetItemOutOfStock(PlayState* play, EnGirlA* this) {
} }
void EnGirlA_UpdateStockedItem(PlayState* play, EnGirlA* this) { void EnGirlA_UpdateStockedItem(PlayState* play, EnGirlA* this) {
ShopItemEntry* itemEntry; // #region [Randomizer] [Enhancment]
if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0)){
ShopItemEntry* itemEntry;
if (EnGirlA_TryChangeShopItemShip(this, play)) {
EnGirlA_InitItem(this, play);
itemEntry = &shopItemEntries[this->actor.params];
if (EnGirlA_TryChangeShopItem(this, play)) { if (this->actor.params == SI_RANDOMIZED_ITEM) {
EnGirlA_InitItem(this, play); ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->randoSlotIndex);
itemEntry = &shopItemEntries[this->actor.params]; this->actor.textId = 0x9100 + (shopItemIdentity.randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1);
} else {
if (this->actor.params == SI_RANDOMIZED_ITEM) { this->actor.textId = itemEntry->itemDescTextId;
ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->randoSlotIndex); }
this->actor.textId = 0x9100 + (shopItemIdentity.randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1);
} else { } else {
this->actor.textId = itemEntry->itemDescTextId; this->isInvisible = false;
this->actor.draw = EnGirlA_Draw;
}
}
// #endregion
else {
ShopItemEntry* itemEntry;
if (EnGirlA_TryChangeShopItem(this)) {
EnGirlA_InitItem(this, play);
itemEntry = &shopItemEntries[this->actor.params];
this->actor.textId = itemEntry->itemDescTextId;
} else {
this->isInvisible = false;
this->actor.draw = EnGirlA_Draw;
} }
} else {
this->isInvisible = false;
this->actor.draw = EnGirlA_Draw;
} }
} }
@ -1186,13 +1278,13 @@ s32 EnGirlA_TrySetMaskItemDescription(EnGirlA* this, PlayState* play) {
return false; return false;
} }
void EnGirlA_InitializeItemAction(EnGirlA* this, PlayState* play) { void EnGirlA_WaitForObject(EnGirlA* this, PlayState* play) {
s16 params = this->actor.params; s16 params = this->actor.params;
ShopItemEntry* itemEntry = &shopItemEntries[params]; ShopItemEntry* itemEntry = &shopItemEntries[params];
if (Object_IsLoaded(&play->objectCtx, this->objBankIndex)) { if (Object_IsLoaded(&play->objectCtx, this->requiredObjectSlot)) {
this->actor.flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED; this->actor.flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED;
this->actor.objBankIndex = this->objBankIndex; this->actor.objBankIndex = this->requiredObjectSlot;
switch (this->actor.params) { switch (this->actor.params) {
case SI_KEATON_MASK: case SI_KEATON_MASK:
if (Flags_GetItemGetInf(ITEMGETINF_38)) { if (Flags_GetItemGetInf(ITEMGETINF_38)) {
@ -1255,49 +1347,78 @@ void EnGirlA_InitializeItemAction(EnGirlA* this, PlayState* play) {
if (!EnGirlA_TrySetMaskItemDescription(this, play)) { if (!EnGirlA_TrySetMaskItemDescription(this, play)) {
EnGirlA_SetItemDescription(play, this); EnGirlA_SetItemDescription(play, this);
} }
// #region [Enhancment] [Randomizer]
this->setOutOfStockFunc = EnGirlA_SetItemOutOfStock; if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0)) {
this->updateStockedItemFunc = EnGirlA_UpdateStockedItem; this->setOutOfStockFunc = EnGirlA_SetItemOutOfStock;
this->getItemId = itemEntry->getItemId; this->updateStockedItemFunc = EnGirlA_UpdateStockedItem;
this->canBuyFunc = itemEntry->canBuyFunc; this->getItemId = itemEntry->getItemId;
this->itemGiveFunc = itemEntry->itemGiveFunc; this->canBuyFunc = itemEntry->canBuyFunc;
this->buyEventFunc = itemEntry->buyEventFunc; this->itemGiveFunc = itemEntry->itemGiveFunc;
// If chus are in logic, make the 10 pack affordable without a wallet upgrade this->buyEventFunc = itemEntry->buyEventFunc;
if (IS_RANDO && this->getItemId == GI_BOMBCHUS_10) { // If Better Bombchu Shopping is on, make the 10 pack affordable without a wallet upgrade
this->basePrice = 99; if (this->getItemId == GI_BOMBCHUS_10) {
} else { this->basePrice = 99;
this->basePrice = itemEntry->price; }
} else {
this->itemCount = itemEntry->count; this->basePrice = itemEntry->price;
this->hiliteFunc = itemEntry->hiliteFunc;
this->giDrawId = itemEntry->giDrawId;
osSyncPrintf("%s(%2d)\n", sShopItemDescriptions[params], params);
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
Actor_SetScale(&this->actor, 0.25f);
this->actor.shape.yOffset = 24.0f;
this->actor.shape.shadowScale = 4.0f;
this->actor.floorHeight = this->actor.home.pos.y;
this->actor.gravity = 0.0f;
EnGirlA_SetupAction(this, EnGirlA_Noop);
this->isInitialized = true;
this->actionFunc2 = EnGirlA_Update2;
this->isSelected = false;
this->yRotation = 0;
this->yRotationInit = this->actor.shape.rot.y;
if (params == SI_RANDOMIZED_ITEM) {
ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->randoSlotIndex);
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId);
this->actor.textId = 0x9100 + (shopItemIdentity.randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1);
this->itemBuyPromptTextId = 0x9100 + ((shopItemIdentity.randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + NUM_SHOP_ITEMS);
this->getItemId = getItemEntry.getItemId;
this->basePrice = shopItemIdentity.itemPrice;
this->giDrawId = getItemEntry.gid;
// Correct the rotation for spiritual stones, but only if mysterious shuffle isn't on, else it's obvious what's there in shops
if (!CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && (getItemEntry.getItemId >= RG_KOKIRI_EMERALD && getItemEntry.getItemId <= RG_ZORA_SAPPHIRE)) {
this->actor.shape.rot.y = this->actor.shape.rot.y + 20000;
} }
this->itemCount = itemEntry->count;
this->hiliteFunc = itemEntry->hiliteFunc;
this->giDrawId = itemEntry->giDrawId;
osSyncPrintf("%s(%2d)\n", sShopItemDescriptions[params], params);
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
Actor_SetScale(&this->actor, 0.25f);
this->actor.shape.yOffset = 24.0f;
this->actor.shape.shadowScale = 4.0f;
this->actor.floorHeight = this->actor.home.pos.y;
this->actor.gravity = 0.0f;
EnGirlA_SetupAction(this, EnGirlA_Noop);
this->isInitialized = true;
this->actionFunc2 = EnGirlA_Update2;
this->isSelected = false;
this->yRotation = 0;
this->yRotationInit = this->actor.shape.rot.y;
if (params == SI_RANDOMIZED_ITEM) {
ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->randoSlotIndex);
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId);
this->actor.textId = 0x9100 + (shopItemIdentity.randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1);
this->itemBuyPromptTextId = 0x9100 + ((shopItemIdentity.randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + NUM_SHOP_ITEMS);
this->getItemId = getItemEntry.getItemId;
this->basePrice = shopItemIdentity.itemPrice;
this->giDrawId = getItemEntry.gid;
// Correct the rotation for spiritual stones, but only if mysterious shuffle isn't on, else it's obvious what's there in shops
if (!CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && (getItemEntry.getItemId >= RG_KOKIRI_EMERALD && getItemEntry.getItemId <= RG_ZORA_SAPPHIRE)) {
this->actor.shape.rot.y = this->actor.shape.rot.y + 20000;
}
}
}
// #endregion
else {
this->setOutOfStockFunc = EnGirlA_SetItemOutOfStock;
this->updateStockedItemFunc = EnGirlA_UpdateStockedItem;
this->getItemId = itemEntry->getItemId;
this->canBuyFunc = itemEntry->canBuyFunc;
this->itemGiveFunc = itemEntry->itemGiveFunc;
this->buyEventFunc = itemEntry->buyEventFunc;
this->basePrice = itemEntry->price;
this->itemCount = itemEntry->count;
this->hiliteFunc = itemEntry->hiliteFunc;
this->giDrawId = itemEntry->giDrawId;
osSyncPrintf("%s(%2d)\n", sShopItemDescriptions[params], params);
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
Actor_SetScale(&this->actor, 0.25f);
this->actor.shape.yOffset = 24.0f;
this->actor.shape.shadowScale = 4.0f;
this->actor.floorHeight = this->actor.home.pos.y;
this->actor.gravity = 0.0f;
EnGirlA_SetupAction(this, EnGirlA_Noop);
this->isInitialized = true;
this->actionFunc2 = EnGirlA_Update2;
this->isSelected = false;
this->yRotation = 0;
this->yRotationInit = this->actor.shape.rot.y;
} }
} }
} }

View File

@ -15,7 +15,7 @@ typedef struct EnGirlA {
/* 0x0000 */ Actor actor; /* 0x0000 */ Actor actor;
/* 0x014C */ SkelAnime skelAnime; /* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ EnGirlAActionFunc actionFunc; /* 0x0190 */ EnGirlAActionFunc actionFunc;
/* 0x0194 */ s8 objBankIndex; /* 0x0194 */ s8 requiredObjectSlot;
/* 0x0198 */ EnGirlAActionFunc actionFunc2; /* 0x0198 */ EnGirlAActionFunc actionFunc2;
/* 0x019C */ s32 isInitialized; /* 0x019C */ s32 isInitialized;
/* 0x01A0 */ s16 itemBuyPromptTextId; /* 0x01A0 */ s16 itemBuyPromptTextId;
@ -53,7 +53,7 @@ typedef enum {
/* 0x0D */ SI_DEKU_SHIELD, /* 0x0D */ SI_DEKU_SHIELD,
/* 0x0E */ SI_GORON_TUNIC, /* 0x0E */ SI_GORON_TUNIC,
/* 0x0F */ SI_ZORA_TUNIC, /* 0x0F */ SI_ZORA_TUNIC,
/* 0x10 */ SI_HEART, /* 0x10 */ SI_RECOVERY_HEART,
/* 0x11 */ SI_MILK_BOTTLE, /* 0x11 */ SI_MILK_BOTTLE,
/* 0x12 */ SI_WEIRD_EGG, /* 0x12 */ SI_WEIRD_EGG,
/* 0x13 */ SI_19, /* 0x13 */ SI_19,

View File

@ -131,7 +131,8 @@ void func_80A89160(EnJs* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_CARPET_SALESMAN, true, this)) { if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_CARPET_SALESMAN, true, this)) {
this->actor.parent = NULL; this->actor.parent = NULL;
En_Js_SetupAction(this, func_80A8910C); En_Js_SetupAction(this, func_80A8910C);
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); // Moved into the text handling to patch a text bug, not a great solution though
// Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN);
} else { } else {
GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10); GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10);
gSaveContext.pendingSale = itemEntry.itemId; gSaveContext.pendingSale = itemEntry.itemId;
@ -148,8 +149,14 @@ void func_80A891C4(EnJs* this, PlayState* play) {
Message_ContinueTextbox(play, 0x6075); Message_ContinueTextbox(play, 0x6075);
func_80A89008(this); func_80A89008(this);
} else { } else {
Rupees_ChangeBy(-200); if (GameInteractor_Should(VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN, true, this) ||
En_Js_SetupAction(this, func_80A89160); (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_CARPET_SALESMAN, true, this))){
Rupees_ChangeBy(-200);
En_Js_SetupAction(this, func_80A89160);
} else{
Message_ContinueTextbox(play, 0x6073);
func_80A89008(this);
}
} }
break; break;
case 1: // no case 1: // no

View File

@ -206,7 +206,7 @@ ShopItem sShopkeeperStores[][8] = {
{ SI_DEKU_SEEDS_30, -50, 52, -20 }, { SI_DEKU_SEEDS_30, -50, 52, -20 },
{ SI_ARROWS_10, -50, 76, -20 }, { SI_ARROWS_10, -50, 76, -20 },
{ SI_ARROWS_30, -80, 52, -3 }, { SI_ARROWS_30, -80, 52, -3 },
{ SI_HEART, -80, 76, -3 } }, { SI_RECOVERY_HEART, -80, 76, -3 } },
{ { SI_GREEN_POTION, 50, 52, -20 }, { { SI_GREEN_POTION, 50, 52, -20 },
{ SI_BLUE_FIRE, 50, 76, -20 }, { SI_BLUE_FIRE, 50, 76, -20 },
@ -238,7 +238,7 @@ ShopItem sShopkeeperStores[][8] = {
{ { SI_HYLIAN_SHIELD, 50, 52, -20 }, { { SI_HYLIAN_SHIELD, 50, 52, -20 },
{ SI_BOMBS_5_R35, 50, 76, -20 }, { SI_BOMBS_5_R35, 50, 76, -20 },
{ SI_DEKU_NUTS_5, 80, 52, -3 }, { SI_DEKU_NUTS_5, 80, 52, -3 },
{ SI_HEART, 80, 76, -3 }, { SI_RECOVERY_HEART, 80, 76, -3 },
{ SI_ARROWS_10, -50, 52, -20 }, { SI_ARROWS_10, -50, 52, -20 },
{ SI_ARROWS_50, -50, 76, -20 }, { SI_ARROWS_50, -50, 76, -20 },
{ SI_DEKU_STICK, -80, 52, -3 }, { SI_DEKU_STICK, -80, 52, -3 },
@ -247,7 +247,7 @@ ShopItem sShopkeeperStores[][8] = {
{ { SI_HYLIAN_SHIELD, 50, 52, -20 }, { { SI_HYLIAN_SHIELD, 50, 52, -20 },
{ SI_BOMBS_5_R25, 50, 76, -20 }, { SI_BOMBS_5_R25, 50, 76, -20 },
{ SI_DEKU_NUTS_5, 80, 52, -3 }, { SI_DEKU_NUTS_5, 80, 52, -3 },
{ SI_HEART, 80, 76, -3 }, { SI_RECOVERY_HEART, 80, 76, -3 },
{ SI_ARROWS_10, -50, 52, -20 }, { SI_ARROWS_10, -50, 52, -20 },
{ SI_ARROWS_50, -50, 76, -20 }, { SI_ARROWS_50, -50, 76, -20 },
{ SI_DEKU_STICK, -80, 52, -3 }, { SI_DEKU_STICK, -80, 52, -3 },
@ -256,15 +256,15 @@ ShopItem sShopkeeperStores[][8] = {
{ { SI_MILK_BOTTLE, 50, 52, -20 }, { { SI_MILK_BOTTLE, 50, 52, -20 },
{ SI_DEKU_NUTS_5, 50, 76, -20 }, { SI_DEKU_NUTS_5, 50, 76, -20 },
{ SI_DEKU_NUTS_10, 80, 52, -3 }, { SI_DEKU_NUTS_10, 80, 52, -3 },
{ SI_HEART, 80, 76, -3 }, { SI_RECOVERY_HEART, 80, 76, -3 },
{ SI_WEIRD_EGG, -50, 52, -20 }, { SI_WEIRD_EGG, -50, 52, -20 },
{ SI_DEKU_STICK, -50, 76, -20 }, { SI_DEKU_STICK, -50, 76, -20 },
{ SI_HEART, -80, 52, -3 }, { SI_RECOVERY_HEART, -80, 52, -3 },
{ SI_HEART, -80, 76, -3 } }, { SI_RECOVERY_HEART, -80, 76, -3 } },
{ { SI_ZORA_TUNIC, 50, 52, -20 }, { { SI_ZORA_TUNIC, 50, 52, -20 },
{ SI_ARROWS_10, 50, 76, -20 }, { SI_ARROWS_10, 50, 76, -20 },
{ SI_HEART, 80, 52, -3 }, { SI_RECOVERY_HEART, 80, 52, -3 },
{ SI_ARROWS_30, 80, 76, -3 }, { SI_ARROWS_30, 80, 76, -3 },
{ SI_DEKU_NUTS_5, -50, 52, -20 }, { SI_DEKU_NUTS_5, -50, 52, -20 },
{ SI_ARROWS_50, -50, 76, -20 }, { SI_ARROWS_50, -50, 76, -20 },
@ -276,9 +276,9 @@ ShopItem sShopkeeperStores[][8] = {
{ SI_BOMBS_20, 80, 52, -3 }, { SI_BOMBS_20, 80, 52, -3 },
{ SI_BOMBS_30, 80, 76, -3 }, { SI_BOMBS_30, 80, 76, -3 },
{ SI_GORON_TUNIC, -50, 52, -20 }, { SI_GORON_TUNIC, -50, 52, -20 },
{ SI_HEART, -50, 76, -20 }, { SI_RECOVERY_HEART, -50, 76, -20 },
{ SI_RED_POTION_R40, -80, 52, -3 }, { SI_RED_POTION_R40, -80, 52, -3 },
{ SI_HEART, -80, 76, -3 } }, { SI_RECOVERY_HEART, -80, 76, -3 } },
{ { SI_19, 50, 52, -20 }, { { SI_19, 50, 52, -20 },
{ SI_19, 50, 76, -20 }, { SI_19, 50, 76, -20 },