From 51310db68fc66725f5720e6d7aa7dcda0b17b8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 25 Feb 2025 08:11:46 +0000 Subject: [PATCH 01/10] ShuffleCows.cpp (#5093) --- .../Enhancements/randomizer/ShuffleCows.cpp | 74 +++++++++++++++++++ .../Enhancements/randomizer/hook_handlers.cpp | 54 -------------- .../Enhancements/randomizer/location_list.cpp | 12 --- soh/soh/Enhancements/randomizer/static_data.h | 1 + soh/soh/OTRGlobals.cpp | 2 +- 5 files changed, 76 insertions(+), 67 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/ShuffleCows.cpp diff --git a/soh/soh/Enhancements/randomizer/ShuffleCows.cpp b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp new file mode 100644 index 000000000..5fc86f76d --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp @@ -0,0 +1,74 @@ +#include +#include "static_data.h" + +extern "C" { +#include "src/overlays/actors/ovl_En_Cow/z_en_cow.h" +extern PlayState* gPlayState; +} + +void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) { + bool moved = false; + + // Don't reposition the tail + if (enCow->actor.params != 0) { + return; + } + + if (play->sceneNum == SCENE_LON_LON_BUILDINGS && enCow->actor.world.pos.x == -108 && + enCow->actor.world.pos.z == -65) { + // Move left cow in lon lon tower + enCow->actor.world.pos.x = -229.0f; + enCow->actor.world.pos.z = 157.0f; + enCow->actor.shape.rot.y = 15783.0f; + moved = true; + } else if (play->sceneNum == SCENE_STABLE && enCow->actor.world.pos.x == -3 && enCow->actor.world.pos.z == -254) { + // Move right cow in lon lon stable + enCow->actor.world.pos.x += 119.0f; + moved = true; + } + + if (moved) { + // Reposition collider + func_809DEE9C(enCow); + } +} + +void RegisterShuffleCows() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_COWS).Get(); + + COND_VB_SHOULD(VB_GIVE_ITEM_FROM_COW, shouldRegister, { + EnCow* enCow = va_arg(args, EnCow*); + CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow(gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z); + // Has this cow already rewarded an item? + if (!Flags_GetRandomizerInf(cowIdentity.randomizerInf)) { + Flags_SetRandomizerInf(cowIdentity.randomizerInf); + // setting the ocarina mode here prevents intermittent issues + // with the item get not triggering until walking away + gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_00; + *should = false; + } + }); + + COND_VB_SHOULD(VB_DESPAWN_HORSE_RACE_COW, shouldRegister, { + EnCow* enCow = va_arg(args, EnCow*); + // If this is a cow we have to move, then move it now. + EnCow_MoveForRandomizer(enCow, gPlayState); + }); +} + +static RegisterShipInitFunc initFunc(RegisterShuffleCows, { "IS_RANDO" }); + +void Rando::StaticData::RegisterCowLocations() { + locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW)); + locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW)); + locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW)); + locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW)); + locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW)); + locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW)); + locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW)); + locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW)); + locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW)); +} + +static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterCowLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 5eee3541a..e236666f6 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -26,7 +26,6 @@ extern "C" { #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_En_Si/z_en_si.h" -#include "src/overlays/actors/ovl_En_Cow/z_en_cow.h" #include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h" #include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" #include "src/overlays/actors/ovl_En_Gb/z_en_gb.h" @@ -512,33 +511,6 @@ void ItemEtcetera_UpdateRandomizedFireArrow(ItemEtcetera* itemEtcetera, PlayStat } } -void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) { - bool moved = false; - - // Don't reposition the tail - if (enCow->actor.params != 0) { - return; - } - - // Move left cow in lon lon tower - if (play->sceneNum == SCENE_LON_LON_BUILDINGS && enCow->actor.world.pos.x == -108 && - enCow->actor.world.pos.z == -65) { - enCow->actor.world.pos.x = -229.0f; - enCow->actor.world.pos.z = 157.0f; - enCow->actor.shape.rot.y = 15783.0f; - moved = true; - // Move right cow in lon lon stable - } else if (play->sceneNum == SCENE_STABLE && enCow->actor.world.pos.x == -3 && enCow->actor.world.pos.z == -254) { - enCow->actor.world.pos.x += 119.0f; - moved = true; - } - - if (moved) { - // Reposition collider - func_809DEE9C(enCow); - } -} - u8 EnDs_RandoCanGetGrannyItem() { return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS || RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) && @@ -1060,23 +1032,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SARIAS_SONG); break; } - case VB_GIVE_ITEM_FROM_COW: { - if (!RAND_GET_OPTION(RSK_SHUFFLE_COWS)) { - break; - } - EnCow* enCow = va_arg(args, EnCow*); - CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow(gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z); - // Has this cow already rewarded an item? - if (Flags_GetRandomizerInf(cowIdentity.randomizerInf)) { - break; - } - Flags_SetRandomizerInf(cowIdentity.randomizerInf); - // setting the ocarina mode here prevents intermittent issues - // with the item get not triggering until walking away - gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_00; - *should = false; - break; - } case VB_GIVE_ITEM_FROM_GRANNYS_SHOP: { if (!EnDs_RandoCanGetGrannyItem()) { break; @@ -1257,15 +1212,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; } - case VB_DESPAWN_HORSE_RACE_COW: { - if (!RAND_GET_OPTION(RSK_SHUFFLE_COWS)) { - break; - } - EnCow* enCow = va_arg(args, EnCow*); - // If this is a cow we have to move, then move it now. - EnCow_MoveForRandomizer(enCow, gPlayState); - break; - } case VB_BUSINESS_SCRUB_DESPAWN: { EnShopnuts* enShopnuts = va_arg(args, EnShopnuts*); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index b4e26c84a..1e0b3a7d1 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -874,18 +874,6 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO)); locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO)); - // Cows - locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW)); - locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW)); - locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW)); - locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW)); - locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW)); - locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW)); - locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW)); - locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW)); - locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW)); - locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW)); - /*------------------------------- --- SHOPS --- 8 6 2 4 diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 8936294a2..a456089a3 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -46,6 +46,7 @@ class StaticData { static std::vector GetPondFishLocations(); static std::vector GetOverworldFishLocations(); static std::vector GetOverworldFairyLocations(); + static void RegisterCowLocations(); static void RegisterFishLocations(); static void RegisterFairyLocations(); static void RegisterPotLocations(); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 6b5afb0c3..dc745b0b5 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2254,7 +2254,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { messageEntry = OTRGlobals::Instance->gRandomizer->GetGoronMessage(choice); } else if (textId == TEXT_FROGS_UNDERWATER && ctx->GetOption(RSK_FROGS_HINT)) { - messageEntry = ctx->GetHint(RH_FROGS_HINT)->GetHintMessage(MF_AUTO_FORMAT), TEXTBOX_TYPE_BLUE; + messageEntry = ctx->GetHint(RH_FROGS_HINT)->GetHintMessage(MF_AUTO_FORMAT); } else if ( Randomizer_GetSettingValue(RSK_LOACH_HINT) && From f023a46a5d5ef8e969427dbd694366f06fb078b7 Mon Sep 17 00:00:00 2001 From: Archez Date: Tue, 25 Feb 2025 03:13:17 -0500 Subject: [PATCH 02/10] Use gamemode enum (#5089) * Use gamemode enum * update console command for file_select --- soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp | 2 +- soh/soh/Enhancements/debugconsole.cpp | 13 +++++++------ .../Enhancements/randomizer/randomizer_entrance.c | 2 +- soh/src/code/graph.c | 2 +- soh/src/code/z_camera.c | 2 +- soh/src/code/z_construct.c | 2 +- soh/src/code/z_demo.c | 14 +++++++------- soh/src/code/z_kankyo.c | 6 +++--- soh/src/code/z_parameter.c | 2 +- soh/src/code/z_player_lib.c | 2 +- soh/src/overlays/actors/ovl_En_Light/z_en_light.c | 2 +- soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c | 6 +++--- soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c | 2 +- .../ovl_En_Okarina_Effect/z_en_okarina_effect.c | 2 +- .../overlays/actors/ovl_player_actor/z_player.c | 2 +- .../gamestates/ovl_file_choose/z_file_choose.c | 5 +---- .../overlays/gamestates/ovl_opening/z_opening.c | 2 +- soh/src/overlays/gamestates/ovl_title/z_title.c | 2 +- 18 files changed, 34 insertions(+), 36 deletions(-) diff --git a/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp index d478f8fc3..2d750ab5d 100644 --- a/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp +++ b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp @@ -205,7 +205,7 @@ void OnZTitleUpdateSkipToFileSelect(void* gameState) { gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = 0xFF; - gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; + gSaveContext.gameMode = GAMEMODE_FILE_SELECT; titleContext->state.running = false; SET_NEXT_GAMESTATE(&titleContext->state, FileChoose_Init, FileChooseContext); diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 5df00dfab..67547437d 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -146,7 +146,7 @@ static bool SetPlayerHealthHandler(std::shared_ptr Console, const static bool LoadSceneHandler(std::shared_ptr Console, const std::vector&, std::string* output) { gSaveContext.respawnFlag = 0; gSaveContext.seqId = 0xFF; - gSaveContext.gameMode = 0; + gSaveContext.gameMode = GAMEMODE_NORMAL; return 0; } @@ -489,13 +489,14 @@ static bool FWHandler(std::shared_ptr Console, const std::vector< } static bool FileSelectHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { - if (gPlayState != nullptr) { - SET_NEXT_GAMESTATE(&gPlayState->state, FileChoose_Init, FileChooseContext); - gPlayState->state.running = 0; - } else { - ERROR_MESSAGE("gPlayState == nullptr"); + if (gGameState == nullptr) { + ERROR_MESSAGE("gGameState == nullptr"); return 1; } + + gSaveContext.gameMode = GAMEMODE_FILE_SELECT; + SET_NEXT_GAMESTATE(gGameState, FileChoose_Init, FileChooseContext); + gGameState->running = false; return 0; } diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c index fdb1f6809..3ad26b1f6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c @@ -440,7 +440,7 @@ void Entrance_SetWarpSongEntrance(void) { // have to force the grotto return afterwards Grotto_ForceGrottoReturnOnSpecialEntrance(); - if (gSaveContext.gameMode != 0) { + if (gSaveContext.gameMode != GAMEMODE_NORMAL) { // During DHWW the cutscene must play at the destination gSaveContext.respawnFlag = -3; } else if (gSaveContext.respawnFlag == -3) { diff --git a/soh/src/code/graph.c b/soh/src/code/graph.c index 51f8fcd17..be5ee994d 100644 --- a/soh/src/code/graph.c +++ b/soh/src/code/graph.c @@ -412,7 +412,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) { { if (CHECK_BTN_ALL(gameState->input[0].press.button, BTN_Z) && CHECK_BTN_ALL(gameState->input[0].cur.button, BTN_L | BTN_R)) { - gSaveContext.gameMode = 0; + gSaveContext.gameMode = GAMEMODE_NORMAL; SET_NEXT_GAMESTATE(gameState, Select_Init, SelectContext); gameState->running = false; } diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 6551d6347..7167daceb 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -7589,7 +7589,7 @@ Vec3s Camera_Update(Camera* camera) { } if (camera->status == CAM_STAT_ACTIVE) { - if ((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 3)) { + if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_END_CREDITS)) { sCameraInterfaceFlags = 0; Camera_UpdateInterface(sCameraInterfaceFlags); } else if ((D_8011D3F0 != 0) && (camera->thisIdx == MAIN_CAM)) { diff --git a/soh/src/code/z_construct.c b/soh/src/code/z_construct.c index 960088cba..065c6f413 100644 --- a/soh/src/code/z_construct.c +++ b/soh/src/code/z_construct.c @@ -479,7 +479,7 @@ void Regs_InitDataImpl(void) { WREG(94) = 3; WREG(95) = 6; - if (gSaveContext.gameMode == 0) { + if (gSaveContext.gameMode == GAMEMODE_NORMAL) { R_TEXTBOX_X = 52; R_TEXTBOX_Y = 36; VREG(2) = 214; diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index 9821b8d26..c079d0064 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -510,8 +510,8 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) && (gSaveContext.fileNum != 0xFEDC) && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0)); - if ((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 3) && (play->sceneNum != SCENE_HYRULE_FIELD) && - (csCtx->frames > 20) && + if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_END_CREDITS) && + (play->sceneNum != SCENE_HYRULE_FIELD) && (csCtx->frames > 20) && (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_A) || CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B) || CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START)) && @@ -575,7 +575,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB osSyncPrintf("\n分岐先指定!!=[%d]番", cmd->base); // "Future fork designation=No. [%d]" - if ((gSaveContext.gameMode != 0) && (csCtx->frames != cmd->startFrame)) { + if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (csCtx->frames != cmd->startFrame)) { gSaveContext.unk_13E7 = 1; } @@ -908,7 +908,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 54: - gSaveContext.gameMode = 3; + gSaveContext.gameMode = GAMEMODE_END_CREDITS; Audio_SetSoundBanksMute(0x6F); play->linkAgeOnLoad = 1; play->nextEntranceIndex = ENTR_GERUDO_VALLEY_EAST_EXIT; @@ -1288,7 +1288,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; break; case 117: - gSaveContext.gameMode = 3; + gSaveContext.gameMode = GAMEMODE_END_CREDITS; Audio_SetSoundBanksMute(0x6F); play->linkAgeOnLoad = 0; play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; @@ -2080,7 +2080,7 @@ void func_80068DC0(PlayState* play, CutsceneContext* csCtx) { osSyncPrintf("\n\n\n\n\nやっぱりここかいな"); // "Right here, huh" gSaveContext.cutsceneIndex = 0; - gSaveContext.gameMode = 0; + gSaveContext.gameMode = GAMEMODE_NORMAL; if (D_8015FCC8 != 0) { switch (gSaveContext.entranceIndex) { @@ -2203,7 +2203,7 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) { return; } - if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { + if ((gSaveContext.gameMode == GAMEMODE_NORMAL) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT; diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c index 6e3736b77..df5decc4a 100644 --- a/soh/src/code/z_kankyo.c +++ b/soh/src/code/z_kankyo.c @@ -895,7 +895,7 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex EnvLightSettings* lightSettingsList = play->envCtx.lightSettingsList; s32 adjustment; - if ((((void)0, gSaveContext.gameMode) != 0) && (((void)0, gSaveContext.gameMode) != 3)) { + if ((((void)0, gSaveContext.gameMode) != GAMEMODE_NORMAL) && (((void)0, gSaveContext.gameMode) != GAMEMODE_END_CREDITS)) { func_800AA16C(play); } @@ -925,9 +925,9 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex } if ((pauseCtx->state == 0) && (gameOverCtx->state == GAMEOVER_INACTIVE)) { - if (((msgCtx->msgLength == 0) && (msgCtx->msgMode == 0)) || (((void)0, gSaveContext.gameMode) == 3)) { + if (((msgCtx->msgLength == 0) && (msgCtx->msgMode == 0)) || (((void)0, gSaveContext.gameMode) == GAMEMODE_END_CREDITS)) { if ((envCtx->unk_1A == 0) && !FrameAdvance_IsEnabled(play) && - (play->transitionMode == TRANS_MODE_OFF || ((void)0, gSaveContext.gameMode) != 0)) { + (play->transitionMode == TRANS_MODE_OFF || ((void)0, gSaveContext.gameMode) != GAMEMODE_NORMAL)) { if (IS_DAY || gTimeIncrement >= 0x190) { gSaveContext.dayTime += gTimeIncrement; diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index a331e4ace..1daa29fb9 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -3215,7 +3215,7 @@ void Interface_UpdateMagicBar(PlayState* play) { case MAGIC_STATE_FILL: gSaveContext.magic += 4; - if (gSaveContext.gameMode == 0 && gSaveContext.sceneSetupIndex < 4) { + if (gSaveContext.gameMode == GAMEMODE_NORMAL && gSaveContext.sceneSetupIndex < 4) { Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index 9d4b55091..bf7189616 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -1131,7 +1131,7 @@ void Player_DrawImpl(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dL if (((CVarGetInteger(CVAR_ENHANCEMENT("FirstPersonGauntlets"), 0) && LINK_IS_ADULT) || (overrideLimbDraw != Player_OverrideLimbDrawGameplayFirstPerson)) && (overrideLimbDraw != Player_OverrideLimbDrawGameplayCrawling) && - (gSaveContext.gameMode != 3)) { + (gSaveContext.gameMode != GAMEMODE_END_CREDITS)) { if (LINK_IS_ADULT) { s32 strengthUpgrade = CUR_UPG_VALUE(UPG_STRENGTH); diff --git a/soh/src/overlays/actors/ovl_En_Light/z_en_light.c b/soh/src/overlays/actors/ovl_En_Light/z_en_light.c index d7f9772d6..ca5cdaa0d 100644 --- a/soh/src/overlays/actors/ovl_En_Light/z_en_light.c +++ b/soh/src/overlays/actors/ovl_En_Light/z_en_light.c @@ -50,7 +50,7 @@ void EnLight_Init(Actor* thisx, PlayState* play) { EnLight* this = (EnLight*)thisx; s16 yOffset; - if (gSaveContext.gameMode == 3) { + if (gSaveContext.gameMode == GAMEMODE_END_CREDITS) { // special case for the credits yOffset = (this->actor.params < 0) ? 1 : 40; Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, yOffset + (s16)this->actor.world.pos.y, diff --git a/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c b/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c index 558a18796..0ea4a2e25 100644 --- a/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c +++ b/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c @@ -251,7 +251,7 @@ void EnMag_UpdateMq(Actor* thisx, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - gSaveContext.gameMode = 2; + gSaveContext.gameMode = GAMEMODE_FILE_SELECT; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; } @@ -411,7 +411,7 @@ void EnMag_UpdateVanilla(Actor* thisx, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - gSaveContext.gameMode = 2; + gSaveContext.gameMode = GAMEMODE_FILE_SELECT; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; } @@ -1065,4 +1065,4 @@ void EnMag_Draw(Actor* thisx, PlayState* play) { POLY_OPA_DISP = gfx; CLOSE_DISPS(play->state.gfxCtx); -} \ No newline at end of file +} diff --git a/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c b/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c index e72a174f8..c3a27994f 100644 --- a/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c +++ b/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c @@ -463,7 +463,7 @@ void func_80AAE294(EnMm* this, PlayState* play) { dustPos.y = this->actor.world.pos.y; dustPos.z = this->actor.world.pos.z; - if (gSaveContext.gameMode != 3) { + if (gSaveContext.gameMode != GAMEMODE_END_CREDITS) { func_80033480(play, &dustPos, 50.0f, 2, 350, 20, 0); } diff --git a/soh/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c b/soh/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c index 0d3519e3d..5bde1af54 100644 --- a/soh/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c +++ b/soh/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c @@ -73,7 +73,7 @@ void EnOkarinaEffect_ManageStorm(EnOkarinaEffect* this, PlayState* play) { Flags_UnsetEnv(play, 5); // clear storms env flag if (((play->pauseCtx.state == 0) && (play->gameOverCtx.state == GAMEOVER_INACTIVE) && (play->msgCtx.msgLength == 0) && (!FrameAdvance_IsEnabled(play)) && - ((play->transitionMode == TRANS_MODE_OFF) || (gSaveContext.gameMode != 0))) || + ((play->transitionMode == TRANS_MODE_OFF) || (gSaveContext.gameMode != GAMEMODE_NORMAL))) || (this->timer >= 250)) { if (play->envCtx.indoors || play->envCtx.unk_1F != 1) { this->timer--; diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 1c9d5a688..1d9c89212 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -10859,7 +10859,7 @@ void Player_Init(Actor* thisx, PlayState* play2) { } if (startMode != PLAYER_START_MODE_NOTHING) { - if ((gSaveContext.gameMode == 0) || (gSaveContext.gameMode == 3)) { + if ((gSaveContext.gameMode == GAMEMODE_NORMAL) || (gSaveContext.gameMode == GAMEMODE_END_CREDITS)) { this->naviActor = Player_SpawnFairy(play, this, &thisx->world.pos, &D_80854778, FAIRY_NAVI); if (gSaveContext.dogParams != 0) { gSaveContext.dogParams |= 0x8000; diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 6b2d0546f..664a9dcfc 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -3112,7 +3112,7 @@ void FileChoose_LoadGame(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gSaveContext.fileNum = this->buttonIndex; - gSaveContext.gameMode = 0; + gSaveContext.gameMode = GAMEMODE_NORMAL; if ((this->buttonIndex == FS_BTN_SELECT_FILE_1 && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0)) || this->buttonIndex == 0xFF) { if (this->buttonIndex == 0xFF) { @@ -3737,7 +3737,4 @@ void FileChoose_Init(GameState* thisx) { Font_LoadOrderedFont(&this->font); Audio_QueueSeqCmd(0xF << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xA); func_800F5E18(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1); - - // Originally this was only set when transitioning from the title screen, but gSkipLogoTitle skips that process so we're ensuring it's set here - gSaveContext.gameMode = GAMEMODE_FILE_SELECT; } diff --git a/soh/src/overlays/gamestates/ovl_opening/z_opening.c b/soh/src/overlays/gamestates/ovl_opening/z_opening.c index 3ecd61fca..7898e8aed 100644 --- a/soh/src/overlays/gamestates/ovl_opening/z_opening.c +++ b/soh/src/overlays/gamestates/ovl_opening/z_opening.c @@ -9,7 +9,7 @@ void Sram_InitDebugSave(void); void Opening_SetupTitleScreen(OpeningContext* this) { - gSaveContext.gameMode = 1; + gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; this->state.running = false; gSaveContext.linkAge = 0; gSaveContext.fileNum = 0xFF; diff --git a/soh/src/overlays/gamestates/ovl_title/z_title.c b/soh/src/overlays/gamestates/ovl_title/z_title.c index 544fb6884..239ee9d3d 100644 --- a/soh/src/overlays/gamestates/ovl_title/z_title.c +++ b/soh/src/overlays/gamestates/ovl_title/z_title.c @@ -137,7 +137,7 @@ void Title_Main(GameState* thisx) { if (this->exit) { gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = 0xFF; - gSaveContext.gameMode = 1; + gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; this->state.running = false; SET_NEXT_GAMESTATE(&this->state, Opening_Init, OpeningContext); } From 5fcdf74f5cc92be3244d820cd1a37f5619a4600b Mon Sep 17 00:00:00 2001 From: Archez Date: Tue, 25 Feb 2025 03:13:31 -0500 Subject: [PATCH 03/10] Exclude debug file and cutscene map from auto save (#5088) * Exclude debug file and cutscene map from auto save * Remove ganon's lair from auto save exclusion --- soh/soh/Enhancements/Autosave.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/Autosave.cpp b/soh/soh/Enhancements/Autosave.cpp index 74b548dab..faa5ee8dd 100644 --- a/soh/soh/Enhancements/Autosave.cpp +++ b/soh/soh/Enhancements/Autosave.cpp @@ -24,11 +24,11 @@ typedef enum { bool Autosave_CanSave() { - // Don't save when in title screen + // Don't save when in title screen or debug file // Don't save the first 60 frames to not save the magic meter when it's still in the animation of filling it. - // Don't save in Ganon's fight and chamber of sages because of master sword and remember save location issues. - if (!GameInteractor::IsSaveLoaded(true) || gPlayState->gameplayFrames < 60 || - gPlayState->sceneNum == SCENE_GANON_BOSS || gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) { + // Don't save in Chamber of Sages and the Cutscene map because of remember save location and cutscene item gives. + if (!GameInteractor::IsSaveLoaded(false) || gPlayState->gameplayFrames < 60 || + gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES || gPlayState->sceneNum == SCENE_CUTSCENE_MAP) { return false; } From 66844fb22037a5e7ec3910ee0d06fc18e1122cc7 Mon Sep 17 00:00:00 2001 From: Archez Date: Tue, 25 Feb 2025 03:14:27 -0500 Subject: [PATCH 04/10] Fix crash with scene logging paths (#5081) --- .../resource/logging/SceneCommandLoggers.cpp | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/soh/soh/resource/logging/SceneCommandLoggers.cpp b/soh/soh/resource/logging/SceneCommandLoggers.cpp index 805de9be0..22e7420c2 100644 --- a/soh/soh/resource/logging/SceneCommandLoggers.cpp +++ b/soh/soh/resource/logging/SceneCommandLoggers.cpp @@ -24,9 +24,18 @@ #include "soh/resource/type/scenecommand/SetTransitionActorList.h" #include "soh/resource/type/scenecommand/SetWindSettings.h" #include "spdlog/spdlog.h" +#include namespace SOH { +const char* TrimOTRSignature(const char* fileName) { + static const char* sOTRSignature = "__OTR__"; + if (strncmp(fileName, sOTRSignature, strlen(sOTRSignature)) == 0) { + return fileName + 7; + } + return fileName; +} + void LogEndMarkerAsXML(std::shared_ptr resource) { std::shared_ptr endMarker = std::static_pointer_cast(resource); @@ -292,12 +301,12 @@ void LogMeshAsXML(std::shared_ptr resource) { for (int i = 0; i < setMesh->meshHeader.polygon0.num; i += 1) { tinyxml2::XMLElement* polygon = doc.NewElement("Polygon"); polygon->SetAttribute("PolyType", "0"); - polygon->SetAttribute("MeshOpa", setMesh->opaPaths[i].c_str()); - polygon->SetAttribute("MeshXlu", setMesh->xluPaths[i].c_str()); + polygon->SetAttribute("MeshOpa", TrimOTRSignature(dlist->opa ? (char*)dlist->opa : "")); + polygon->SetAttribute("MeshXlu", TrimOTRSignature(dlist->xlu ? (char*)dlist->xlu : "")); root->InsertEndChild(polygon); + dlist += 1; } - dlist += 1; } else if (setMesh->meshHeader.base.type == 1) { root->SetAttribute("PolyNum", "1"); tinyxml2::XMLElement* polygon = doc.NewElement("Polygon"); @@ -313,8 +322,10 @@ void LogMeshAsXML(std::shared_ptr resource) { polygon->SetAttribute("PolyType", "0"); - polygon->SetAttribute("MeshOpa", setMesh->opaPaths[0].c_str()); - polygon->SetAttribute("MeshXlu", setMesh->xluPaths[0].c_str()); + PolygonDlist* dlist = (PolygonDlist*)setMesh->meshHeader.polygon1.dlist; + + polygon->SetAttribute("MeshOpa", TrimOTRSignature(dlist->opa ? (char*)dlist->opa : "")); + polygon->SetAttribute("MeshXlu", TrimOTRSignature(dlist->xlu ? (char*)dlist->xlu : "")); root->InsertEndChild(polygon); @@ -325,7 +336,7 @@ void LogMeshAsXML(std::shared_ptr resource) { if (setMesh->meshHeader.polygon1.format == 1) { bgImage->SetAttribute("Unknown_00", image->unk_00); bgImage->SetAttribute("Id", image->id); - bgImage->SetAttribute("ImagePath", setMesh->imagePaths[i].c_str()); + bgImage->SetAttribute("ImagePath", TrimOTRSignature((char*)setMesh->meshHeader.polygon1.single.source)); bgImage->SetAttribute("Unknown_0C", setMesh->meshHeader.polygon1.single.unk_0C); bgImage->SetAttribute("TLUT", setMesh->meshHeader.polygon1.single.tlut); bgImage->SetAttribute("Width", setMesh->meshHeader.polygon1.single.width); @@ -337,7 +348,7 @@ void LogMeshAsXML(std::shared_ptr resource) { } else { bgImage->SetAttribute("Unknown_00", image->unk_00); bgImage->SetAttribute("Id", image->id); - bgImage->SetAttribute("ImagePath", setMesh->imagePaths[i].c_str()); + bgImage->SetAttribute("ImagePath", TrimOTRSignature((char*)image->source)); bgImage->SetAttribute("Unknown_0C", image->unk_0C); bgImage->SetAttribute("TLUT", image->tlut); bgImage->SetAttribute("Width", image->width); @@ -363,8 +374,8 @@ void LogMeshAsXML(std::shared_ptr resource) { polygon->SetAttribute("PosZ", dlist->pos.z); polygon->SetAttribute("Unknown", dlist->unk_06); - polygon->SetAttribute("MeshOpa", setMesh->opaPaths[i].c_str()); - polygon->SetAttribute("MeshXlu", setMesh->xluPaths[i].c_str()); + polygon->SetAttribute("MeshOpa", TrimOTRSignature(dlist->opa ? (char*)dlist->opa : "")); + polygon->SetAttribute("MeshXlu", TrimOTRSignature(dlist->xlu ? (char*)dlist->xlu : "")); root->InsertEndChild(polygon); dlist += 1; @@ -606,4 +617,4 @@ void LogWindSettingsAsXML(std::shared_ptr resource) { SPDLOG_INFO("{}: {}", resource->GetInitData()->Path, printer.CStr()); } -} //namespace SOH \ No newline at end of file +} //namespace SOH From e516f45e2322b93e2d8c8a1737c1d68b2796362d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 25 Feb 2025 08:30:05 +0000 Subject: [PATCH 05/10] logic: allow finding big poe in bottle for reward logic (#5075) * logic: allow finding big poe in bottle for reward logic only applies when big poe count is set to 1 * Allow multiple big poe bottles for when big poe requirement > 1 --- .../randomizer/location_access/overworld/market.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 6 +++++- soh/soh/Enhancements/randomizer/logic.h | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 0b010c8a7..af406f8bf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -39,7 +39,7 @@ void RegionTable_Init_Market() { EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}), }, { //Locations - LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->BigPoeKill), + LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes > ctx->GetOption(RSK_BIG_POE_COUNT).Get())), LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index fa9c8d8e5..9e1b1cf85 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1694,6 +1694,9 @@ namespace Rando { if (BottleRandomizerGetToItemID.contains(randoGet)) { itemId = BottleRandomizerGetToItemID[randoGet]; } + if (randoGet == RG_BOTTLE_WITH_BIG_POE) { + BigPoes++; + } mSaveContext->inventory.items[slot] = itemId; } break; case RG_RUTOS_LETTER: @@ -2255,7 +2258,8 @@ namespace Rando { IsChild = false; IsAdult = false; //CanPlantBean = false; - BigPoeKill = false; + BigPoeKill = false; + BigPoes = 0; BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() + 1; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index ea9d51801..77d6b2573 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -36,7 +36,6 @@ class Logic { // Adult logic bool FreedEpona = false; - //bool BigPoe = false; //unused // Trade Quest Events bool WakeUpAdultTalon = false; @@ -101,6 +100,7 @@ class Logic { bool IsChild = false; bool IsAdult = false; bool BigPoeKill = false; + uint8_t BigPoes = 0; uint8_t BaseHearts = 0; // Bridge and LACS Requirements From db41c6513b409e9fca95b1c5fe1d9cc5ef35f7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 25 Feb 2025 09:25:45 +0000 Subject: [PATCH 06/10] Move boss kill logic into CanKillEnemy (#5000) * Move boss kill logic into CanKillEnemy Added hammer as being able to defeat Morpha * add hammer vs gohma, king dodongo, & twinrova --- .../location_access/dungeons/deku_tree.cpp | 2 +- .../dungeons/dodongos_cavern.cpp | 2 +- .../location_access/dungeons/fire_temple.cpp | 2 +- .../dungeons/forest_temple.cpp | 2 +- .../dungeons/jabujabus_belly.cpp | 2 +- .../dungeons/shadow_temple.cpp | 6 +---- .../dungeons/spirit_temple.cpp | 2 +- .../location_access/dungeons/water_temple.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 25 +++++++++++++++++++ .../Enhancements/randomizer/randomizerTypes.h | 8 ++++++ 10 files changed, 41 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 9d3febe36..2500e4996 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -350,7 +350,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", "Deku Tree", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&logic->DekuTreeClear, []{return logic->DekuTreeClear || (logic->HasBossSoul(RG_GOHMA_SOUL) && (logic->CanJumpslashExceptHammer() && (logic->CanUse(RG_NUTS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HookshotOrBoomerang())));}), + EventAccess(&logic->DekuTreeClear, []{return logic->DekuTreeClear || logic->CanKillEnemy(RE_GOHMA);}), }, { // Locations LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index e961a5c08..bb5e1754f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -528,7 +528,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", "Dodongos Cavern", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernClear || (logic->HasBossSoul(RG_KING_DODONGO_SOUL) && (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanJumpslashExceptHammer())); /*todo add chu kill to tricks*/}), + EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernClear || (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && logic->CanKillEnemy(RE_KING_DODONGO)); /*todo add chu kill to tricks*/}), }, { // Locations LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 429d84667..1e7214a3d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -705,7 +705,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", "Fire Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&logic->FireTempleClear, []{return logic->FireTempleClear || (logic->HasBossSoul(RG_VOLVAGIA_SOUL) && (logic->FireTimer() >= 64 && logic->CanUse(RG_MEGATON_HAMMER)));}), + EventAccess(&logic->FireTempleClear, []{return logic->FireTempleClear || (logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA));}), }, { // Locations LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index 87f738b90..c9f4ebc23 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -600,7 +600,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", "Forest Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleClear || (logic->HasBossSoul(RG_PHANTOM_GANON_SOUL) && ((logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))));}), + EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleClear || logic->CanKillEnemy(RE_PHANTOM_GANON);}), }, { // Locations LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index fe043caa3..fa9c7b085 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -341,7 +341,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", {}, NO_DAY_NIGHT_CYCLE, { // Events //todo: add pot kill trick - EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyClear || (logic->HasBossSoul(RG_BARINADE_SOUL) && (logic->CanUse(RG_BOOMERANG) && logic->CanJumpslashExceptHammer()));}), + EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyClear || logic->CanKillEnemy(RE_BARINADE);}), }, { // Locations LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 1267e2408..bdcf8a4fa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -399,11 +399,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", "Shadow Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&logic->ShadowTempleClear, []{ - return logic->ShadowTempleClear || (logic->HasBossSoul(RG_BONGO_BONGO_SOUL) && ((logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && - (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && - (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO)))); - }), + EventAccess(&logic->ShadowTempleClear, []{return logic->ShadowTempleClear || logic->CanKillEnemy(RE_BONGO_BONGO);}), }, { // Locations LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 3d8e26cd6..e3d00ccf3 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -544,7 +544,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleClear || (logic->HasBossSoul(RG_TWINROVA_SOUL) && (logic->CanUse(RG_MIRROR_SHIELD) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))));}), + EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleClear || logic->CanKillEnemy(RE_TWINROVA);}), }, { // Locations LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 318a5eb64..4d2fbb9bf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -725,7 +725,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleClear || (logic->HasBossSoul(RG_MORPHA_SOUL) && (logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))));}), + EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleClear || logic->CanKillEnemy(RE_MORPHA);}), }, { // Locations LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 9e1b1cf85..5e5389dd4 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -673,6 +673,31 @@ namespace Rando { case RE_BIG_OCTO: //If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigains anyway. Bunny makes it free return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD); + case RE_GOHMA: + return HasBossSoul(RG_GOHMA_SOUL) && CanJumpslash() && + (CanUse(RG_NUTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HookshotOrBoomerang()); + case RE_KING_DODONGO: + return HasBossSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() && + (CanUse(RG_BOMB_BAG) || HasItem(RG_GORONS_BRACELET)); + case RE_BARINADE: + return HasBossSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer(); + case RE_PHANTOM_GANON: + return HasBossSoul(RG_PHANTOM_GANON_SOUL) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && + (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT)); + case RE_VOLVAGIA: + return HasBossSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER); + case RE_MORPHA: + return HasBossSoul(RG_MORPHA_SOUL) && CanUse(RG_HOOKSHOT) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER)); + case RE_BONGO_BONGO: + return HasBossSoul(RG_BONGO_BONGO_SOUL) && + (CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && + (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO)); + case RE_TWINROVA: + return HasBossSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER)); case RE_GANONDORF: // RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the energy ball // and either of them regardless of jumpslashing to damage and kill ganondorf diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 550f2b1af..155b31db1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -5732,6 +5732,14 @@ typedef enum { RE_BIG_OCTO, RE_GERUDO_WARRIOR, RE_GIBDO, + RE_GOHMA, + RE_KING_DODONGO, + RE_BARINADE, + RE_PHANTOM_GANON, + RE_VOLVAGIA, + RE_MORPHA, + RE_BONGO_BONGO, + RE_TWINROVA, RE_GANONDORF, RE_GANON, RE_DARK_LINK, From 06387060d6b3434eae7d65f12f651d495444af2c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:09:01 +0100 Subject: [PATCH 07/10] Trade cleanup (#4971) * Move adult trade to flags * Move child trade to flags * Fix vanilla * Address review * Rename `trade_shuffle` to `ShuffleTradeItems` * Fix mac build * Update GIVanillaBehavior.h * Update z_kankyo.c * Update z_en_heishi2.c --- soh/include/z64save.h | 1 - .../Enhancements/debugger/debugSaveEditor.cpp | 27 -------- .../Enhancements/debugger/debugSaveEditor.h | 24 +++++++ .../GameInteractor_HookTable.h | 1 + .../game-interactor/GameInteractor_Hooks.cpp | 4 ++ .../game-interactor/GameInteractor_Hooks.h | 2 +- .../vanilla-behavior/GIVanillaBehavior.h | 5 ++ .../randomizer/ShuffleTradeItems.c | 51 ++++++++++++++ .../randomizer/ShuffleTradeItems.h | 11 +++ .../randomizer/adult_trade_shuffle.c | 33 --------- .../randomizer/adult_trade_shuffle.h | 13 ---- .../Enhancements/randomizer/hook_handlers.cpp | 68 ++++++++++++++----- soh/soh/Enhancements/randomizer/logic.cpp | 31 ++------- soh/soh/Enhancements/randomizer/logic.h | 2 - .../Enhancements/randomizer/randomizer_inf.h | 24 +++++++ soh/soh/Enhancements/randomizer/savefile.cpp | 18 +++-- soh/soh/SaveManager.cpp | 8 --- soh/src/code/z_kankyo.c | 3 + soh/src/code/z_parameter.c | 20 ++++-- soh/src/code/z_play.c | 1 + soh/src/code/z_scene_table.c | 3 +- soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c | 1 - soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 1 - soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 1 - .../actors/ovl_En_Heishi2/z_en_heishi2.c | 4 +- soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c | 1 - soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c | 1 - soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 1 - soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c | 1 - .../actors/ovl_En_Niw_Lady/z_en_niw_lady.c | 1 - .../overlays/actors/ovl_En_Toryo/z_en_toryo.c | 1 - .../misc/ovl_kaleido_scope/z_kaleido_item.c | 48 +++++++++---- 32 files changed, 246 insertions(+), 165 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/ShuffleTradeItems.c create mode 100644 soh/soh/Enhancements/randomizer/ShuffleTradeItems.h delete mode 100644 soh/soh/Enhancements/randomizer/adult_trade_shuffle.c delete mode 100644 soh/soh/Enhancements/randomizer/adult_trade_shuffle.h diff --git a/soh/include/z64save.h b/soh/include/z64save.h index f59271212..f7873031f 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -160,7 +160,6 @@ typedef struct { #pragma region SoH typedef struct ShipRandomizerSaveContextData { - u16 adultTradeItems; u8 triforcePiecesCollected; } ShipRandomizerSaveContextData; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 962f50bd6..b9858aff4 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -19,7 +19,6 @@ extern "C" { #include "functions.h" #include "macros.h" #include "soh/cvar_prefixes.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" extern PlayState* gPlayState; #include "textures/icon_item_static/icon_item_static.h" @@ -414,22 +413,6 @@ void DrawInfoTab() { void DrawBGSItemFlag(uint8_t itemID) { const ItemMapEntry& slotEntry = itemMapping[itemID]; ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1)); - ImGui::SameLine(); - int tradeIndex = itemID - ITEM_POCKET_EGG; - bool hasItem = (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) != 0; - bool shouldHaveItem = hasItem; - ImGui::Checkbox(("##adultTradeFlag" + std::to_string(itemID)).c_str(), &shouldHaveItem); - if (hasItem != shouldHaveItem) { - if (shouldHaveItem) { - gSaveContext.ship.quest.data.randomizer.adultTradeItems |= (1 << tradeIndex); - if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_NONE) { - INV_CONTENT(ITEM_TRADE_ADULT) = ITEM_POCKET_EGG + tradeIndex; - } - } else { - gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~(1 << tradeIndex); - Inventory_ReplaceItem(gPlayState, itemID, Randomizer_GetNextAdultTradeItem()); - } - } } void DrawInventoryTab() { @@ -476,9 +459,6 @@ void DrawInventoryTab() { if (ImGui::BeginPopup(itemPopupPicker)) { if (ImGui::Button("##itemNonePicker", ImVec2(32.0f, 32.0f))) { gSaveContext.inventory.items[selectedIndex] = ITEM_NONE; - if (selectedIndex == SLOT_TRADE_ADULT) { - gSaveContext.ship.quest.data.randomizer.adultTradeItems = 0; - } ImGui::CloseCurrentPopup(); } UIWidgets::SetLastItemHoverText("None"); @@ -512,13 +492,6 @@ void DrawInventoryTab() { ImGui::PopStyleVar(); if (ret) { gSaveContext.inventory.items[selectedIndex] = slotEntry.id; - // Set adult trade item flag if you're playing adult trade shuffle in rando - if (IS_RANDO && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) && - selectedIndex == SLOT_TRADE_ADULT && - slotEntry.id >= ITEM_POCKET_EGG && slotEntry.id <= ITEM_CLAIM_CHECK) { - gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(slotEntry.id); - } ImGui::CloseCurrentPopup(); } UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id)); diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 2a77b9b0a..554a90b2a 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -1600,6 +1600,30 @@ const std::vector flagTables = { { RAND_INF_HYLIA_LAB_KEY_OBTAINED, "RAND_INF_HYLIA_LAB_KEY_OBTAINED" }, { RAND_INF_FISHING_HOLE_UNLOCKED, "RAND_INF_FISHING_HOLE_UNLOCKED" }, { RAND_INF_FISHING_HOLE_KEY_OBTAINED, "RAND_INF_FISHING_HOLE_KEY_OBTAINED" }, + + { RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG, "RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG" }, + { RAND_INF_CHILD_TRADES_HAS_CHICKEN, "RAND_INF_CHILD_TRADES_HAS_CHICKEN" }, + { RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA, "RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_KEATON, "RAND_INF_CHILD_TRADES_HAS_MASK_KEATON" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_SKULL, "RAND_INF_CHILD_TRADES_HAS_MASK_SKULL" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY, "RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY, "RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_GORON, "RAND_INF_CHILD_TRADES_HAS_MASK_GORON" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_ZORA, "RAND_INF_CHILD_TRADES_HAS_MASK_ZORA" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO, "RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH, "RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH" }, + + { RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, "RAND_INF_ADULT_TRADES_HAS_POCKET_EGG" }, + { RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO, "RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO" }, + { RAND_INF_ADULT_TRADES_HAS_COJIRO, "RAND_INF_ADULT_TRADES_HAS_COJIRO" }, + { RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM, "RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM" }, + { RAND_INF_ADULT_TRADES_HAS_ODD_POTION, "RAND_INF_ADULT_TRADES_HAS_ODD_POTION" }, + { RAND_INF_ADULT_TRADES_HAS_SAW, "RAND_INF_ADULT_TRADES_HAS_SAW" }, + { RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN, "RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN" }, + { RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION, "RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION" }, + { RAND_INF_ADULT_TRADES_HAS_FROG, "RAND_INF_ADULT_TRADES_HAS_FROG" }, + { RAND_INF_ADULT_TRADES_HAS_EYEDROPS, "RAND_INF_ADULT_TRADES_HAS_EYEDROPS" }, + { RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK, "RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK" }, } }, }; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 3f2f80265..3bd2ef36e 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -22,6 +22,7 @@ DEFINE_HOOK(OnFlagUnset, (int16_t flagType, int16_t flag)); DEFINE_HOOK(OnSceneSpawnActors, ()); DEFINE_HOOK(OnPlayerUpdate, ()); DEFINE_HOOK(OnOcarinaSongAction, ()); +DEFINE_HOOK(OnCuccoOrChickenHatch, ()); DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price)); DEFINE_HOOK(OnActorInit, (void* actor)); DEFINE_HOOK(OnActorUpdate, (void* actor)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index ab69b543f..b41030cfa 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -80,6 +80,10 @@ void GameInteractor_ExecuteOnOcarinaSongAction() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnCuccoOrChickenHatch() { + GameInteractor::Instance->ExecuteHooks(); +} + void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) { GameInteractor::Instance->ExecuteHooks(cursorIndex, price); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index b73f9fe70..f1b918cef 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -24,6 +24,7 @@ void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag); void GameInteractor_ExecuteOnSceneSpawnActors(); void GameInteractor_ExecuteOnPlayerUpdate(); void GameInteractor_ExecuteOnOcarinaSongAction(); +void GameInteractor_ExecuteOnCuccoOrChickenHatch(); void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor); void GameInteractor_ExecuteOnActorKill(void* actor); @@ -33,7 +34,6 @@ void GameInteractor_ExecuteOnTimestamp (u8 item); void GameInteractor_ExecuteOnPlayerBonk(); void GameInteractor_ExecuteOnPlayerHealthChange(int16_t amount); void GameInteractor_ExecuteOnPlayerBottleUpdate(int16_t contents); -void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price); void GameInteractor_ExecuteOnPlayDestroy(); void GameInteractor_ExecuteOnPlayDrawEnd(); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 1157f3c75..a95dabb00 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -371,6 +371,11 @@ typedef enum { // #### `args` // - `*Actor` VB_DOOR_PLAY_SCENE_TRANSITION, + // Vanilla condition: true + VB_HATCH_CUCCO_OR_CHICKEN, + // Vanilla condition: exchangeItemId == EXCH_ITEM_LETTER_ZELDA + // Opt: s32 + VB_HEISHI2_ACCEPT_ITEM_AS_ZELDAS_LETTER, // #### `result` // In `Interface_DrawAmmoCount`: diff --git a/soh/soh/Enhancements/randomizer/ShuffleTradeItems.c b/soh/soh/Enhancements/randomizer/ShuffleTradeItems.c new file mode 100644 index 000000000..62e0bc9f0 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleTradeItems.c @@ -0,0 +1,51 @@ +#include "functions.h" +#include "variables.h" +#include "macros.h" + +u8 Randomizer_GetNextChildTradeItem() { + const u8 numTradeItems = ITEM_MASK_TRUTH - ITEM_WEIRD_EGG + 1; + u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_CHILD) - ITEM_WEIRD_EGG; + for (int i = 0; i < numTradeItems; i++) { + u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems; + if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG)) { + return ITEM_WEIRD_EGG + tradeIndex; + } + } + return ITEM_NONE; +} + +u8 Randomizer_GetPrevChildTradeItem() { + const u8 numTradeItems = ITEM_MASK_TRUTH - ITEM_WEIRD_EGG + 1; + u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_CHILD) - ITEM_WEIRD_EGG; + for (int i = 0; i < numTradeItems; i++) { + u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems; + if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG)) { + return ITEM_WEIRD_EGG + tradeIndex; + } + } + return ITEM_NONE; +} + +u8 Randomizer_GetNextAdultTradeItem() { + const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1; + u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG; + for (int i = 0; i < numTradeItems; i++) { + u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems; + if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) { + return ITEM_POCKET_EGG + tradeIndex; + } + } + return ITEM_NONE; +} + +u8 Randomizer_GetPrevAdultTradeItem() { + const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1; + u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG; + for (int i = 0; i < numTradeItems; i++) { + u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems; + if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) { + return ITEM_POCKET_EGG + tradeIndex; + } + } + return ITEM_NONE; +} diff --git a/soh/soh/Enhancements/randomizer/ShuffleTradeItems.h b/soh/soh/Enhancements/randomizer/ShuffleTradeItems.h new file mode 100644 index 000000000..a43f7de52 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleTradeItems.h @@ -0,0 +1,11 @@ +#ifndef Z_ADULT_TRADE_SHUFFLE_H +#define Z_ADULT_TRADE_SHUFFLE_H + +#include + +u8 Randomizer_GetNextChildTradeItem(); +u8 Randomizer_GetPrevChildTradeItem(); +u8 Randomizer_GetNextAdultTradeItem(); +u8 Randomizer_GetPrevAdultTradeItem(); + +#endif diff --git a/soh/soh/Enhancements/randomizer/adult_trade_shuffle.c b/soh/soh/Enhancements/randomizer/adult_trade_shuffle.c deleted file mode 100644 index 4bf481d2a..000000000 --- a/soh/soh/Enhancements/randomizer/adult_trade_shuffle.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" -#include "functions.h" -#include "variables.h" -#include "macros.h" - -void Randomizer_ConsumeAdultTradeItem(PlayState* play, u8 itemId) { - gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~ADULT_TRADE_FLAG(itemId); - Inventory_ReplaceItem(play, itemId, Randomizer_GetNextAdultTradeItem()); -} - -u8 Randomizer_GetNextAdultTradeItem() { - const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1; - u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG; - for (int i = 0; i < numTradeItems; i++) { - u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems; - if (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) { - return ITEM_POCKET_EGG + tradeIndex; - } - } - return ITEM_NONE; -} - -u8 Randomizer_GetPrevAdultTradeItem() { - const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1; - u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG; - for (int i = 0; i < numTradeItems; i++) { - u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems; - if (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) { - return ITEM_POCKET_EGG + tradeIndex; - } - } - return ITEM_NONE; -} diff --git a/soh/soh/Enhancements/randomizer/adult_trade_shuffle.h b/soh/soh/Enhancements/randomizer/adult_trade_shuffle.h deleted file mode 100644 index f9894cf4e..000000000 --- a/soh/soh/Enhancements/randomizer/adult_trade_shuffle.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef Z_ADULT_TRADE_SHUFFLE_H -#define Z_ADULT_TRADE_SHUFFLE_H - -#include - -#define ADULT_TRADE_FLAG(itemId) (1 << (itemId - ITEM_POCKET_EGG)) -#define PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(itemID) (IS_RANDO && gSaveContext.ship.quest.data.randomizer.adultTradeItems & ADULT_TRADE_FLAG(itemID)) - -void Randomizer_ConsumeAdultTradeItem(PlayState* play, u8 itemId); -u8 Randomizer_GetNextAdultTradeItem(); -u8 Randomizer_GetPrevAdultTradeItem(); - -#endif diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index e236666f6..f48b7da5a 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -21,7 +21,7 @@ extern "C" { #include "macros.h" #include "functions.h" #include "variables.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/randomizer/ShuffleTradeItems.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" @@ -55,7 +55,6 @@ 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 "adult_trade_shuffle.h" #include "draw.h" extern SaveContext gSaveContext; @@ -219,14 +218,21 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { if (RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && flagType == FLAG_RANDOMIZER_INF) { switch (flag) { case RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD: - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SWORD_BROKEN); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN); + Inventory_ReplaceItem(gPlayState, ITEM_SWORD_BROKEN, Randomizer_GetNextAdultTradeItem()); break; case RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS: - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_EYEDROPS); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_EYEDROPS); + Inventory_ReplaceItem(gPlayState, ITEM_EYEDROPS, Randomizer_GetNextAdultTradeItem()); break; } } + if (flagType == FLAG_EVENT_CHECK_INF && flag == EVENTCHKINF_TALON_WOKEN_IN_CASTLE) { + //remove chicken as this is the only use for it + Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_CHICKEN); + } + RandomizerCheck rc = GetRandomizerCheckFromFlag(flagType, flag); if (rc == RC_UNKNOWN_CHECK) return; @@ -1133,7 +1139,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l EnFr* enFr = va_arg(args, EnFr*); if ( - (enFr->songIndex >= FROG_STORMS && enFr->reward == GI_HEART_PIECE) || + (enFr->songIndex >= FROG_STORMS && enFr->reward == GI_HEART_PIECE) || (enFr->songIndex < FROG_STORMS && enFr->reward == GI_RUPEE_PURPLE) ) { *should = true; @@ -1142,7 +1148,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_TRADE_POCKET_CUCCO: { EnNiwLady* enNiwLady = va_arg(args, EnNiwLady*); - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_POCKET_CUCCO); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO); + Inventory_ReplaceItem(gPlayState, ITEM_POCKET_CUCCO, Randomizer_GetNextAdultTradeItem()); // Trigger the reward now Flags_SetItemGetInf(ITEMGETINF_2E); enNiwLady->actionFunc = func_80ABA778; @@ -1151,13 +1158,15 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_TRADE_COJIRO: { - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_COJIRO); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO); + Inventory_ReplaceItem(gPlayState, ITEM_COJIRO, Randomizer_GetNextAdultTradeItem()); *should = false; break; } case VB_TRADE_ODD_MUSHROOM: { EnDs* granny = va_arg(args, EnDs*); - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_MUSHROOM); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM); + Inventory_ReplaceItem(gPlayState, ITEM_ODD_MUSHROOM, Randomizer_GetNextAdultTradeItem()); // Trigger the reward now Flags_SetItemGetInf(ITEMGETINF_30); granny->actor.textId = 0x504F; @@ -1168,14 +1177,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_TRADE_ODD_POTION: { EnKo* enKo = va_arg(args, EnKo*); - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_POTION); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_POTION); + Inventory_ReplaceItem(gPlayState, ITEM_ODD_POTION, Randomizer_GetNextAdultTradeItem()); // Trigger the reward now Flags_SetItemGetInf(ITEMGETINF_31); *should = false; break; } case VB_TRADE_SAW: { - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SAW); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_SAW); + Inventory_ReplaceItem(gPlayState, ITEM_SAW, Randomizer_GetNextAdultTradeItem()); *should = false; break; } @@ -1192,14 +1203,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l if (func_8002F368(gPlayState) == EXCH_ITEM_PRESCRIPTION || (hasShieldHoldingR && INV_CONTENT(ITEM_TRADE_ADULT) < ITEM_FROG)) { Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION); + Inventory_ReplaceItem(gPlayState, ITEM_PRESCRIPTION, Randomizer_GetNextAdultTradeItem()); } else { Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); } } else { - if (enKz->isTrading){ + if (enKz->isTrading) { Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION); + Inventory_ReplaceItem(gPlayState, ITEM_PRESCRIPTION, Randomizer_GetNextAdultTradeItem()); } else { Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); } @@ -1208,7 +1221,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_TRADE_FROG: { - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_FROG); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_FROG); + Inventory_ReplaceItem(gPlayState, ITEM_FROG, Randomizer_GetNextAdultTradeItem()); *should = false; break; } @@ -1236,9 +1250,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l if (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE)) { break; } - if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { + if (Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO)) { *should = false; - } else if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION)) { + } else if (Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_POTION)) { *should = true; } else { *should = Flags_GetItemGetInf(ITEMGETINF_30); // Traded odd mushroom @@ -1250,10 +1264,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } - if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { + if (Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO)) { *should = false; } else { - *should = PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION); + *should = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_POTION); } break; @@ -1595,6 +1609,13 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } break; } + case VB_HEISHI2_ACCEPT_ITEM_AS_ZELDAS_LETTER: { + if (*should) { + //remove zelda's letter as this is the only use for it + Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); + } + break; + } case VB_FREEZE_ON_SKULL_TOKEN: case VB_TRADE_TIMER_ODD_MUSHROOM: case VB_TRADE_TIMER_FROG: @@ -2293,6 +2314,13 @@ void RandomizerOnKaleidoscopeUpdateHandler(int16_t inDungeonScene) { prevKaleidoState = gPlayState->pauseCtx.state; } +void RandomizerOnCuccoOrChickenHatch() { + if (LINK_IS_CHILD) { + Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_CHICKEN); + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -2310,6 +2338,7 @@ void RandomizerRegisterHooks() { static uint32_t onPlayDestroyHook = 0; static uint32_t onExitGameHook = 0; static uint32_t onKaleidoUpdateHook = 0; + static uint32_t onCuccoOrChickenHatchHook = 0; static uint32_t fishsanityOnActorInitHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0; @@ -2345,6 +2374,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onPlayDestroyHook); GameInteractor::Instance->UnregisterGameHook(onExitGameHook); GameInteractor::Instance->UnregisterGameHook(onKaleidoUpdateHook); + GameInteractor::Instance->UnregisterGameHook(onCuccoOrChickenHatchHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); @@ -2373,6 +2403,7 @@ void RandomizerRegisterHooks() { onPlayDestroyHook = 0; onExitGameHook = 0; onKaleidoUpdateHook = 0; + onCuccoOrChickenHatchHook = 0; fishsanityOnActorInitHook = 0; fishsanityOnActorUpdateHook = 0; @@ -2414,6 +2445,7 @@ void RandomizerRegisterHooks() { onPlayDestroyHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayDestroyHandler); onExitGameHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnExitGameHandler); onKaleidoUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnKaleidoscopeUpdateHandler); + onCuccoOrChickenHatchHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnCuccoOrChickenHatch); if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 5e5389dd4..408ded72e 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -226,7 +226,7 @@ namespace Rando { case RG_EYEBALL_FROG: case RG_EYEDROPS: case RG_CLAIM_CHECK: - return HasAdultTrade(StaticData::RetrieveItem(itemName).GetGIEntry()->itemId); + return CheckRandoInf(itemName - RG_POCKET_EGG + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); case RG_BOTTLE_WITH_BIG_POE: case RG_BOTTLE_WITH_BLUE_FIRE: case RG_BOTTLE_WITH_BLUE_POTION: @@ -1509,7 +1509,7 @@ namespace Rando { case RG_EYEBALL_FROG: case RG_EYEDROPS: case RG_CLAIM_CHECK: - SetAdultTrade(item.GetGIEntry()->itemId, state); + SetRandoInf(randoGet - RG_POCKET_EGG + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, state); break; case RG_PROGRESSIVE_HOOKSHOT: { @@ -2079,26 +2079,10 @@ namespace Rando { return ((1 << item) & mSaveContext->inventory.questItems); } - bool Logic::HasAdultTrade(uint32_t itemID) { - int tradeIndex = itemID - ITEM_POCKET_EGG; - return mSaveContext->ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex); - } - - void Logic::SetAdultTrade(uint32_t itemID, bool state) { - int tradeIndex = itemID - ITEM_POCKET_EGG; - if (!state) { - mSaveContext->ship.quest.data.randomizer.adultTradeItems &= ~(1 << tradeIndex); - } - else { - mSaveContext->ship.quest.data.randomizer.adultTradeItems |= (1 << tradeIndex); - } - } - void Logic::SetQuestItem(uint32_t item, bool state) { if (!state) { mSaveContext->inventory.questItems &= ~(1 << item); - } - else { + } else { mSaveContext->inventory.questItems |= (1 << item); } } @@ -2118,8 +2102,7 @@ namespace Rando { void Logic::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) { if (!state) { mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item]; - } - else { + } else { mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item]; } } @@ -2131,8 +2114,7 @@ namespace Rando { void Logic::SetRandoInf(uint32_t flag, bool state) { if (!state) { mSaveContext->ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); - } - else { + } else { mSaveContext->ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); } } @@ -2144,8 +2126,7 @@ namespace Rando { void Logic::SetEventChkInf(int32_t flag, bool state) { if (!state) { mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); - } - else { + } else { mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); } } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 77d6b2573..4286cc5c3 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -261,8 +261,6 @@ class Logic { bool CheckEquipment(uint32_t item); bool CheckQuestItem(uint32_t item); void SetQuestItem(uint32_t item, bool state); - bool HasAdultTrade(uint32_t item); - void SetAdultTrade(uint32_t item, bool state); uint8_t GetSmallKeyCount(uint32_t dungeonIndex); void SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count); bool CheckDungeonItem(uint32_t item, uint32_t dungeonIndex); diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index e43acf57c..8c4d05a4f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1325,6 +1325,30 @@ typedef enum { RAND_INF_FISHING_HOLE_UNLOCKED, RAND_INF_FISHING_HOLE_KEY_OBTAINED, + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG, + RAND_INF_CHILD_TRADES_HAS_CHICKEN, + RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA, + RAND_INF_CHILD_TRADES_HAS_MASK_KEATON, + RAND_INF_CHILD_TRADES_HAS_MASK_SKULL, + RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY, + RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY, + RAND_INF_CHILD_TRADES_HAS_MASK_GORON, + RAND_INF_CHILD_TRADES_HAS_MASK_ZORA, + RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO, + RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH, + + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, + RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO, + RAND_INF_ADULT_TRADES_HAS_COJIRO, + RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM, + RAND_INF_ADULT_TRADES_HAS_ODD_POTION, + RAND_INF_ADULT_TRADES_HAS_SAW, + RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN, + RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION, + RAND_INF_ADULT_TRADES_HAS_FROG, + RAND_INF_ADULT_TRADES_HAS_EYEDROPS, + RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK, + // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 7e91026b0..fba7c688b 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -260,11 +260,6 @@ extern "C" void Randomizer_InitSaveFile() { // Give Link's pocket item GiveLinksPocketItem(); - // shuffle adult trade quest - if (Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) { - gSaveContext.ship.quest.data.randomizer.adultTradeItems = 0; - } - // remove One Time scrubs with scrubsanity off if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE); @@ -316,6 +311,7 @@ extern "C" void Randomizer_InitSaveFile() { // Set "Got Zelda's Letter" flag. Also ensures Saria is back at SFM. Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); // Got item from impa Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); @@ -325,6 +321,7 @@ extern "C" void Randomizer_InitSaveFile() { // set this at the end to ensure we always start with the letter // this is for the off chance we got the weird egg from impa (which should never happen) INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); } if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { @@ -375,6 +372,7 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_KAK_GATE) == RO_KAK_GATE_OPEN) { Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); + Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); } if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST || @@ -412,6 +410,16 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) { Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); + + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GORON); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_ZORA); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH); + gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index f91696191..55c7d204e 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -218,8 +218,6 @@ void SaveManager::LoadRandomizerVersion1() { } randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, {CustomMessage(ganonText)})); - SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems); - SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount); @@ -348,8 +346,6 @@ void SaveManager::LoadRandomizerVersion2() { SaveManager::Instance->LoadData("warpPreludeText", warpPreludeText); randoContext->AddHint(RH_PRELUDE_WARP_LOC, Rando::Hint(RH_PRELUDE_WARP_LOC, {CustomMessage(warpPreludeText)})); - SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems); - SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount); @@ -445,8 +441,6 @@ void SaveManager::LoadRandomizerVersion3() { randoContext->AddHint(hint, Rando::Hint(hint, json)); }); - SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems); - SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount); @@ -582,8 +576,6 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f }); }); - SaveManager::Instance->SaveData("adultTradeItems", saveContext->ship.quest.data.randomizer.adultTradeItems); - SaveManager::Instance->SaveData("triforcePiecesCollected", saveContext->ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->ship.pendingIceTrapCount); diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c index df5decc4a..2c88ecd80 100644 --- a/soh/src/code/z_kankyo.c +++ b/soh/src/code/z_kankyo.c @@ -6,6 +6,8 @@ #include "soh/frame_interpolation.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" typedef enum { /* 0 */ LENS_FLARE_CIRCLE0, @@ -2111,6 +2113,7 @@ void func_80075B44(PlayState* play) { if ((Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) || Inventory_HatchPocketCucco(play)) && play->csCtx.state == 0 && !Player_InCsMode(play)) { + GameInteractor_ExecuteOnCuccoOrChickenHatch(); Message_StartTextbox(play, 0x3066, NULL); } play->envCtx.unk_E0++; diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 1daa29fb9..f424b9fcd 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -4,7 +4,6 @@ #include "textures/do_action_static/do_action_static.h" #include "textures/icon_item_static/icon_item_static.h" #include "soh_assets.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "libultraship/bridge.h" @@ -2446,8 +2445,17 @@ u8 Item_Give(PlayState* play, u8 item) { Flags_SetItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE); } - if (item >= ITEM_POCKET_EGG) { - gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(item); + if (IS_RANDO) { + if (item >= ITEM_POCKET_EGG) { + Flags_SetRandomizerInf(item - ITEM_POCKET_EGG + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); + } else if (item == ITEM_LETTER_ZELDA) { + //don't care about zelda's letter if it's already been shown to the guard + if (!Flags_GetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD)) { + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); + } + } else { + Flags_SetRandomizerInf(item - ITEM_WEIRD_EGG + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG); + } } temp = INV_CONTENT(item); @@ -2759,12 +2767,12 @@ bool Inventory_HatchPocketCucco(PlayState* play) { return Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO); } - if (!PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_POCKET_EGG)) { + if (!Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) { return 0; } - gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~ADULT_TRADE_FLAG(ITEM_POCKET_EGG); - gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(ITEM_POCKET_CUCCO); + Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO); Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO); return 1; } diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 115369171..e625f4b53 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -521,6 +521,7 @@ void Play_Init(GameState* thisx) { if (Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) || Inventory_HatchPocketCucco(play)) { + GameInteractor_ExecuteOnCuccoOrChickenHatch(); Message_StartTextbox(play, 0x3066, NULL); } diff --git a/soh/src/code/z_scene_table.c b/soh/src/code/z_scene_table.c index c7d76db01..a85965a82 100644 --- a/soh/src/code/z_scene_table.c +++ b/soh/src/code/z_scene_table.c @@ -24,7 +24,6 @@ #include "overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h" #include "soh/mq_asset_hacks.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" @@ -1300,7 +1299,7 @@ void func_8009EE44(PlayState* play) { bool playerHasCojiro = INV_CONTENT(ITEM_COJIRO) == ITEM_COJIRO; if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) { - playerHasCojiro = PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO); + playerHasCojiro = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO); } if ((play->roomCtx.unk_74[0] == 0) && playerHasCojiro) { if (play->roomCtx.unk_74[1] == 50) { diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c index ebc1b07b4..3a85be38b 100644 --- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c +++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c @@ -6,7 +6,6 @@ #include "z_en_ds.h" #include "objects/object_ds/object_ds.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index 22117f9d0..bb43d4709 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -3,7 +3,6 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 1462f8302..264daa595 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -3,7 +3,6 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c index 3a0824bc1..0bb2b1e9d 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c +++ b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c @@ -12,6 +12,8 @@ #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY) @@ -407,7 +409,7 @@ void func_80A53AD4(EnHeishi2* this, PlayState* play) { this->unk_300 = TEXT_STATE_DONE; if (Actor_ProcessTalkRequest(&this->actor, play)) { exchangeItemId = func_8002F368(play); - if (exchangeItemId == EXCH_ITEM_LETTER_ZELDA) { + if (GameInteractor_Should(VB_HEISHI2_ACCEPT_ITEM_AS_ZELDAS_LETTER, exchangeItemId == EXCH_ITEM_LETTER_ZELDA, exchangeItemId)) { Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); player->actor.textId = 0x2010; this->unk_300 = TEXT_STATE_EVENT; diff --git a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c index 468d2124f..0ca12f878 100644 --- a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -7,7 +7,6 @@ #include "z_en_hs.h" #include "vt.h" #include "objects/object_hs/object_hs.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index 33c86821f..9e70ebce1 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -10,7 +10,6 @@ #include "objects/object_km1/object_km1.h" #include "objects/object_kw1/object_kw1.h" #include "vt.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 7e0a3521e..99695266b 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -6,7 +6,6 @@ #include "z_en_kz.h" #include "objects/object_kz/object_kz.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index b1891a296..56f0e70b2 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -6,7 +6,6 @@ #include "z_en_mk.h" #include "objects/object_mk/object_mk.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 2c3b2bbe5..59f2cafc6 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -3,7 +3,6 @@ #include "objects/object_os_anime/object_os_anime.h" #include "overlays/actors/ovl_En_Niw/z_en_niw.h" #include "vt.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index d13309059..15940afc2 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -6,7 +6,6 @@ #include "z_en_toryo.h" #include "objects/object_toryo/object_toryo.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index 6e8a42803..9096271c1 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -1,7 +1,7 @@ #include "z_kaleido_scope.h" #include "textures/parameter_static/parameter_static.h" #include "textures/icon_item_static/icon_item_static.h" -#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/randomizer/ShuffleTradeItems.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" @@ -316,6 +316,10 @@ void KaleidoScope_HandleItemCycleExtras(PlayState* play, u8 slot, bool canCycle, } bool CanMaskSelect() { + if (IS_RANDO) { + return CVarGetInteger(CVAR_ENHANCEMENT("MaskSelect"), 0) /* || Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_TRADE) */; + } + // only allow mask select when: // the shop is open: // * zelda's letter check: Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER) @@ -333,12 +337,20 @@ void KaleidoScope_HandleItemCycles(PlayState* play) { play, SLOT_TRADE_CHILD, CanMaskSelect(), - INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ? - ITEM_MASK_TRUTH : - INV_CONTENT(ITEM_TRADE_CHILD) - 1, - INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ? - ITEM_MASK_KEATON : - INV_CONTENT(ITEM_TRADE_CHILD) + 1, + IS_RANDO ? + Randomizer_GetPrevChildTradeItem() : + ( + INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ? + ITEM_MASK_TRUTH : + INV_CONTENT(ITEM_TRADE_CHILD) - 1 + ), + IS_RANDO ? + Randomizer_GetNextChildTradeItem() : + ( + INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ? + ITEM_MASK_KEATON : + INV_CONTENT(ITEM_TRADE_CHILD) + 1 + ), true ); @@ -379,14 +391,22 @@ void KaleidoScope_DrawItemCycles(PlayState* play) { play, SLOT_TRADE_CHILD, CanMaskSelect(), - INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ? - ITEM_MASK_TRUTH : - INV_CONTENT(ITEM_TRADE_CHILD) - 1, - INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ? - ITEM_MASK_KEATON : - INV_CONTENT(ITEM_TRADE_CHILD) + 1 + IS_RANDO ? + Randomizer_GetPrevChildTradeItem() : + ( + INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ? + ITEM_MASK_TRUTH : + INV_CONTENT(ITEM_TRADE_CHILD) - 1 + ), + IS_RANDO ? + Randomizer_GetNextChildTradeItem() : + ( + INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ? + ITEM_MASK_KEATON : + INV_CONTENT(ITEM_TRADE_CHILD) + 1 + ) ); - + //draw the adult trade select KaleidoScope_DrawItemCycleExtras( play, From 2d78cb561ac504b160f9d1988839fc7890a9d876 Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Thu, 27 Feb 2025 22:33:48 -0500 Subject: [PATCH 08/10] Move Broken Giant's Knife fix hook to its own file (#5049) * Move Broken Giant's Knife fix hook to its own file * Separate IS_RANDO out of value macro * Remove redundant extern * One-line comment --- .../Enhancements/Fixes/BrokenGiantsKnife.cpp | 46 +++++++++++++++++++ soh/soh/Enhancements/mods.cpp | 39 ---------------- 2 files changed, 46 insertions(+), 39 deletions(-) create mode 100644 soh/soh/Enhancements/Fixes/BrokenGiantsKnife.cpp diff --git a/soh/soh/Enhancements/Fixes/BrokenGiantsKnife.cpp b/soh/soh/Enhancements/Fixes/BrokenGiantsKnife.cpp new file mode 100644 index 000000000..6d21d812b --- /dev/null +++ b/soh/soh/Enhancements/Fixes/BrokenGiantsKnife.cpp @@ -0,0 +1,46 @@ +#include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include "functions.h" +#include "macros.h" +#include "variables.h" +#include "z64save.h" + +extern "C" PlayState* gPlayState; + +static constexpr int32_t CVAR_BGS_FIX_DEFAULT = 0; +#define CVAR_BGS_FIX_NAME CVAR_ENHANCEMENT("FixBrokenGiantsKnife") +#define CVAR_BGS_FIX_VALUE CVarGetInteger(CVAR_BGS_FIX_NAME, CVAR_BGS_FIX_DEFAULT) + +void OnReceiveBrokenGiantsKnife(GetItemEntry itemEntry) { + if (itemEntry.itemId != ITEM_SWORD_BGS) { + return; + } + + // Flag wasn't reset because Kokiri or Master Sword was missing, so we need to bypass those checks + int32_t bypassEquipmentChecks = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER); + + int32_t allSwordsInEquipment = bypassEquipmentChecks | ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD); + int32_t allSwordFlags = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | + (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE); + + if (allSwordsInEquipment != allSwordFlags) { + return; + } + + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); + + if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; + if (gPlayState != NULL) { + Interface_LoadItemIcon1(gPlayState, 0); + } + } +} + +void RegisterBrokenGiantsKnifeFix() { + // If enhancement is off, flag should be handled exclusively by vanilla behaviour + COND_HOOK(OnItemReceive, CVAR_BGS_FIX_VALUE || IS_RANDO, OnReceiveBrokenGiantsKnife); +} + +static RegisterShipInitFunc initFunc(RegisterBrokenGiantsKnifeFix, { CVAR_BGS_FIX_NAME, "IS_RANDO" }); diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index e6777644e..cd60f7d8c 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -35,7 +35,6 @@ #include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h" #include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h" -#include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_child/object_link_child.h" @@ -47,7 +46,6 @@ extern "C" { #include "align_asset_macro.h" #include "macros.h" #include "soh/cvar_prefixes.h" -#include "functions.h" #include "variables.h" #include "functions.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h" @@ -552,42 +550,6 @@ void RegisterResetNaviTimer() { }); } -void RegisterBrokenGiantsKnifeFix() { - GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { - if (itemEntry.itemId != ITEM_SWORD_BGS) { - return; - } - - int32_t bypassEquipmentChecks = 0; - - if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), 0)) { - // Flag wasn't reset because Kokiri or Master Sword was missing, so we need to - // bypass those checks - bypassEquipmentChecks |= (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER); - } else { - // If enhancement is off, flag should be handled exclusively by vanilla behaviour - return; - } - - int32_t allSwordsInEquipment = bypassEquipmentChecks | ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD); - int32_t allSwordFlags = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | - (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE); - - if (allSwordsInEquipment != allSwordFlags) { - return; - } - - gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); - - if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; - if (gPlayState != NULL) { - Interface_LoadItemIcon1(gPlayState, 0); - } - } - }); -} - //this map is used for enemies that can be uniquely identified by their id //and that are always counted //enemies that can't be uniquely identified by their id @@ -1098,7 +1060,6 @@ void InitMods() { RegisterMenuPathFix(); RegisterMirrorModeHandler(); RegisterResetNaviTimer(); - RegisterBrokenGiantsKnifeFix(); RegisterEnemyDefeatCounts(); RegisterBossDefeatTimestamps(); RegisterRandomizedEnemySizes(); From eb6c0d9d29da4abdfe23ead81d53d7b765aba6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 28 Feb 2025 03:34:16 +0000 Subject: [PATCH 09/10] presets: clear blocks (#5098) * presets: clear blocks this avoids needing to list every new cvar in presets.h * avoid resetting selected preset * no cvar lists, clear less blocks on drop --- soh/soh/Enhancements/presets.cpp | 11 +- soh/soh/Enhancements/presets.h | 499 +------------------------------ soh/soh/OTRGlobals.cpp | 8 +- 3 files changed, 12 insertions(+), 506 deletions(-) diff --git a/soh/soh/Enhancements/presets.cpp b/soh/soh/Enhancements/presets.cpp index 4ba4b62be..2b1812d21 100644 --- a/soh/soh/Enhancements/presets.cpp +++ b/soh/soh/Enhancements/presets.cpp @@ -6,12 +6,6 @@ #include "soh/SohGui/UIWidgets.hpp" #include -void clearCvars(std::vector cvarsToClear) { - for(const char* cvar : cvarsToClear) { - CVarClear(cvar); - } -} - std::string FormatLocations(std::vector locs) { std::string locString = ""; for (auto loc: locs) { @@ -69,10 +63,13 @@ void DrawPresetSelector(PresetType presetTypeId) { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f)); if (ImGui::Button(("Apply Preset##" + presetTypeCvar).c_str())) { - clearCvars(presetTypeDef.cvarsToClear); + for(const char* block : presetTypeDef.blocksToClear) { + CVarClearBlock(block); + } if (selectedPresetId != 0) { applyPreset(selectedPresetDef.entries); } + CVarSetInteger(presetTypeCvar.c_str(), selectedPresetId); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); if (presetTypeId == PRESET_TYPE_RANDOMIZER){ Rando::Settings::GetInstance()->ReloadOptions(); diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 329fbcdc8..2922ec589 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -61,499 +61,6 @@ void applyPreset(std::vector entries); // TODO: Ideally everything below this point will come from one/many JSON files -const std::vector enhancementsCvars = { - CVAR_SETTING("DPadOnPause"), - CVAR_SETTING("DpadInText"), - CVAR_SETTING("OcarinaControl.Dpad"), - CVAR_SETTING("OcarinaControl.RStick"), - CVAR_ENHANCEMENT("DpadEquips"), - CVAR_ENHANCEMENT("PauseAnyCursor"), - CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), - CVAR_ENHANCEMENT("NaviOnL"), - CVAR_SETTING("FreeLook.InvertXAxis"), - CVAR_SETTING("FreeLook.InvertYAxis"), - CVAR_SETTING("Controls.RightStickAim"), - CVAR_SETTING("DisableFirstPersonAutoCenterView"), - CVAR_ENHANCEMENT("TextSpeed"), - CVAR_ENHANCEMENT("MweepSpeed"), - CVAR_ENHANCEMENT("ForgeTime"), - CVAR_ENHANCEMENT("ClimbSpeed"), - CVAR_ENHANCEMENT("FasterBlockPush"), - CVAR_ENHANCEMENT("CrawlSpeed"), - CVAR_ENHANCEMENT("FasterHeavyBlockLift"), - CVAR_ENHANCEMENT("NoForcedNavi"), - CVAR_ENHANCEMENT("SkulltulaFreeze"), - CVAR_ENHANCEMENT("MMBunnyHood"), - CVAR_ENHANCEMENT("AdultMasks"), - CVAR_ENHANCEMENT("FastChests"), - CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), - CVAR_ENHANCEMENT("FastDrops"), - CVAR_ENHANCEMENT("BetterOwl"), - CVAR_ENHANCEMENT("FastOcarinaPlayback"), - CVAR_ENHANCEMENT("InstantPutaway"), - CVAR_ENHANCEMENT("FastBoomerang"), - CVAR_ENHANCEMENT("AskToEquip"), - CVAR_ENHANCEMENT("MaskSelect"), - CVAR_ENHANCEMENT("RememberSaveLocation"), - CVAR_ENHANCEMENT("DamageMult"), - CVAR_ENHANCEMENT("FallDamageMult"), - CVAR_ENHANCEMENT("VoidDamageMult"), - CVAR_ENHANCEMENT("BonkDamageMult"), - CVAR_ENHANCEMENT("NoRandomDrops"), - CVAR_ENHANCEMENT("NoHeartDrops"), - CVAR_ENHANCEMENT("EnableBombchuDrops"), - CVAR_ENHANCEMENT("GoronPot"), - CVAR_ENHANCEMENT("FullHealthSpawn"), - CVAR_ENHANCEMENT("DampeWin"), - CVAR_ENHANCEMENT("CustomizeFishing"), - CVAR_ENHANCEMENT("InstantFishing"), - CVAR_ENHANCEMENT("GuaranteeFishingBite"), - CVAR_ENHANCEMENT("FishNeverEscape"), - CVAR_ENHANCEMENT("MinimumFishWeightChild"), - CVAR_ENHANCEMENT("MinimumFishWeightAdult"), - CVAR_ENHANCEMENT("LowHpAlarm"), - CVAR_ENHANCEMENT("MinimalUI"), - CVAR_ENHANCEMENT("DisableNaviCallAudio"), - CVAR_ENHANCEMENT("VisualAgony"), - CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), - CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), - CVAR_ENHANCEMENT("CowOfTime"), - CVAR_ENHANCEMENT("GuardVision"), - CVAR_ENHANCEMENT("TimeFlowFileSelect"), - CVAR_ENHANCEMENT("InjectItemCounts.GoldSkulltula"), - CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece"), - CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer"), - CVAR_ENHANCEMENT("DayGravePull"), - CVAR_ENHANCEMENT("DampeAllNight"), - CVAR_ENHANCEMENT("QuitFishingAtDoor"), - CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"), - CVAR_ENHANCEMENT("InstantScarecrow"), - CVAR_ENHANCEMENT("BlueFireArrows"), - CVAR_ENHANCEMENT("SunlightArrows"), - CVAR_ENHANCEMENT("MinFrameCount"), - CVAR_ENHANCEMENT("NewDrops"), - CVAR_ENHANCEMENT("DisableBlackBars"), - CVAR_ENHANCEMENT("DynamicWalletIcon"), - CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), - CVAR_ENHANCEMENT("FixMenuLR"), - CVAR_ENHANCEMENT("NGCKaleidoSwitcher"), - CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), - CVAR_ENHANCEMENT("TwoHandedIdle"), - CVAR_ENHANCEMENT("GravediggingTourFix"), - CVAR_ENHANCEMENT("DekuNutUpgradeFix"), - CVAR_ENHANCEMENT("NaviTextFix"), - CVAR_ENHANCEMENT("AnubisFix"), - CVAR_ENHANCEMENT("CrouchStabHammerFix"), - CVAR_ENHANCEMENT("CrouchStabFix"), - CVAR_ENHANCEMENT("GerudoWarriorClothingFix"), - CVAR_ENHANCEMENT("FixCameraDrift"), - CVAR_ENHANCEMENT("FixCameraSwing"), - CVAR_ENHANCEMENT("FixHangingLedgeSwingRate"), - CVAR_ENHANCEMENT("RedGanonBlood"), - CVAR_ENHANCEMENT("HoverFishing"), - CVAR_ENHANCEMENT("N64WeirdFrames"), - CVAR_ENHANCEMENT("BombchusOOB"), - CVAR_ENHANCEMENT("QuickPutaway"), - CVAR_ENHANCEMENT("GSCutscene"), - CVAR_ENHANCEMENT("RestoreRBAValues"), - CVAR_ENHANCEMENT("SkipSaveConfirmation"), - CVAR_ENHANCEMENT("DisableCritWiggle"), - CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), - CVAR_ENHANCEMENT("SkipArrowAnimation"), - CVAR_ENHANCEMENT("SeparateArrows"), - CVAR_ENHANCEMENT("CustomizeShootingGallery"), - CVAR_ENHANCEMENT("InstantShootingGalleryWin"), - CVAR_ENHANCEMENT("ConstantAdultGallery"), - CVAR_ENHANCEMENT("ShootingGalleryAmmoChild"), - CVAR_ENHANCEMENT("ShootingGalleryAmmoAdult"), - CVAR_ENHANCEMENT("CustomizeBombchuBowling"), - CVAR_ENHANCEMENT("BombchuBowlingNoSmallCucco"), - CVAR_ENHANCEMENT("BombchuBowlingNoBigCucco"), - CVAR_ENHANCEMENT("BombchuBowlingAmmo"), - CVAR_ENHANCEMENT("CustomizeOcarinaGame"), - CVAR_ENHANCEMENT("InstantOcarinaGameWin"), - CVAR_ENHANCEMENT("OcarinaGame.NoteSpeed"), - CVAR_ENHANCEMENT("OcarinaUnlimitedFailTime"), - CVAR_ENHANCEMENT("OcarinaGame.StartingNotes"), - CVAR_ENHANCEMENT("OcarinaGame.RoundOneNotes"), - CVAR_ENHANCEMENT("OcarinaGame.RoundTwoNotes"), - CVAR_ENHANCEMENT("OcarinaGame.RoundThreeNotes"), - CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), - CVAR_ENHANCEMENT("InstantFrogsGameWin"), - CVAR_ENHANCEMENT("FrogsUnlimitedFailTime"), - CVAR_ENHANCEMENT("FrogsModifyFailTime"), - CVAR_ENHANCEMENT("CreditsFix"), - CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), - CVAR_ENHANCEMENT("StaticExplosionRadius"), - CVAR_ENHANCEMENT("NoInputForCredits"), - CVAR_ENHANCEMENT("FastFarores"), - CVAR_ENHANCEMENT("NightGSAlwaysSpawn"), - CVAR_ENHANCEMENT("SkipText"), - CVAR_ENHANCEMENT("LinkDefaultName"), - CVAR_ENHANCEMENT("MarketSneak"), - CVAR_ENHANCEMENT("TimeTravel"), - CVAR_ENHANCEMENT("NutsExplodeBombs"), - CVAR_ENHANCEMENT("BowSlingshotAmmoFix"), - CVAR_ENHANCEMENT("BetterFarore"), - CVAR_ENHANCEMENT("DisableFirstPersonChus"), - CVAR_ENHANCEMENT("BetterBombchuShopping"), - CVAR_ENHANCEMENT("HyperBosses"), - CVAR_ENHANCEMENT("RupeeDash"), - CVAR_ENHANCEMENT("RupeeDashInterval"), - CVAR_ENHANCEMENT("DogFollowsEverywhere"), - CVAR_ENHANCEMENT("DisableTunicWarningText"), - CVAR_ENHANCEMENT("DisableLOD"), - CVAR_ENHANCEMENT("DisableDrawDistance"), - CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), - CVAR_ENHANCEMENT("WidescreenActorCulling"), - CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"), - CVAR_LOW_RES_MODE, - CVAR_ENHANCEMENT("DrawLineupTick"), - CVAR_ENHANCEMENT("QuickBongoKill"), - CVAR_ENHANCEMENT("FirstPersonGauntlets"), - CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), - CVAR_Z_FIGHTING_MODE, - CVAR_ENHANCEMENT("AuthenticLogo"), - CVAR_ENHANCEMENT("BowReticle"), - CVAR_ENHANCEMENT("BoomerangFirstPerson"), - CVAR_ENHANCEMENT("BoomerangReticle"), - CVAR_ENHANCEMENT("FixTexturesOOB"), - CVAR_ENHANCEMENT("IvanCoopModeEnabled"), - CVAR_ENHANCEMENT("EnemySpawnsOverWaterboxes"), - CVAR_ENHANCEMENT("TreesDropSticks"), - CVAR_ENHANCEMENT("ShadowTag"), - CVAR_ENHANCEMENT("RandomizedEnemySizes"), - CVAR_ENHANCEMENT("RandomizedEnemies"), - CVAR_ENHANCEMENT("MirroredWorldMode"), - CVAR_ENHANCEMENT("MirroredWorld"), - CVAR_ENHANCEMENT("HyperEnemies"), - CVAR_ENHANCEMENT("HookshotableReticle"), - CVAR_ENHANCEMENT("HideBunnyHood"), - CVAR_ENHANCEMENT("FixVineFall"), - CVAR_ENHANCEMENT("FileSelectMoreInfo"), - CVAR_ENHANCEMENT("EnemyHealthBar"), - CVAR_ENHANCEMENT("BushDropFix"), - CVAR_ENHANCEMENT("AllDogsRichard"), - CVAR_ENHANCEMENT("ExtraTraps.Enabled"), - CVAR_ENHANCEMENT("ExtraTraps.Ammo"), - CVAR_ENHANCEMENT("ExtraTraps.Bomb"), - CVAR_ENHANCEMENT("ExtraTraps.Burn"), - CVAR_ENHANCEMENT("ExtraTraps.Ice"), - CVAR_ENHANCEMENT("ExtraTraps.Kill"), - CVAR_ENHANCEMENT("ExtraTraps.Knockback"), - CVAR_ENHANCEMENT("ExtraTraps.Shock"), - CVAR_ENHANCEMENT("ExtraTraps.Speed"), - CVAR_ENHANCEMENT("ExtraTraps.Teleport"), - CVAR_ENHANCEMENT("ExtraTraps.Void"), - CVAR_ENHANCEMENT("ToTMedallionsColors"), - CVAR_ENHANCEMENT("CuccoStayDurationMult"), - CVAR_ENHANCEMENT("DeleteFileOnDeath"), - CVAR_ENHANCEMENT("EnemySizeScalesHealth"), - CVAR_ENHANCEMENT("BetterAmmoRendering"), - CVAR_ENHANCEMENT("EquipmentAlwaysVisible"), - CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"), - CVAR_ENHANCEMENT("OpenAllHours"), - CVAR_ENHANCEMENT("ResetNaviTimer"), - CVAR_ENHANCEMENT("ScaleAdultEquipmentAsChild"), - CVAR_ENHANCEMENT("LeeverSpawnRate"), - CVAR_ENHANCEMENT("SwordToggle"), - CVAR_ENHANCEMENT("FixFloorSwitches"), - CVAR_ENHANCEMENT("FixZoraHintDialogue"), - CVAR_ENHANCEMENT("HurtContainer"), - CVAR_ENHANCEMENT("PauseWarp"), - CVAR_ENHANCEMENT("PermanentHeartLoss"), - CVAR_ENHANCEMENT("RemoveExplosiveLimit"), - CVAR_ENHANCEMENT("ToggleStrength"), - CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), - CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), - CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), - CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), - CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), - CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), - CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), - CVAR_ENHANCEMENT("TimeSavers.NoForcedDialog"), - CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), - CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), - CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), - CVAR_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), - CVAR_ENHANCEMENT("TimeSavers.SkipChildStealth"), - CVAR_ENHANCEMENT("TimeSavers.SkipTowerEscape"), - CVAR_ENHANCEMENT("TimeSavers.SkipForcedDialog"), - CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), - CVAR_ENHANCEMENT("SlowTextSpeed"), -}; - -const std::vector cheatCvars = { - CVAR_CONSOLE_WINDOW_OPEN, - CVAR_WINDOW("ActorViewer"), - CVAR_WINDOW("CollisionViewer"), - CVAR_WINDOW("DLViewer"), - CVAR_WINDOW("SaveEditor"), - CVAR_SETTING("WalkModifier.Enabled"), - CVAR_SETTING("WalkModifier.SpeedToggle"), - CVAR_SETTING("WalkModifier.Mapping1"), - CVAR_SETTING("WalkModifier.Mapping2"), - CVAR_SETTING("WalkModifier.SwimMapping1"), - CVAR_SETTING("WalkModifier.SwimMapping2"), - CVAR_ENHANCEMENT("GoronPot"), - CVAR_ENHANCEMENT("DampeWin"), - CVAR_ENHANCEMENT("CustomizeShootingGallery"), - CVAR_ENHANCEMENT("CustomizeBombchuBowling"), - CVAR_ENHANCEMENT("CustomizeFishing"), - CVAR_CHEAT("InfiniteAmmo"), - CVAR_CHEAT("InfiniteEponaBoost"), - CVAR_CHEAT("InfiniteHealth"), - CVAR_CHEAT("InfiniteMagic"), - CVAR_CHEAT("InfiniteMoney"), - CVAR_CHEAT("InfiniteNayru"), - CVAR_CHEAT("NoClip"), - CVAR_CHEAT("ClimbEverything"), - CVAR_CHEAT("HookshotEverything"), - CVAR_CHEAT("HookshotReachMultiplier"), - CVAR_CHEAT("MoonJumpOnL"), - CVAR_CHEAT("SuperTunic"), - CVAR_CHEAT("EasyISG"), - CVAR_CHEAT("EasyQPA"), - CVAR_CHEAT("TimelessEquipment"), - CVAR_CHEAT("NoRestrictItems"), - CVAR_CHEAT("FreezeTime"), - CVAR_GENERAL("PrevTime"), - CVAR_CHEAT("DropsDontDie"), - CVAR_CHEAT("FireproofDekuShield"), - CVAR_CHEAT("ShieldTwoHanded"), - CVAR_CHEAT("TimeSync"), - CVAR_DEVELOPER_TOOLS("DebugEnabled"), - CVAR_DEVELOPER_TOOLS("SkulltulaDebugEnabled"), - CVAR_DEVELOPER_TOOLS("SkipLogoTitle"), - CVAR_DEVELOPER_TOOLS("SaveFileID"), - CVAR_CHEAT("EnableBetaQuest"), - CVAR_DEVELOPER_TOOLS("BetterDebugWarpScreen"), - CVAR_CHEAT("NoRedeadFreeze"), - CVAR_CHEAT("NoKeeseGuayTarget"), - CVAR_CHEAT("BombTimerMultiplier"), - CVAR_CHEAT("NoFishDespawn"), - CVAR_CHEAT("NoBugsDespawn"), - CVAR_SETTING("WalkModifier.DoesntChangeJump"), - CVAR_STATS_WINDOW_OPEN, - CVAR_CHEAT("SaveStatesEnabled"), - CVAR_CHEAT("SaveStatePromise"), - CVAR_DEVELOPER_TOOLS("RegEditEnabled"), - CVAR_CHEAT("DekuStick"), - CVAR_DEVELOPER_TOOLS("DebugWarpScreenTranslation"), - CVAR_DEVELOPER_TOOLS("DebugSaveFileMode"), - CVAR_COSMETIC("Link.BodyScale.Changed"), - CVAR_COSMETIC("Link.BodyScale.Value"), - CVAR_COSMETIC("Link.HeadScale.Changed"), - CVAR_COSMETIC("Link.HeadScale.Value"), - CVAR_COSMETIC("Link.SwordScale.Changed"), - CVAR_COSMETIC("Link.SwordScale.Value"), - CVAR_ENHANCEMENT("RememberMapToggleState"), -}; - -const std::vector randomizerCvars = { - CVAR_RANDOMIZER_ENHANCEMENT("MatchKeyColors"), - CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"), - CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"), - CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), - CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"), - CVAR_RANDOMIZER_SETTING("100GSHint"), - CVAR_RANDOMIZER_SETTING("10GSHint"), - CVAR_RANDOMIZER_SETTING("20GSHint"), - CVAR_RANDOMIZER_SETTING("30GSHint"), - CVAR_RANDOMIZER_SETTING("40GSHint"), - CVAR_RANDOMIZER_SETTING("50GSHint"), - CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), - CVAR_RANDOMIZER_SETTING("AltarHint"), - CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), - CVAR_RANDOMIZER_SETTING("BigPoesHint"), - CVAR_RANDOMIZER_SETTING("BiggoronHint"), - CVAR_RANDOMIZER_SETTING("BlueFireArrows"), - CVAR_RANDOMIZER_SETTING("BombchuBag"), - CVAR_RANDOMIZER_SETTING("BossKeysanity"), - CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), - CVAR_RANDOMIZER_SETTING("ChickensHint"), - CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), - CVAR_RANDOMIZER_SETTING("CuccosToReturn"), - CVAR_RANDOMIZER_SETTING("DampeHint"), - CVAR_RANDOMIZER_SETTING("DecoupleEntrances"), - CVAR_RANDOMIZER_SETTING("DoorOfTime"), - CVAR_RANDOMIZER_SETTING("DungeonCount"), - CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), - CVAR_RANDOMIZER_SETTING("FishingPoleHint"), - CVAR_RANDOMIZER_SETTING("Fishsanity"), - CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), - CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), - CVAR_RANDOMIZER_SETTING("ClosedForest"), - CVAR_RANDOMIZER_SETTING("FrogsHint"), - CVAR_RANDOMIZER_SETTING("FullWallets"), - CVAR_RANDOMIZER_SETTING("GanonTrial"), - CVAR_RANDOMIZER_SETTING("GanonTrialCount"), - CVAR_RANDOMIZER_SETTING("GanondorfHint"), - CVAR_RANDOMIZER_SETTING("FortressCarpenters"), - CVAR_RANDOMIZER_SETTING("GerudoKeys"), - CVAR_RANDOMIZER_SETTING("GossipStoneHints"), - CVAR_RANDOMIZER_SETTING("GregHint"), - CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), - CVAR_RANDOMIZER_SETTING("HBAHint"), - CVAR_RANDOMIZER_SETTING("HintClarity"), - CVAR_RANDOMIZER_SETTING("HintDistribution"), - CVAR_RANDOMIZER_SETTING("IceTraps"), - CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), - CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"), - CVAR_RANDOMIZER_SETTING("ItemPool"), - CVAR_RANDOMIZER_SETTING("KakarikoGate"), - CVAR_RANDOMIZER_SETTING("Keysanity"), - CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), - CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), - CVAR_RANDOMIZER_SETTING("LacsRewardCount"), - CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), - CVAR_RANDOMIZER_SETTING("LacsStoneCount"), - CVAR_RANDOMIZER_SETTING("LacsTokenCount"), - CVAR_RANDOMIZER_SETTING("LinksPocket"), - CVAR_RANDOMIZER_SETTING("LoachHint"), - CVAR_RANDOMIZER_SETTING("LogicRules"), - CVAR_RANDOMIZER_SETTING("MQDungeonCount"), - CVAR_RANDOMIZER_SETTING("MQDungeons"), - CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), - CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), - CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), - CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), - CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), - CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), - CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), - CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), - CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), - CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), - CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), - CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), - CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), - CVAR_RANDOMIZER_SETTING("MalonHint"), - CVAR_RANDOMIZER_SETTING("MaskShopHint"), - CVAR_RANDOMIZER_SETTING("MedallionCount"), - CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), - CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), - CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), - CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), - CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), - CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), - CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), - CVAR_RANDOMIZER_SETTING("MerchantPrices"), - CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), - CVAR_RANDOMIZER_SETTING("MerchantText"), - CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), - CVAR_RANDOMIZER_SETTING("MixBosses"), - CVAR_RANDOMIZER_SETTING("MixDungeons"), - CVAR_RANDOMIZER_SETTING("MixGrottos"), - CVAR_RANDOMIZER_SETTING("MixInteriors"), - CVAR_RANDOMIZER_SETTING("MixOverworld"), - CVAR_RANDOMIZER_SETTING("MixedEntrances"), - CVAR_RANDOMIZER_SETTING("OoTHint"), - CVAR_RANDOMIZER_SETTING("RainbowBridge"), - CVAR_RANDOMIZER_SETTING("RewardCount"), - CVAR_RANDOMIZER_SETTING("SariaHint"), - CVAR_RANDOMIZER_SETTING("ScrubText"), - CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), - CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), - CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), - CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), - CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), - CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), - CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), - CVAR_RANDOMIZER_SETTING("ScrubsPrices"), - CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"), - CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), - CVAR_RANDOMIZER_SETTING("SheikLAHint"), - CVAR_RANDOMIZER_SETTING("Shopsanity"), - CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), - CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), - CVAR_RANDOMIZER_SETTING("ShopsanityCount"), - CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), - CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), - CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), - CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), - CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), - CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), - CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), - CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), - CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), - CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), - CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), - CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), - CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), - CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), - CVAR_RANDOMIZER_SETTING("ShuffleCows"), - CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), - CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), - CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), - CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), - CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), - CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), - CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), - CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), - CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), - CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsFireTemple"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsForestTemple"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsSpiritTemple"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"), - CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), - CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), - CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), - CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), - CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), - CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), - CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), - CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"), - CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), - CVAR_RANDOMIZER_SETTING("ShuffleSongs"), - CVAR_RANDOMIZER_SETTING("ShuffleSwim"), - CVAR_RANDOMIZER_SETTING("ShuffleTokens"), - CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), - CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), - CVAR_RANDOMIZER_SETTING("SkeletonKey"), - CVAR_RANDOMIZER_SETTING("SkipChildStealth"), - CVAR_RANDOMIZER_SETTING("SkipChildZelda"), - CVAR_RANDOMIZER_SETTING("SkipEponaRace"), - CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), - CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), - CVAR_RANDOMIZER_SETTING("StartingAge"), - CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"), - CVAR_RANDOMIZER_SETTING("StartingConsumables"), - CVAR_RANDOMIZER_SETTING("StartingDekuShield"), - CVAR_RANDOMIZER_SETTING("StartingEponasSong"), - CVAR_RANDOMIZER_SETTING("StartingHearts"), - CVAR_RANDOMIZER_SETTING("StartingKokiriSword"), - CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), - CVAR_RANDOMIZER_SETTING("StartingMasterSword"), - CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"), - CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), - CVAR_RANDOMIZER_SETTING("StartingOcarina"), - CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight"), - CVAR_RANDOMIZER_SETTING("StartingRequiemOfSpirit"), - CVAR_RANDOMIZER_SETTING("StartingSariasSong"), - CVAR_RANDOMIZER_SETTING("StartingSerenadeOfWater"), - CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), - CVAR_RANDOMIZER_SETTING("StartingSongOfStorms"), - CVAR_RANDOMIZER_SETTING("StartingSongOfTime"), - CVAR_RANDOMIZER_SETTING("StartingSunsSong"), - CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), - CVAR_RANDOMIZER_SETTING("StoneCount"), - CVAR_RANDOMIZER_SETTING("SunlightArrows"), - CVAR_RANDOMIZER_SETTING("TokenCount"), - CVAR_RANDOMIZER_SETTING("TriforceHunt"), - CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"), - CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), - CVAR_RANDOMIZER_SETTING("WarpSongText"), - CVAR_RANDOMIZER_SETTING("ZorasFountain"), -}; - const std::vector vanillaPlusPresetEntries = { // D-pad Support in text and file select PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1), @@ -1325,12 +832,12 @@ typedef struct PresetDefinition { } PresetDefinition; typedef struct PresetTypeDefinition { - std::vector cvarsToClear; + std::vector blocksToClear; std::map presets; } PresetTypeDefinition; const std::map presetTypes = { - { PRESET_TYPE_ENHANCEMENTS, { enhancementsCvars, { + { PRESET_TYPE_ENHANCEMENTS, { { CVAR_PREFIX_ENHANCEMENT, CVAR_PREFIX_CHEAT }, { { ENHANCEMENT_PRESET_DEFAULT, { "Default", "Reset all options to their default values.", @@ -1352,7 +859,7 @@ const std::map presetTypes = { randomizerPresetEntries } }, } } }, - { PRESET_TYPE_RANDOMIZER, { randomizerCvars, { + { PRESET_TYPE_RANDOMIZER, { { CVAR_PREFIX_RANDOMIZER_SETTING, CVAR_PREFIX_RANDOMIZER_ENHANCEMENT }, { { RANDOMIZER_PRESET_DEFAULT, { "Default", "Reset all options to their default values.", diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index dc745b0b5..2acc01d7f 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2437,9 +2437,11 @@ void SoH_ProcessDroppedFiles(std::string filePath) { return; } - clearCvars(enhancementsCvars); - clearCvars(cheatCvars); - clearCvars(randomizerCvars); + CVarClearBlock(CVAR_PREFIX_ENHANCEMENT); + CVarClearBlock(CVAR_PREFIX_CHEAT); + CVarClearBlock(CVAR_PREFIX_RANDOMIZER_SETTING); + CVarClearBlock(CVAR_PREFIX_RANDOMIZER_ENHANCEMENT); + CVarClearBlock(CVAR_PREFIX_DEVELOPER_TOOLS); // Flatten everything under CVars into a single array auto cvars = configJson["CVars"].flatten(); From 39e52aa8e6695610cac9e986095f882971d46de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 6 Mar 2025 23:59:02 +0000 Subject: [PATCH 10/10] Fix Gerudo Valley entrance logic (#5094) * Fix Gerudo Valley entrance logic Logic assumed cucco could be used as child to get around lacking bronze scale, but this assumption fails if you enter grotto ledge from grotto or initial spawn * fix lower/upper mixup * fix: you can walk to lake hylia * adult can jump across --- .../randomizer/location_access/overworld/gerudo_valley.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 1c4714e52..a0441dbec 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -13,10 +13,11 @@ void RegionTable_Init_GerudoValley() { }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), - Entrance(RR_GV_UPPER_STREAM, []{return true;}), + Entrance(RR_GV_UPPER_STREAM, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}), Entrance(RR_GV_CRATE_LEDGE, []{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_GV_GROTTO_LEDGE, []{return true;}), Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_LAKE_HYLIA, []{return logic->IsChild;}), //can use cucco as child }); areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, { @@ -41,11 +42,12 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_LOWER_STREAM] = Region("GV Lower Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_LAKE_HYLIA, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE);}),//can use cucco as child + Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), }); areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, { //Exits + Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}), Entrance(RR_GV_LOWER_STREAM, []{return true;}), Entrance(RR_GV_OCTOROK_GROTTO, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}), Entrance(RR_GV_CRATE_LEDGE, []{return logic->CanUse(RG_LONGSHOT);}),