Shuffle Bean Souls (#5833)

This commit is contained in:
Philip Dubé
2025-12-31 01:27:37 +00:00
committed by GitHub
parent c688923272
commit d41273f34b
27 changed files with 523 additions and 107 deletions

View File

@@ -1964,6 +1964,8 @@ void StaticData::HintTable_Init_Item() {
CustomMessage("a gold fragment", /*german*/"ein Goldfragment", /*french*/"un fragment d'or")});
// /*spanish*/un fragmento dorado
hintTextTable[RHT_BEAN_SOUL] = HintText(CustomMessage("a bean soul", /*german*/"eine bohnenseele", /*french*/"une âme de haricot"));
hintTextTable[RHT_GOHMA_SOUL] = HintText(CustomMessage("the soul of Gohma", /*german*/"Gohmas Seele", /*french*/"l'Âme de Gohma"),
{
CustomMessage("something webbed", /*german*/"etwas Verwobenes", /*french*/"un truc entoilé")

View File

@@ -662,15 +662,16 @@ void GenerateItemPool() {
}
}
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) {
// if beans unshuffled, put on bean guy, otherwise if not starting with beans, add to pool
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).IsNot(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) &&
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).IsNot(RO_SHUFFLE_MERCHANTS_ALL)) {
ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true);
} else if (!ctx->GetOption(RSK_STARTING_BEANS)) {
AddItemToMainPool(RG_MAGIC_BEAN_PACK);
if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) {
AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK);
}
ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK);
} else {
ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true);
}
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) ||
@@ -752,6 +753,19 @@ void GenerateItemPool() {
ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, false, true);
}
if (ctx->GetOption(RSK_SHUFFLE_BEAN_SOULS)) {
AddItemToMainPool(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);
AddItemToMainPool(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL);
AddItemToMainPool(RG_DESERT_COLOSSUS_BEAN_SOUL);
AddItemToMainPool(RG_GERUDO_VALLEY_BEAN_SOUL);
AddItemToMainPool(RG_GRAVEYARD_BEAN_SOUL);
AddItemToMainPool(RG_KOKIRI_FOREST_BEAN_SOUL);
AddItemToMainPool(RG_LAKE_HYLIA_BEAN_SOUL);
AddItemToMainPool(RG_LOST_WOODS_BRIDGE_BEAN_SOUL);
AddItemToMainPool(RG_LOST_WOODS_BEAN_SOUL);
AddItemToMainPool(RG_ZORAS_RIVER_BEAN_SOUL);
}
if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) {
AddItemToMainPool(RG_GOHMA_SOUL);
AddItemToMainPool(RG_KING_DODONGO_SOUL);

View File

@@ -28,6 +28,7 @@ extern "C" {
#include "objects/object_bv/object_bv.h"
#include "objects/object_gnd/object_gnd.h"
#include "objects/object_fd/object_fd.h"
#include "objects/object_mamenoki/object_mamenoki.h"
#include "objects/object_mo/object_mo.h"
#include "objects/object_sst/object_sst.h"
#include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h"
@@ -929,6 +930,17 @@ extern "C" void DrawGanon(PlayState* play) {
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMagicBeanSeedlingDL);
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEntry) {
s16 slot;
if (getItemEntry->getItemId != RG_ICE_TRAP) {

View File

@@ -14,6 +14,7 @@ void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawMasterSword(PlayState* play, GetItemEntry* getItemEntry);

View File

@@ -55,11 +55,13 @@ extern "C" {
#include "src/overlays/actors/ovl_En_Xc/z_en_xc.h"
#include "src/overlays/actors/ovl_Fishing/z_fishing.h"
#include "src/overlays/actors/ovl_En_Mk/z_en_mk.h"
#include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h"
#include "draw.h"
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
extern void func_8084DFAC(PlayState* play, Player* player);
extern void func_80B8FE00(ObjBean*); // trigger planting
extern void Player_SetupActionPreserveAnimMovement(PlayState* play, Player* player, PlayerActionFunc actionFunc,
s32 flags);
extern s32 Player_SetupWaitForPutAway(PlayState* play, Player* player, AfterPutAwayFunc func);
@@ -933,6 +935,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) {
*should = gSaveContext.rupees >=
OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPrice();
} else if (RAND_GET_OPTION(RSK_SKIP_PLANTING_BEANS)) {
*should = gSaveContext.rupees >= 60;
}
break;
}
@@ -1268,6 +1272,27 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN);
enMs->actionFunc = (EnMsActionFunc)EnMs_Wait;
*should = false;
} else if (RAND_GET_OPTION(RSK_SKIP_PLANTING_BEANS)) {
Rupees_ChangeBy(-60);
Item_Give(NULL, ITEM_BEAN);
BEANS_BOUGHT = 10;
AMMO(ITEM_BEAN) = 0;
gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_CRATER].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_TRAIL].swch |= (1 << 6);
gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 24);
gSaveContext.sceneFlags[SCENE_GERUDO_VALLEY].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_GRAVEYARD].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 9);
gSaveContext.sceneFlags[SCENE_LAKE_HYLIA].swch |= (1 << 1);
gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 4) | (1 << 18);
gSaveContext.sceneFlags[SCENE_ZORAS_RIVER].swch |= (1 << 3);
ObjBean* bean = (ObjBean*)Actor_Find(&gPlayState->actorCtx, ACTOR_OBJ_BEAN, ACTORCAT_BG);
if (bean != nullptr) {
Flags_SetSwitch(gPlayState, bean->dyna.actor.params & 0x3F);
func_80B8FE00(bean);
}
enMs->actionFunc = (EnMsActionFunc)EnMs_Wait;
*should = false;
}
break;
}
@@ -2249,6 +2274,49 @@ void RandomizerOnActorInitHandler(void* actorRef) {
return;
}
if (RAND_GET_OPTION(RSK_SHUFFLE_BEAN_SOULS)) {
if (actor->id == ACTOR_OBJ_BEAN) {
RandomizerInf currentBeanSoulRandInf = RAND_INF_MAX;
switch (gPlayState->sceneNum) {
case SCENE_DEATH_MOUNTAIN_CRATER:
currentBeanSoulRandInf = RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL;
break;
case SCENE_DEATH_MOUNTAIN_TRAIL:
currentBeanSoulRandInf = RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL;
break;
case SCENE_DESERT_COLOSSUS:
currentBeanSoulRandInf = RAND_INF_DESERT_COLOSSUS_BEAN_SOUL;
break;
case SCENE_GERUDO_VALLEY:
currentBeanSoulRandInf = RAND_INF_GERUDO_VALLEY_BEAN_SOUL;
break;
case SCENE_GRAVEYARD:
currentBeanSoulRandInf = RAND_INF_GRAVEYARD_BEAN_SOUL;
break;
case SCENE_KOKIRI_FOREST:
currentBeanSoulRandInf = RAND_INF_KOKIRI_FOREST_BEAN_SOUL;
break;
case SCENE_LAKE_HYLIA:
currentBeanSoulRandInf = RAND_INF_LAKE_HYLIA_BEAN_SOUL;
break;
case SCENE_LOST_WOODS:
if ((actor->params & 0x3F) == 4) {
currentBeanSoulRandInf = RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL;
} else {
currentBeanSoulRandInf = RAND_INF_LOST_WOODS_BEAN_SOUL;
}
break;
case SCENE_ZORAS_RIVER:
currentBeanSoulRandInf = RAND_INF_ZORAS_RIVER_BEAN_SOUL;
break;
}
if (currentBeanSoulRandInf != RAND_INF_MAX && !Flags_GetRandomizerInf(currentBeanSoulRandInf)) {
Actor_Kill(actor);
return;
}
}
}
// If child is in the adult shooting gallery or adult in the child shooting gallery, then despawn the shooting
// gallery man
if (actor->id == ACTOR_EN_SYATEKI_MAN && RAND_GET_OPTION(RSK_SHUFFLE_INTERIOR_ENTRANCES) &&

View File

@@ -316,6 +316,27 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 40);
itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50);
// Misc.
itemTable[RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL] = Item(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, Text{ "Death Mountain Crater Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL] = Item(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, Text{ "Death Mountain Trail Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_DESERT_COLOSSUS_BEAN_SOUL] = Item(RG_DESERT_COLOSSUS_BEAN_SOUL, Text{ "Desert Colossus Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_DESERT_COLOSSUS_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DESERT_COLOSSUS_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_GERUDO_VALLEY_BEAN_SOUL] = Item(RG_GERUDO_VALLEY_BEAN_SOUL, Text{ "Gerudo Valley Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_GERUDO_VALLEY_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_GERUDO_VALLEY_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_GRAVEYARD_BEAN_SOUL] = Item(RG_GRAVEYARD_BEAN_SOUL, Text{ "Graveyard Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_GRAVEYARD_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_GRAVEYARD_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_KOKIRI_FOREST_BEAN_SOUL] = Item(RG_KOKIRI_FOREST_BEAN_SOUL, Text{ "Kokiri Forest Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_KOKIRI_FOREST_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_KOKIRI_FOREST_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_LAKE_HYLIA_BEAN_SOUL] = Item(RG_LAKE_HYLIA_BEAN_SOUL, Text{ "Lake Hylia Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_LAKE_HYLIA_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_LAKE_HYLIA_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_LOST_WOODS_BRIDGE_BEAN_SOUL] = Item(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, Text{ "Lost Woods Bridge Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_LOST_WOODS_BRIDGE_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_LOST_WOODS_BRIDGE_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_LOST_WOODS_BEAN_SOUL] = Item(RG_LOST_WOODS_BEAN_SOUL, Text{ "Lost Woods Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_LOST_WOODS_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_LOST_WOODS_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_ZORAS_RIVER_BEAN_SOUL] = Item(RG_ZORAS_RIVER_BEAN_SOUL, Text{ "Zora's River Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_ZORAS_RIVER_BEAN_SOUL, OBJECT_GI_BEAN, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_ZORAS_RIVER_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout);
itemTable[RG_GOHMA_SOUL] = Item(RG_GOHMA_SOUL, Text{ "Gohma's Soul", "Âme de Gohma", "Gohmas Seele" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_CAN_SUMMON_GOHMA, RHT_GOHMA_SOUL, RG_GOHMA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_GOHMA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_KING_DODONGO_SOUL] = Item(RG_KING_DODONGO_SOUL, Text{ "King Dodongo's Soul", "Âme du Roi Dodongo", "König Dodongos Seele" }, ITEMTYPE_ITEM, 0xE1, true, LOGIC_CAN_SUMMON_KINGDODONGO, RHT_KING_DODONGO_SOUL, RG_KING_DODONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);

View File

@@ -505,8 +505,11 @@ Rando::Entrance* Region::GetExit(RandomizerRegion exitToReturn) {
return nullptr;
}
bool Region::CanPlantBeanCheck() const {
return Rando::Context::GetInstance()->GetLogic()->GetAmmo(ITEM_BEAN) > 0 && BothAgesCheck();
bool Region::CanPlantBeanCheck(RandomizerGet bean) const {
auto ctx = Rando::Context::GetInstance();
auto logic = ctx->GetLogic();
return logic->HasItem(bean) && logic->GetAmmo(ITEM_BEAN) > 0 &&
(ctx->GetOption(RSK_SKIP_PLANTING_BEANS) || BothAgesCheck());
}
bool Region::AllAccountedFor() const {
@@ -675,49 +678,55 @@ bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn con
return areaTable[region].MQSpiritShared(condition, true, anyAge);
}
bool BeanPlanted(const RandomizerRegion region) {
bool BeanPlanted(const RandomizerGet bean) {
auto logic = Rando::Context::GetInstance()->GetLogic();
// flag irrelevant if plant won't spawn
if (!logic->HasItem(bean)) {
return false;
}
// swchFlag found using the Actor Viewer to get the Obj_Bean parameters & 0x3F
// not tested with multiple OTRs, but can be automated similarly to GetDungeonSmallKeyDoors
SceneID sceneID;
uint8_t swchFlag;
switch (region) {
case RR_ZORAS_RIVER:
switch (bean) {
case RG_ZORAS_RIVER_BEAN_SOUL:
sceneID = SceneID::SCENE_ZORAS_RIVER;
swchFlag = 3;
break;
case RR_THE_GRAVEYARD:
case RG_GRAVEYARD_BEAN_SOUL:
sceneID = SceneID::SCENE_GRAVEYARD;
swchFlag = 3;
break;
case RR_KOKIRI_FOREST:
case RG_KOKIRI_FOREST_BEAN_SOUL:
sceneID = SceneID::SCENE_KOKIRI_FOREST;
swchFlag = 9;
break;
case RR_THE_LOST_WOODS:
case RG_LOST_WOODS_BRIDGE_BEAN_SOUL:
sceneID = SceneID::SCENE_LOST_WOODS;
swchFlag = 4;
break;
case RR_LW_BEYOND_MIDO:
case RG_LOST_WOODS_BEAN_SOUL:
sceneID = SceneID::SCENE_LOST_WOODS;
swchFlag = 18;
break;
case RR_DEATH_MOUNTAIN_TRAIL:
case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL:
sceneID = SceneID::SCENE_DEATH_MOUNTAIN_TRAIL;
swchFlag = 6;
break;
case RR_LAKE_HYLIA:
case RG_LAKE_HYLIA_BEAN_SOUL:
sceneID = SceneID::SCENE_LAKE_HYLIA;
swchFlag = 1;
break;
case RR_GERUDO_VALLEY:
case RG_GERUDO_VALLEY_BEAN_SOUL:
sceneID = SceneID::SCENE_GERUDO_VALLEY;
swchFlag = 3;
break;
case RR_DMC_CENTRAL_LOCAL:
case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL:
sceneID = SceneID::SCENE_DEATH_MOUNTAIN_CRATER;
swchFlag = 3;
break;
case RR_DESERT_COLOSSUS:
case RG_DESERT_COLOSSUS_BEAN_SOUL:
sceneID = SceneID::SCENE_DESERT_COLOSSUS;
swchFlag = 24;
break;
@@ -733,7 +742,7 @@ bool BeanPlanted(const RandomizerRegion region) {
if (gPlayState != nullptr && gPlayState->sceneNum == sceneID) {
swch = gPlayState->actorCtx.flags.swch;
} else if (sceneID != SCENE_ID_MAX) {
swch = Rando::Context::GetInstance()->GetLogic()->GetSaveContext()->sceneFlags[sceneID].swch;
swch = logic->GetSaveContext()->sceneFlags[sceneID].swch;
} else {
swch = 0;
}
@@ -741,8 +750,8 @@ bool BeanPlanted(const RandomizerRegion region) {
return swch >> swchFlag & 1;
}
bool CanPlantBean(const RandomizerRegion region) {
return areaTable[region].CanPlantBeanCheck() || BeanPlanted(region);
bool CanPlantBean(const RandomizerRegion region, const RandomizerGet bean) {
return areaTable[region].CanPlantBeanCheck(bean) || BeanPlanted(bean);
}
bool BothAges(const RandomizerRegion region) {

View File

@@ -207,7 +207,7 @@ class Region {
return hereVal;
}
bool CanPlantBeanCheck() const;
bool CanPlantBeanCheck(RandomizerGet bean) const;
bool AllAccountedFor() const;
bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false);
@@ -224,7 +224,7 @@ bool Here(const RandomizerRegion region,
condition); // RANDOTODO make a less stupid way to check own at either age than self referencing with this
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
bool CanPlantBean(const RandomizerRegion region);
bool CanPlantBean(const RandomizerRegion region, RandomizerGet bean);
bool BothAges(const RandomizerRegion region);
bool ChildCanAccess(const RandomizerRegion region);
bool AdultCanAccess(const RandomizerRegion region);

View File

@@ -66,7 +66,7 @@ void RegionTable_Init_DeathMountainCrater() {
areaTable[RR_DMC_CENTRAL_NEARBY] = Region("DMC Central Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, {
//Locations
LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))),
LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))),
LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
}, {
//Exits
@@ -75,10 +75,10 @@ void RegionTable_Init_DeathMountainCrater() {
areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", SCENE_DEATH_MOUNTAIN_CRATER, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}),
}, {
//Locations
LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanAttack()),
LOCATION(RC_DMC_NEAR_PLATFORM_RED_RUPEE, logic->IsChild),
LOCATION(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
@@ -87,14 +87,14 @@ void RegionTable_Init_DeathMountainCrater() {
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
}, {
//Exits
Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}),
Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL);}),
Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);}),
Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}),
Entrance(RR_DMC_DISTANT_PLATFORM, []{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}),
});

View File

@@ -7,25 +7,25 @@ void RegionTable_Init_DeathMountainTrail() {
// clang-format off
areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", SCENE_DEATH_MOUNTAIN_TRAIL, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}),
}, {
//Locations
LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))),
LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))),
LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))),
LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))),
LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash()),
LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash())) && logic->CanGetNightTimeGS()),
LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash())) && logic->CanGetNightTimeGS()),
LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()),
LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits
Entrance(RR_KAK_BEHIND_GATE, []{return true;}),
Entrance(RR_GORON_CITY, []{return true;}),
Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->BlastOrSmash();}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}),
Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->BlastOrSmash();}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}),
Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, []{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->IsAdult;}),
Entrance(RR_DMT_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
});

View File

@@ -10,13 +10,13 @@ void RegionTable_Init_DesertColossus() {
EventAccess(LOGIC_BUG_ACCESS, []{return true;}),
}, {
//Locations
LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)),
LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL)),
LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()),
LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_COLOSSUS_GOSSIP_STONE, true),

View File

@@ -23,15 +23,15 @@ void RegionTable_Init_GerudoValley() {
areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", SCENE_GERUDO_VALLEY, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS));}),
}, {
//Locations
LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child
LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL)),//can use cucco as child
LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanAttack()),
LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_GV_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GV_GOSSIP_STONE, true),

View File

@@ -12,13 +12,13 @@ void RegionTable_Init_Graveyard() {
EventAccess(LOGIC_BORROW_BUNNY_HOOD, []{return logic->IsChild && logic->AtDay && logic->Get(LOGIC_BORROW_SPOOKY_MASK) && logic->HasItem(RG_CHILD_WALLET);}),
}, {
//Locations
LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change
LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()),
LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_GRAVEYARD_BEAN_SOUL) && logic->CanAttack()),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GRAVEYARD_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GRAVEYARD_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GRAVEYARD_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_GY_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_GY_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_GY_GRASS_3, logic->CanCutShrubs()),
@@ -31,7 +31,7 @@ void RegionTable_Init_Graveyard() {
LOCATION(RC_GY_GRASS_10, logic->CanCutShrubs()),
LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()),
LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()),
LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()),
LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()),
}, {
//Exits
Entrance(RR_GRAVEYARD_SHIELD_GRAVE, []{return logic->IsAdult || logic->AtNight;}),

View File

@@ -7,17 +7,17 @@ void RegionTable_Init_KokiriForest() {
// clang-format off
areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", SCENE_KOKIRI_FOREST, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairyExceptSuns() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairyExceptSuns() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}),
}, {
//Locations
LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild),
LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()),
LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanAttack()),
LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild),
@@ -28,13 +28,13 @@ void RegionTable_Init_KokiriForest() {
LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild),
LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild),
LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild),
LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild),
LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild),
LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild),

View File

@@ -7,7 +7,7 @@ void RegionTable_Init_LakeHylia() {
// clang-format off
areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", SCENE_LAKE_HYLIA, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || logic->CanUse(RG_STICKS) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || logic->CanUse(RG_STICKS) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_BUG_ACCESS, []{return logic->IsChild && logic->CanCutShrubs();}),
EventAccess(LOGIC_CHILD_SCARECROW, []{return logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}),
EventAccess(LOGIC_ADULT_SCARECROW, []{return logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}),
@@ -15,17 +15,17 @@ void RegionTable_Init_LakeHylia() {
//Locations
LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)),
LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->Get(LOGIC_WATER_TEMPLE_CLEAR) && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)),
LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))),
LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)) && logic->CanAvoidEnemy(RE_GUAY, false)),
LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()),
LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)),
LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanGetNightTimeGS()),
LOCATION(RC_LH_FRONT_RUPEE, logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)),
LOCATION(RC_LH_MIDDLE_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LH_BACK_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LH_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
//You can walk along the edge of the lake to get these without swimming, the fairy is created going backwards, which is convenient here
@@ -84,7 +84,7 @@ void RegionTable_Init_LakeHylia() {
Entrance(RR_HYRULE_FIELD, []{return true;}),
Entrance(RR_LH_FROM_SHORTCUT, []{return true;}),
Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}),
Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}),
Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)));}),
Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}),
Entrance(RR_LH_FROM_WATER_TEMPLE, []{return true;}),
Entrance(RR_LH_GROTTO, []{return true;}),

View File

@@ -12,7 +12,7 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", SCENE_LOST_WOODS, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairyExceptSuns() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairyExceptSuns() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_BUG_ACCESS, []{return logic->IsChild && logic->CanCutShrubs();}),
EventAccess(LOGIC_BORROW_SPOOKY_MASK, []{return logic->IsChild && logic->Get(LOGIC_BORROW_SKULL_MASK) && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET);}),
}, {
@@ -32,7 +32,7 @@ void RegionTable_Init_LostWoods() {
LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 5),
LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku() && GetCheckPrice() <= GetWalletCapacity()),
LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanAttack()),
//RANDOTODO handle collecting some of these as you leave the shortcut from the other side
LOCATION(RC_LW_SHORTCUT_RUPEE_1, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_2, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
@@ -42,9 +42,9 @@ void RegionTable_Init_LostWoods() {
LOCATION(RC_LW_SHORTCUT_RUPEE_6, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_7, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_SHORTCUT_RUPEE_8, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
@@ -56,7 +56,7 @@ void RegionTable_Init_LostWoods() {
//Exits
Entrance(RR_LW_FOREST_EXIT, []{return true;}),
Entrance(RR_GC_WOODS_WARP, []{return true;}),
Entrance(RR_LW_BRIDGE, []{return (logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_LW_BRIDGE, []{return (logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS, RG_LOST_WOODS_BRIDGE_BEAN_SOUL) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_ZR_FROM_SHORTCUT, []{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LOST_WOOD_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash());}),
Entrance(RR_LW_BEYOND_MIDO, []{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}),
Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, []{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}),
@@ -64,17 +64,17 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_LW_BEYOND_MIDO] = Region("LW Beyond Mido", SCENE_LOST_WOODS, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanUse(RG_STICKS);}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanUse(RG_STICKS) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS));}),
}, {
//Locations
LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku() && GetCheckPrice() <= GetWalletCapacity()),
LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku() && GetCheckPrice() <= GetWalletCapacity()),
LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->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->CanSpawnSoilSkull() && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))),
LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && ((CanPlantBean(RR_LW_BEYOND_MIDO, RG_LOST_WOODS_BEAN_SOUL) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (ctx->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->CanSpawnSoilSkull(RG_LOST_WOODS_BEAN_SOUL) && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))),
LOCATION(RC_LW_BOULDER_RUPEE, logic->BlastOrSmash()),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_LW_GRASS_4, logic->CanCutShrubs()),
LOCATION(RC_LW_GRASS_5, logic->CanCutShrubs()),
LOCATION(RC_LW_GRASS_6, logic->CanCutShrubs()),

View File

@@ -29,7 +29,7 @@ void RegionTable_Init_ZoraRiver() {
areaTable[RR_ZORAS_RIVER] = Region("Zora River", SCENE_ZORAS_RIVER, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_STICKS)) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS));}),
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_STICKS)) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS));}),
}, {
//Locations
LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->IsChild && GetCheckPrice() <= GetWalletCapacity()/* && CanUse(SPEAK_HYLIAN)*/),
@@ -45,9 +45,9 @@ void RegionTable_Init_ZoraRiver() {
LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH) && logic->CanGetNightTimeGS()),
LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT) && logic->CanGetNightTimeGS()),
LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_HOOKSHOT) && logic->CanGetNightTimeGS()),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))),

View File

@@ -132,6 +132,17 @@ bool Logic::HasItem(RandomizerGet itemName) {
case RG_OCARINA_C_RIGHT_BUTTON:
case RG_OCARINA_C_DOWN_BUTTON:
case RG_OCARINA_C_UP_BUTTON:
// Bean Souls
case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL:
case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL:
case RG_DESERT_COLOSSUS_BEAN_SOUL:
case RG_GERUDO_VALLEY_BEAN_SOUL:
case RG_GRAVEYARD_BEAN_SOUL:
case RG_KOKIRI_FOREST_BEAN_SOUL:
case RG_LAKE_HYLIA_BEAN_SOUL:
case RG_LOST_WOODS_BRIDGE_BEAN_SOUL:
case RG_LOST_WOODS_BEAN_SOUL:
case RG_ZORAS_RIVER_BEAN_SOUL:
// Boss Souls
case RG_GOHMA_SOUL:
case RG_KING_DODONGO_SOUL:
@@ -571,6 +582,7 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW);
case RE_KEESE:
case RE_FIRE_KEESE:
case RE_GUAY:
switch (distance) {
case ED_CLOSE:
case ED_SHORT_JUMPSLASH:
@@ -583,15 +595,15 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
[[fallthrough]];
case ED_BOMB_THROW:
// RANDOTODO test dins and chu range in a practical example
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
// RANDOTODO test chu range in a practical example
killed = killed || (!inWater && CanUse(RG_BOMB_BAG)) || (enemy == RE_GUAY && CanUse(RG_DINS_FIRE));
[[fallthrough]];
case ED_BOOMERANG:
// RANDOTODO test dins and chu range in a practical example
// RANDOTODO test chu range in a practical example
killed = killed || CanUse(RG_BOOMERANG);
[[fallthrough]];
case ED_HOOKSHOT:
// RANDOTODO test dins, bomb and chu range in a practical example
// RANDOTODO test chu range in a practical example
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
[[fallthrough]];
case ED_LONGSHOT:
@@ -912,6 +924,7 @@ bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity
return !grounded || CanUse(RG_NUTS);
case RE_KEESE:
case RE_FIRE_KEESE:
case RE_GUAY:
return CanUse(RG_NUTS);
case RE_BLUE_BUBBLE:
// RANDOTODO Trick to use shield hylian shield as child to stun these guys
@@ -956,6 +969,7 @@ bool Logic::CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance, bool
break;
case RE_KEESE:
case RE_FIRE_KEESE:
case RE_GUAY:
return true;
default:
return aboveLink || (distance <= ED_BOOMERANG && CanUse(RG_BOOMERANG));
@@ -1173,8 +1187,8 @@ bool Logic::BlastOrSmash() {
return HasExplosives() || CanUse(RG_MEGATON_HAMMER);
}
bool Logic::CanSpawnSoilSkull() {
return IsChild && CanUse(RG_BOTTLE_WITH_BUGS);
bool Logic::CanSpawnSoilSkull(RandomizerGet bean) {
return IsChild && CanUse(RG_BOTTLE_WITH_BUGS) && HasItem(bean);
}
bool Logic::CanReflectNuts() {
@@ -1402,6 +1416,16 @@ std::map<RandomizerGet, uint32_t> Logic::RandoGetToRandInf = {
{ RG_ZELDAS_LETTER, RAND_INF_ZELDAS_LETTER },
{ RG_WEIRD_EGG, RAND_INF_WEIRD_EGG },
{ RG_RUTOS_LETTER, RAND_INF_OBTAINED_RUTOS_LETTER },
{ RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL },
{ RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL },
{ RG_DESERT_COLOSSUS_BEAN_SOUL, RAND_INF_DESERT_COLOSSUS_BEAN_SOUL },
{ RG_GERUDO_VALLEY_BEAN_SOUL, RAND_INF_GERUDO_VALLEY_BEAN_SOUL },
{ RG_GRAVEYARD_BEAN_SOUL, RAND_INF_GRAVEYARD_BEAN_SOUL },
{ RG_KOKIRI_FOREST_BEAN_SOUL, RAND_INF_KOKIRI_FOREST_BEAN_SOUL },
{ RG_LAKE_HYLIA_BEAN_SOUL, RAND_INF_LAKE_HYLIA_BEAN_SOUL },
{ RG_LOST_WOODS_BRIDGE_BEAN_SOUL, RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL },
{ RG_LOST_WOODS_BEAN_SOUL, RAND_INF_LOST_WOODS_BEAN_SOUL },
{ RG_ZORAS_RIVER_BEAN_SOUL, RAND_INF_ZORAS_RIVER_BEAN_SOUL },
{ RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL },
{ RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL },
{ RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL },
@@ -1768,6 +1792,16 @@ void Logic::ApplyItemEffect(Item& item, bool state) {
case RG_RUTOS_LETTER:
SetRandoInf(RAND_INF_OBTAINED_RUTOS_LETTER, state);
break;
case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL:
case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL:
case RG_DESERT_COLOSSUS_BEAN_SOUL:
case RG_GERUDO_VALLEY_BEAN_SOUL:
case RG_GRAVEYARD_BEAN_SOUL:
case RG_KOKIRI_FOREST_BEAN_SOUL:
case RG_LAKE_HYLIA_BEAN_SOUL:
case RG_LOST_WOODS_BRIDGE_BEAN_SOUL:
case RG_LOST_WOODS_BEAN_SOUL:
case RG_ZORAS_RIVER_BEAN_SOUL:
case RG_GOHMA_SOUL:
case RG_KING_DODONGO_SOUL:
case RG_BARINADE_SOUL:
@@ -2319,6 +2353,19 @@ void Logic::Reset(bool resetSaveContext /*= true*/) {
SetRandoInf(RAND_INF_FISHING_POLE_FOUND, true);
}
if (ctx->GetOption(RSK_SHUFFLE_BEAN_SOULS).Is(false)) {
SetRandoInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, true);
SetRandoInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, true);
SetRandoInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL, true);
SetRandoInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL, true);
SetRandoInf(RAND_INF_GRAVEYARD_BEAN_SOUL, true);
SetRandoInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL, true);
SetRandoInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL, true);
SetRandoInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL, true);
SetRandoInf(RAND_INF_LOST_WOODS_BEAN_SOUL, true);
SetRandoInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL, true);
}
// If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in
// vanilla FiT
if (!IsFireLoopLocked() && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) {

View File

@@ -76,7 +76,7 @@ class Logic {
bool BlueFire();
bool HasExplosives();
bool BlastOrSmash();
bool CanSpawnSoilSkull();
bool CanSpawnSoilSkull(RandomizerGet bean);
bool CanReflectNuts();
bool CanCutShrubs();
bool CanStunDeku();

View File

@@ -627,6 +627,8 @@ void Settings::CreateOptionDescriptions() {
"Start with the ability to summon Pierre the Scarecrow. Pulling out an Ocarina in the usual locations will "
"automatically summon him.\n"
"With \"Shuffle Ocarina Buttons\" enabled, you'll need at least two Ocarina buttons to summon him.";
mOptionDescriptions[RSK_SKIP_PLANTING_BEANS] = "Beans will be planted once you find beans.\n"
"If bean souls are shuffled, you must find soul still.";
mOptionDescriptions[RSK_ITEM_POOL] = "Sets how many major items appear in the item pool.\n"
"\n"
"Plentiful - Extra major items are added to the pool.\n"
@@ -776,6 +778,8 @@ void Settings::CreateOptionDescriptions() {
"location is reachable. When disabled, only "
"required items and locations to beat the game "
"will be guaranteed reachable.";
mOptionDescriptions[RSK_SHUFFLE_BEAN_SOULS] =
"Shuffle 10 bean souls which must be found to spawn corresponding soil / plant.";
mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS] =
"Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its "
"respective soul."

View File

@@ -5579,7 +5579,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) {
void Randomizer::CreateCustomMessages() {
// RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED
// with GIMESSAGE(getItemID, itemID, english, german, french).
const std::array<GetItemMessage, 112> getItemMessages = { {
const std::array<GetItemMessage, 122> getItemMessages = { {
GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!",
"Félicitation! Vous avez trouvé %gGreg%w!"),
GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!",
@@ -5855,6 +5855,27 @@ void Randomizer::CreateCustomMessages() {
"Du erhältst die %rKindergeldbörse%w!&Jetzt kannst Du bis&zu %y99 Rubine%w mit Dir führen!",
"Vous obtenez la %rPetite Bourse%w!&Elle peut contenir jusqu'à %y99 rubis%w!"),
GIMESSAGE(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, ITEM_BEAN, "You found the&%gDeath Mountain Crater Bean Soul%w!",
TODO_TRANSLATE, TODO_TRANSLATE),
GIMESSAGE(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, ITEM_BEAN, "You found the&%gDeath Mountain Trail Bean Soul%w!",
TODO_TRANSLATE, TODO_TRANSLATE),
GIMESSAGE(RG_DESERT_COLOSSUS_BEAN_SOUL, ITEM_BEAN, "You found the&%gDesert Colossus Bean Soul%w!",
TODO_TRANSLATE, TODO_TRANSLATE),
GIMESSAGE(RG_GERUDO_VALLEY_BEAN_SOUL, ITEM_BEAN, "You found the&%gGerudo Valley Bean Soul%w!", TODO_TRANSLATE,
TODO_TRANSLATE),
GIMESSAGE(RG_GRAVEYARD_BEAN_SOUL, ITEM_BEAN, "You found the&%gGraveyard Bean Soul%w!", TODO_TRANSLATE,
TODO_TRANSLATE),
GIMESSAGE(RG_KOKIRI_FOREST_BEAN_SOUL, ITEM_BEAN, "You found the&%gKokiri Forest Bean Soul%w!", TODO_TRANSLATE,
TODO_TRANSLATE),
GIMESSAGE(RG_LAKE_HYLIA_BEAN_SOUL, ITEM_BEAN, "You found the&%gLake Hylia Bean Soul%w!", TODO_TRANSLATE,
TODO_TRANSLATE),
GIMESSAGE(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, ITEM_BEAN, "You found the&%gLost Wood's Bridge Bean Soul%w!",
TODO_TRANSLATE, TODO_TRANSLATE),
GIMESSAGE(RG_LOST_WOODS_BEAN_SOUL, ITEM_BEAN, "You found the&%gLost Wood's Theatre Bean Soul%w!",
TODO_TRANSLATE, TODO_TRANSLATE),
GIMESSAGE(RG_ZORAS_RIVER_BEAN_SOUL, ITEM_BEAN, "You found the&%gZora's River Bean Soul%w!", TODO_TRANSLATE,
TODO_TRANSLATE),
GIMESSAGE(RG_GOHMA_SOUL, ITEM_BIG_POE, "You found the soul for %gGohma%w!",
"Du hast die Seele von&%gGohma%w gefunden!", "Vous obtenez l'âme de %gGohma%w!"),
GIMESSAGE(RG_KING_DODONGO_SOUL, ITEM_BIG_POE, "You found the soul for %rKing&Dodongo%w!",
@@ -6086,6 +6107,16 @@ std::map<RandomizerGet, RandomizerInf> randomizerGetToRandInf = {
{ RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN },
{ RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT },
{ RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT },
{ RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL },
{ RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL },
{ RG_DESERT_COLOSSUS_BEAN_SOUL, RAND_INF_DESERT_COLOSSUS_BEAN_SOUL },
{ RG_GERUDO_VALLEY_BEAN_SOUL, RAND_INF_GERUDO_VALLEY_BEAN_SOUL },
{ RG_GRAVEYARD_BEAN_SOUL, RAND_INF_GRAVEYARD_BEAN_SOUL },
{ RG_KOKIRI_FOREST_BEAN_SOUL, RAND_INF_KOKIRI_FOREST_BEAN_SOUL },
{ RG_LAKE_HYLIA_BEAN_SOUL, RAND_INF_LAKE_HYLIA_BEAN_SOUL },
{ RG_LOST_WOODS_BRIDGE_BEAN_SOUL, RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL },
{ RG_LOST_WOODS_BEAN_SOUL, RAND_INF_LOST_WOODS_BEAN_SOUL },
{ RG_ZORAS_RIVER_BEAN_SOUL, RAND_INF_ZORAS_RIVER_BEAN_SOUL },
{ RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL },
{ RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL },
{ RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL },
@@ -6321,6 +6352,18 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) {
INV_CONTENT(ITEM_BEAN) = ITEM_BEAN;
AMMO(ITEM_BEAN) = 10;
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_PLANTING_BEANS)) {
gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_CRATER].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_TRAIL].swch |= (1 << 6);
gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 24);
gSaveContext.sceneFlags[SCENE_GERUDO_VALLEY].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_GRAVEYARD].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 9);
gSaveContext.sceneFlags[SCENE_LAKE_HYLIA].swch |= (1 << 1);
gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 4) | (1 << 18);
gSaveContext.sceneFlags[SCENE_ZORAS_RIVER].swch |= (1 << 3);
AMMO(ITEM_BEAN) = 0;
}
}
break;
case RG_DOUBLE_DEFENSE:

View File

@@ -4367,6 +4367,16 @@ typedef enum {
RG_BUY_RED_POTION_50,
RG_TRIFORCE,
RG_TRIFORCE_PIECE,
RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL,
RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL,
RG_DESERT_COLOSSUS_BEAN_SOUL,
RG_GERUDO_VALLEY_BEAN_SOUL,
RG_GRAVEYARD_BEAN_SOUL,
RG_KOKIRI_FOREST_BEAN_SOUL,
RG_LAKE_HYLIA_BEAN_SOUL,
RG_LOST_WOODS_BRIDGE_BEAN_SOUL,
RG_LOST_WOODS_BEAN_SOUL,
RG_ZORAS_RIVER_BEAN_SOUL,
RG_GOHMA_SOUL,
RG_KING_DODONGO_SOUL,
RG_BARINADE_SOUL,
@@ -5570,6 +5580,7 @@ typedef enum {
RHT_DEKU_STICK_CAPACITY_20,
RHT_DEKU_STICK_CAPACITY_30,
RHT_TRIFORCE_PIECE,
RHT_BEAN_SOUL,
RHT_GOHMA_SOUL,
RHT_KING_DODONGO_SOUL,
RHT_BARINADE_SOUL,
@@ -6258,12 +6269,14 @@ typedef enum {
RSK_SKIP_CHILD_ZELDA,
RSK_STARTING_STICKS,
RSK_STARTING_NUTS,
RSK_STARTING_BEANS,
RSK_FULL_WALLETS,
RSK_SHUFFLE_CHEST_MINIGAME,
RSK_BIG_POE_COUNT,
RSK_SKIP_EPONA_RACE,
RSK_COMPLETE_MASK_QUEST,
RSK_SKIP_SCARECROWS_SONG,
RSK_SKIP_PLANTING_BEANS,
RSK_SKULLS_SUNS_SONG,
RSK_SHUFFLE_ADULT_TRADE,
RSK_SHUFFLE_MERCHANTS,
@@ -6341,6 +6354,7 @@ typedef enum {
RSK_TRIFORCE_HUNT,
RSK_TRIFORCE_HUNT_PIECES_TOTAL,
RSK_TRIFORCE_HUNT_PIECES_REQUIRED,
RSK_SHUFFLE_BEAN_SOULS,
RSK_SHUFFLE_BOSS_SOULS,
RSK_FISHSANITY,
RSK_FISHSANITY_POND_COUNT,
@@ -6891,6 +6905,7 @@ typedef enum {
RE_GOHMA_LARVA,
RE_KEESE,
RE_FIRE_KEESE,
RE_GUAY,
RE_MAD_SCRUB,
RE_BLUE_BUBBLE,
RE_POE,

View File

@@ -182,6 +182,17 @@ DEFINE_RAND_INF(RAND_INF_ADULT_LOACH)
DEFINE_RAND_INF(RAND_INF_10_BIG_POES)
DEFINE_RAND_INF(RAND_INF_GRANT_GANONS_BOSSKEY)
DEFINE_RAND_INF(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_GERUDO_VALLEY_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_GRAVEYARD_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_KOKIRI_FOREST_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_LAKE_HYLIA_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_LOST_WOODS_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_ZORAS_RIVER_BEAN_SOUL)
DEFINE_RAND_INF(RAND_INF_GOHMA_SOUL)
DEFINE_RAND_INF(RAND_INF_KING_DODONGO_SOUL)
DEFINE_RAND_INF(RAND_INF_BARINADE_SOUL)

View File

@@ -55,6 +55,7 @@ static WidgetInfo triforcePieceCount;
static WidgetInfo dungeonItemTracking;
static WidgetInfo gregTracking;
static WidgetInfo triforcePieceTracking;
static WidgetInfo beanSoulsTracking;
static WidgetInfo bossSoulsTracking;
static WidgetInfo ocarinaButtonTracking;
static WidgetInfo overworldKeysTracking;
@@ -136,6 +137,19 @@ std::vector<ItemTrackerItem> triforcePieces = {
ITEM_TRACKER_ITEM(RG_TRIFORCE_PIECE, 0, DrawItem),
};
std::vector<ItemTrackerItem> beanSoulItems = {
ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_DESERT_COLOSSUS_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_GERUDO_VALLEY_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_GRAVEYARD_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_KOKIRI_FOREST_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_LAKE_HYLIA_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_LOST_WOODS_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
ITEM_TRACKER_ITEM_CUSTOM(RG_ZORAS_RIVER_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem),
};
std::vector<ItemTrackerItem> bossSoulItems = {
ITEM_TRACKER_ITEM(RG_GOHMA_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_KING_DODONGO_SOUL, 0, DrawItem),
ITEM_TRACKER_ITEM(RG_BARINADE_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_PHANTOM_GANON_SOUL, 0, DrawItem),
@@ -246,6 +260,19 @@ std::map<uint16_t, std::string> itemTrackerDungeonShortNames = {
{ SCENE_THIEVES_HIDEOUT, "HIDE" },
};
std::map<uint16_t, std::string> itemTrackerBeanShortNames = {
{ RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, "DMC" },
{ RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, "DMT" },
{ RG_DESERT_COLOSSUS_BEAN_SOUL, "DC" },
{ RG_GERUDO_VALLEY_BEAN_SOUL, "GV" },
{ RG_GRAVEYARD_BEAN_SOUL, "GY" },
{ RG_KOKIRI_FOREST_BEAN_SOUL, "KF" },
{ RG_LAKE_HYLIA_BEAN_SOUL, "LA" },
{ RG_LOST_WOODS_BRIDGE_BEAN_SOUL, "LWB" },
{ RG_LOST_WOODS_BEAN_SOUL, "LWT" },
{ RG_ZORAS_RIVER_BEAN_SOUL, "ZR" },
};
std::map<uint16_t, std::string> itemTrackerBossShortNames = {
{ RG_GOHMA_SOUL, "GOHMA" }, { RG_KING_DODONGO_SOUL, "KD" }, { RG_BARINADE_SOUL, "BARI" },
{ RG_PHANTOM_GANON_SOUL, "PG" }, { RG_VOLVAGIA_SOUL, "VOLV" }, { RG_MORPHA_SOUL, "MORPH" },
@@ -809,6 +836,56 @@ void DrawItem(ItemTrackerItem item) {
hasItem = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT);
itemName = "Triforce Piece";
break;
case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);
itemName = "Death Mountain Crater Bean Soul";
break;
case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL);
itemName = "Death Mountain Trail Bean Soul";
break;
case RG_DESERT_COLOSSUS_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL);
itemName = "Desert Colossus Bean Soul";
break;
case RG_GERUDO_VALLEY_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL);
itemName = "Gerudo Valley Bean Soul";
break;
case RG_GRAVEYARD_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_GRAVEYARD_BEAN_SOUL);
itemName = "Graveyard Bean Soul";
break;
case RG_KOKIRI_FOREST_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL);
itemName = "Kokiri Forest Bean Soul";
break;
case RG_LAKE_HYLIA_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL);
itemName = "Lake Hylia Bean Soul";
break;
case RG_LOST_WOODS_BRIDGE_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL);
itemName = "Lost Woods Bridge Bean Soul";
break;
case RG_LOST_WOODS_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BEAN_SOUL);
itemName = "Lost Woods Theatre Bean Soul";
break;
case RG_ZORAS_RIVER_BEAN_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL);
itemName = "Zora's River Bean Soul";
break;
case RG_GOHMA_SOUL:
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_GOHMA_SOUL);
@@ -1025,6 +1102,16 @@ void DrawItem(ItemTrackerItem item) {
DrawItemCount(item, false);
if (item.id >= RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL && item.id <= RG_ZORAS_RIVER_BEAN_SOUL) {
ImVec2 p = ImGui::GetCursorScreenPos();
std::string beanName = itemTrackerBeanShortNames[item.id];
ImGui::SetCursorScreenPos(
ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(beanName.c_str()).x / 2), p.y - (iconSize + 13)));
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE);
ImGui::Text("%s", beanName.c_str());
ImGui::PopStyleColor();
}
if (item.id >= RG_GOHMA_SOUL && item.id <= RG_GANON_SOUL) {
ImVec2 p = ImGui::GetCursorScreenPos();
std::string bossName = itemTrackerBossShortNames[item.id];
@@ -1478,6 +1565,19 @@ void UpdateVectors() {
mainWindowItems.insert(mainWindowItems.end(), fishingPoleItems.begin(), fishingPoleItems.end());
}
// If we're adding bean souls to the main window...
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BeanSouls"), SECTION_DISPLAY_HIDDEN) ==
SECTION_DISPLAY_MAIN_WINDOW) {
//...add empty items on the main window to get the souls on their own row. (Too many to sit with Greg/Triforce
// pieces)
while (mainWindowItems.size() % 6) {
mainWindowItems.push_back(ITEM_TRACKER_ITEM(ITEM_NONE, 0, DrawItem));
}
// Add bean souls
mainWindowItems.insert(mainWindowItems.end(), beanSoulItems.begin(), beanSoulItems.end());
}
// If we're adding boss souls to the main window...
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BossSouls"), SECTION_DISPLAY_HIDDEN) ==
SECTION_DISPLAY_MAIN_WINDOW) {
@@ -1674,6 +1774,13 @@ void ItemTrackerWindow::DrawElement() {
EndFloatingWindows();
}
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BeanSouls"), SECTION_DISPLAY_HIDDEN) ==
SECTION_DISPLAY_SEPARATE) {
BeginFloatingWindows("Bean Soul Tracker");
DrawItemsInRows(beanSoulItems);
EndFloatingWindows();
}
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BossSouls"), SECTION_DISPLAY_HIDDEN) ==
SECTION_DISPLAY_SEPARATE) {
BeginFloatingWindows("Boss Soul Tracker");
@@ -1914,6 +2021,7 @@ void ItemTrackerSettingsWindow::DrawElement() {
}
SohGui::mSohMenu->MenuDrawItem(gregTracking, 250, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(triforcePieceTracking, 250, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(beanSoulsTracking, 250, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(bossSoulsTracking, 250, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(ocarinaButtonTracking, 250, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(overworldKeysTracking, 250, THEME_COLOR);
@@ -2028,6 +2136,18 @@ void RegisterItemTrackerWidgets() {
;
SohGui::mSohMenu->AddSearchWidget({ gregTracking, "Randomizer", "Item Tracker", "General Settings", "icon" });
beanSoulsTracking = { .name = "Bean Souls", .type = WidgetType::WIDGET_CVAR_COMBOBOX };
beanSoulsTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.BeanSouls"))
.Options(ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
.ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far)
.Color(THEME_COLOR)
.ComboMap(displayTypes))
.Callback([](WidgetInfo& info) { shouldUpdateVectors = true; });
;
SohGui::mSohMenu->AddSearchWidget({ beanSoulsTracking, "Randomizer", "Item Tracker", "General Settings", "icon" });
bossSoulsTracking = { .name = "Boss Souls", .type = WidgetType::WIDGET_CVAR_COMBOBOX };
bossSoulsTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.BossSouls"))
.Options(ComboboxOptions()

View File

@@ -266,6 +266,41 @@ extern "C" void Randomizer_InitSaveFile() {
// Go away Ruto (Water Temple first cutscene).
gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10);
if (Randomizer_GetSettingValue(RSK_STARTING_BEANS)) {
INV_CONTENT(ITEM_BEAN) = ITEM_BEAN;
if (Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_BEANS_ONLY &&
Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_ALL) {
BEANS_BOUGHT = 10;
}
if (Randomizer_GetSettingValue(RSK_SKIP_PLANTING_BEANS)) {
AMMO(ITEM_BEAN) = 0;
gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_CRATER].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_TRAIL].swch |= (1 << 6);
gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 24);
gSaveContext.sceneFlags[SCENE_GERUDO_VALLEY].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_GRAVEYARD].swch |= (1 << 3);
gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 9);
gSaveContext.sceneFlags[SCENE_LAKE_HYLIA].swch |= (1 << 1);
gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 4) | (1 << 18);
gSaveContext.sceneFlags[SCENE_ZORAS_RIVER].swch |= (1 << 3);
} else {
AMMO(ITEM_BEAN) = 10;
}
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BEAN_SOULS) == RO_GENERIC_OFF) {
Flags_SetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_GRAVEYARD_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_LOST_WOODS_BEAN_SOUL);
Flags_SetRandomizerInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL);
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS) == RO_GENERIC_OFF) {
Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_A);
Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT);

View File

@@ -237,6 +237,7 @@ void Settings::CreateOptions() {
OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, "Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]);
OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"});
OPT_BOOL(RSK_SHUFFLE_100_GS_REWARD, "Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_SHUFFLE_BEAN_SOULS, "Shuffle Bean Souls", CVAR_RANDOMIZER_SETTING("ShuffleBeanSouls"), mOptionDescriptions[RSK_SHUFFLE_BEAN_SOULS], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_U8(RSK_SHUFFLE_BOSS_SOULS, "Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox);
OPT_BOOL(RSK_SHUFFLE_DEKU_STICK_BAG, "Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_SHUFFLE_DEKU_NUT_BAG, "Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
@@ -276,6 +277,7 @@ void Settings::CreateOptions() {
OPT_BOOL(RSK_SKIP_CHILD_ZELDA, "Skip Child Zelda", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipChildZelda"), mOptionDescriptions[RSK_SKIP_CHILD_ZELDA], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
OPT_BOOL(RSK_SKIP_EPONA_RACE, "Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), mOptionDescriptions[RSK_SKIP_EPONA_RACE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, "Skip Scarecrow's Song", CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]);
OPT_BOOL(RSK_SKIP_PLANTING_BEANS, "Skip Planting Beans", CVAR_RANDOMIZER_SETTING("SkipPlantingBeans"), mOptionDescriptions[RSK_SKIP_PLANTING_BEANS]);
OPT_U8(RSK_BIG_POE_COUNT, "Big Poe Target Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), mOptionDescriptions[RSK_BIG_POE_COUNT], WidgetType::Slider, 10);
OPT_BOOL(RSK_COMPLETE_MASK_QUEST, "Complete Mask Quest", CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), mOptionDescriptions[RSK_COMPLETE_MASK_QUEST]);
OPT_U8(RSK_GOSSIP_STONE_HINTS, "Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), mOptionDescriptions[RSK_GOSSIP_STONE_HINTS], WidgetType::Combobox, RO_GOSSIP_STONES_NEED_NOTHING, false, IMFLAG_NONE);
@@ -322,6 +324,7 @@ void Settings::CreateOptions() {
OPT_BOOL(RSK_STARTING_MASTER_SWORD, "Start with Master Sword", CVAR_RANDOMIZER_SETTING("StartingMasterSword"));
OPT_BOOL(RSK_STARTING_STICKS, "Start with Stick Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSticks"), "", WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_NUTS, "Start with Nut Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingNuts"), "", WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_BEANS, "Start with Magic Beans", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBeans"), "", WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_FULL_WALLETS, "Full Wallets", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FullWallets"), mOptionDescriptions[RSK_FULL_WALLETS], WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_ZELDAS_LULLABY, "Start with Zelda's Lullaby", CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_EPONAS_SONG, "Start with Epona's Song", CVAR_RANDOMIZER_SETTING("StartingEponasSong"), "", IMFLAG_NONE);
@@ -1343,6 +1346,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_BEAN_SOULS],
&mOptions[RSK_SHUFFLE_BOSS_SOULS],
&mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES],
&mOptions[RSK_SHUFFLE_STONE_FAIRIES],
@@ -1389,7 +1393,7 @@ void Settings::CreateOptions() {
mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup(
"Timesavers",
{ &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA], &mOptions[RSK_SKIP_EPONA_RACE],
&mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] },
&mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG], &mOptions[RSK_SKIP_PLANTING_BEANS] },
WidgetContainerType::COLUMN);
mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("",
{
@@ -1463,6 +1467,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_STARTING_OCARINA],
&mOptions[RSK_STARTING_STICKS],
&mOptions[RSK_STARTING_NUTS],
&mOptions[RSK_STARTING_BEANS],
&mOptions[RSK_STARTING_SKULLTULA_TOKEN],
&mOptions[RSK_STARTING_HEARTS],
},
@@ -1608,6 +1613,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_CHEST_MINIGAME],
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_BEAN_SOULS],
&mOptions[RSK_SHUFFLE_BOSS_SOULS],
&mOptions[RSK_SHUFFLE_DEKU_STICK_BAG],
&mOptions[RSK_SHUFFLE_DEKU_NUT_BAG],
@@ -1664,6 +1670,7 @@ void Settings::CreateOptions() {
mOptionGroups[RSG_STARTING_OTHER] = OptionGroup::SubGroup("Other", {
&mOptions[RSK_STARTING_STICKS],
&mOptions[RSK_STARTING_NUTS],
&mOptions[RSK_STARTING_BEANS],
&mOptions[RSK_FULL_WALLETS],
&mOptions[RSK_STARTING_SKULLTULA_TOKEN],
&mOptions[RSK_STARTING_HEARTS],
@@ -1679,6 +1686,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SKIP_CHILD_ZELDA],
&mOptions[RSK_SKIP_EPONA_RACE],
&mOptions[RSK_SKIP_SCARECROWS_SONG],
&mOptions[RSK_SKIP_PLANTING_BEANS],
&mOptions[RSK_BIG_POE_COUNT],
&mOptions[RSK_COMPLETE_MASK_QUEST],
});

View File

@@ -2549,12 +2549,18 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
u16 naviTextId = Random(0, NUM_NAVI_MESSAGES);
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID,
naviTextId, MF_FORMATTED);
} else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_10 &&
(ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) {
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(
RC_ZR_MAGIC_BEAN_SALESMAN, TEXT_BEAN_SALESMAN_BUY_FOR_10, TEXT_NONE,
Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT) == RO_GENERIC_OFF);
} else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_10) {
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) {
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(
RC_ZR_MAGIC_BEAN_SALESMAN, TEXT_BEAN_SALESMAN_BUY_FOR_10, TEXT_NONE,
Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT) == RO_GENERIC_OFF);
} else if (ctx->GetOption(RSK_SKIP_PLANTING_BEANS)) {
// TODO_TRANSLATE Translate into french and german
messageEntry =
CustomMessage("For #60 rupees# I'll plant beans across Hyrule, deal?\x1B#Yes&No#", { QM_YELLOW });
messageEntry.AutoFormat();
}
} else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_100) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100, MF_AUTO_FORMAT);