diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 8074fa707..fecb0b673 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -293,8 +293,8 @@ static std::map cosmeticOptions = { COSMETIC_OPTION("Key.FortSmallEmblem", "Fortress Small Key Emblem",COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false), COSMETIC_OPTION("Key.GTGSmallBody", "GTG Small Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false), COSMETIC_OPTION("Key.GTGSmallEmblem", "GTG Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(221, 212, 60, 255), false, true, false), - //COSMETIC_OPTION("Key.ChestGameSmallBody", "Chest Game Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false), - //COSMETIC_OPTION("Key.ChestGameEmblem", "Chest Game Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false), + COSMETIC_OPTION("Key.ChestGameSmallBody", "Chest Game Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Key.ChestGameEmblem", "Chest Game Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false), COSMETIC_OPTION("Key.Skeleton", "Skeleton Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 170, 255), false, true, false), COSMETIC_OPTION("HUD.AButton", "A Button", COSMETICS_GROUP_HUD, ColorRGBA8( 90, 90, 255, 255), false, true, false), diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 186307aed..8a34ba05f 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2222,6 +2222,54 @@ typedef enum { // - `s32` limbCount // - `*Vec3s` frameTable VB_LOAD_PLAYER_ANIMATION_FRAME, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnTakaraMan` + VB_TAKARA_MAN_RESET_CHESTS_AND_KEYS, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnTakaraMan` + VB_TAKARA_MAN_OFFER_GET_ITEM, + + // #### `result` + // ```c + // Rand_ZeroFloat(1.99f) < 1.0f + // ``` + // #### `args` + // - `*EnChanger` + VB_EN_CHANGER_SWAP_CHESTS, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*DoorShutter` + VB_DOOR_SHUTTER_SET_SWITCH_FLAG, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnBox` + VB_CHEST_SET_TREASURE_FLAG, + + // #### `result` + // ```c + // Flags_GetTreasure(play, this->dyna.actor.params & 0x1F) + // ``` + // #### `args` + // - `*EnBox` + VB_CHEST_CONSIDER_CHEST_OPEN, } GIVanillaBehavior; #endif diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index 21891ff81..74ab4a554 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -324,7 +324,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, être #le gagnant parmi 32# donne #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/hay una #probabilidad de 1/32# de ganar #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1] = HintText(CustomMessage("They say that the #first locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_LEFT_1] = HintText(CustomMessage("They say that the #first locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #erste verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #première salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la primera sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -338,7 +338,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #premier ou deuxième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el primer o segundo cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2] = HintText(CustomMessage("They say that the #second locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_LEFT_2] = HintText(CustomMessage("They say that the #second locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #zweite verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #deuxième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la segunda sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -352,7 +352,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #troisième ou quatrième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el tercer o cuarto cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3] = HintText(CustomMessage("They say that the #third locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_LEFT_3] = HintText(CustomMessage("They say that the #third locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #dritte verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #troisième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la tercera sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -366,7 +366,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #cinquième ou sixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el quinto o sexto cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4] = HintText(CustomMessage("They say that the #fourth locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_LEFT_4] = HintText(CustomMessage("They say that the #fourth locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #vierte verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #quatrième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la cuarta sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -380,7 +380,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #septième ou huitième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el séptimo u octavo cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5] = HintText(CustomMessage("They say that the #fifth locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_LEFT_5] = HintText(CustomMessage("They say that the #fifth locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #fünfte verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #cinquième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la quinta sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -394,7 +394,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #neuvième ou dixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el noveno o décimo cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_1] = HintText(CustomMessage("They say that the #first locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_1] = HintText(CustomMessage("They say that the #first locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #erste verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #première salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la primera sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -408,7 +408,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #premier ou deuxième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el primer o segundo cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_2] = HintText(CustomMessage("They say that the #second locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_2] = HintText(CustomMessage("They say that the #second locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #zweite verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #deuxième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la segunda sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -422,7 +422,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #troisième ou quatrième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el tercer o cuarto cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_3] = HintText(CustomMessage("They say that the #third locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_3] = HintText(CustomMessage("They say that the #third locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #dritte verschloßene Raum# in der Truhenlotterie, #[[1]]# enthielte.", /*french*/ "Selon moi, la #troisième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la tercera sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -436,7 +436,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #cinquième ou sixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el quinto o sexto cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_4] = HintText(CustomMessage("They say that the #fourth locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_4] = HintText(CustomMessage("They say that the #fourth locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #vierte verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #quatrième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la cuarta sala del Cofre del Tesoro# aguarda #[[1]]#. @@ -450,7 +450,7 @@ void StaticData::HintTable_Init() { /*french*/ "Selon moi, le #septième ou huitième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); // /*spanish*/#el séptimo u octavo cofre del azar# revela #[[1]]#. - hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_5] = HintText(CustomMessage("They say that the #fifth locked room# in the chest game contains #[[1]]#.", + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_5] = HintText(CustomMessage("They say that the #fifth locked room# in the chest game contains #[[1]]#.", /*german*/ "Man erzählt sich, daß der #fünfte verschloßene Raum# in der Truhenlotterie #[[1]]# enthielte.", /*french*/ "Selon moi, la #cinquième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), // /*spanish*/#en la quinta sala del Cofre del Tesoro# aguarda #[[1]]#. diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 3e6588646..c9b88f678 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -712,12 +712,6 @@ void GenerateItemPool() { } AddItemToMainPool(RG_CLAIM_CHECK); - if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS)) { - AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY, 6); // 6 individual keys - } else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK)) { - AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6 - } - if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) { for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { ctx->PlaceItemInLocation(loc, RG_GOLD_SKULLTULA_TOKEN, false, true); @@ -869,6 +863,40 @@ void GenerateItemPool() { // Keys + if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) { + switch (ctx->GetOption(RSK_KEYRINGS_TREASURE_CHEST_GAME).Get()) { + case RO_KEYRINGS_OFF: + AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY, 6); + break; + // random & count handled in settings.cpp + case RO_KEYRINGS_RANDOM: + case RO_KEYRINGS_COUNT: + case RO_KEYRINGS_SELECTION: + switch (ctx->GetOption(RSK_KEYRINGS_TREASURE_CHEST_GAME).Get()) { + case RO_KEYRING_FOR_DUNGEON_OFF: + AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY, 6); + break; + case RO_KEYRING_FOR_DUNGEON_ON: + AddItemToMainPool(RG_TREASURE_GAME_KEY_RING); + break; + case RO_KEYRING_FOR_DUNGEON_RANDOM: + if (Random(0, 2)) { + AddItemToMainPool(RG_TREASURE_GAME_KEY_RING); + } else { + AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY, 6); + } + break; + default: + assert(false); + break; + } + break; + default: + assert(false); + break; + } + } + // For key rings, need to add as many junk items as "missing" keys if (ctx->GetOption(RSK_KEYRINGS).IsNot(RO_KEYRINGS_OFF)) { uint8_t ringJunkAmt = 0; diff --git a/soh/soh/Enhancements/randomizer/ShuffleTreasureChestGame.cpp b/soh/soh/Enhancements/randomizer/ShuffleTreasureChestGame.cpp new file mode 100644 index 000000000..6f3f7f4a3 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleTreasureChestGame.cpp @@ -0,0 +1,158 @@ +#include +#include "soh_assets.h" +#include "static_data.h" +#include +#include "global.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/ObjectExtension/ObjectExtension.h" + +extern "C" { +#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" +#include "src/overlays/actors/ovl_En_Changer/z_en_changer.h" +extern PlayState* gPlayState; +} + +void DoorShutter_RandomizerInit(void* actorRef) { + if (gPlayState->sceneNum != SCENE_TREASURE_BOX_SHOP) { + return; + } + + DoorShutter* shutterDoor = static_cast(actorRef); + + // turn the temp switches into permanent switches + shutterDoor->dyna.actor.params &= ~0x20; + + // do the unlocked check again + if (Flags_GetSwitch(gPlayState, shutterDoor->dyna.actor.params & 0x1F)) { + shutterDoor->unk_16E = 0; + } +} + +void ItemEtcetera_RandomizerInit(void* actorRef) { + if (gPlayState->sceneNum != SCENE_TREASURE_BOX_SHOP) { + return; + } + + Actor* actor = static_cast(actorRef); + + // remove the items visible with lens inside the chests + Actor_Kill(actor); +} + +extern "C" void EnChanger_RandomizerWait(EnChanger* thisx, PlayState* play) {} + +void EnChanger_RandomizerInit(void* actorRef) { + if (gPlayState->sceneNum != SCENE_TREASURE_BOX_SHOP) { + return; + } + + EnChanger* enChanger = static_cast(actorRef); + + // prevent opening one chest from also opening the other & the vanilla "item hover" animation + enChanger->actionFunc = EnChanger_RandomizerWait; +} + +void EnBox_RandomizerInit(void* actorRef) { + if (gPlayState->sceneNum != SCENE_TREASURE_BOX_SHOP || gPlayState->roomCtx.curRoom.num == 6) { + return; + } + + Actor* chest = static_cast(actorRef); + + // make the chests not react to lens as the items visible with lens inside have been removed + chest->flags &= ~ACTOR_FLAG_REACT_TO_LENS; +} + +void RegisterShuffleTreasureChestGame() { + bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_CHEST_MINIGAME); + + // prevents the chest and keys from being reset in the chest minigame upon entry + COND_VB_SHOULD(VB_TAKARA_MAN_RESET_CHESTS_AND_KEYS, shouldRegister, { + *should = false; + }); + + // replace the vanilla shopkeeper item with the randomized item + COND_VB_SHOULD(VB_TAKARA_MAN_OFFER_GET_ITEM, shouldRegister, { + Flags_SetRandomizerInf(RAND_INF_TREASURE_CHEST_GAME_SHOPKEEPER_ITEM); + *should = false; + }); + + // make the chests never swap so they're consistent + COND_VB_SHOULD(VB_EN_CHANGER_SWAP_CHESTS, shouldRegister, { + *should = false; + }); + + COND_VB_SHOULD(VB_CHEST_SET_TREASURE_FLAG, shouldRegister, { + if (gPlayState->sceneNum != SCENE_TREASURE_BOX_SHOP || gPlayState->roomCtx.curRoom.num == 6) { + return; + } + + Actor* chest = va_arg(args, Actor*); + + bool rightChest = chest->world.pos.x > 0; + + u32 randInf = RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_1 + gPlayState->roomCtx.curRoom.num - 1 + (rightChest ? 5 : 0); + + LUSLOG_WARN("gPlayState->roomCtx.curRoom.num = %d", gPlayState->roomCtx.curRoom.num); + LUSLOG_WARN("rightChest = %d", rightChest); + LUSLOG_WARN("randInf = %d", randInf); + + Flags_SetRandomizerInf((RandomizerInf)randInf); + + *should = false; + }); + + COND_VB_SHOULD(VB_CHEST_CONSIDER_CHEST_OPEN, shouldRegister, { + if (gPlayState->sceneNum != SCENE_TREASURE_BOX_SHOP || gPlayState->roomCtx.curRoom.num == 6) { + return; + } + + Actor* chest = va_arg(args, Actor*); + + bool rightChest = chest->world.pos.x > 0; + + RandomizerInf randInf = (RandomizerInf)(RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_1 + gPlayState->roomCtx.curRoom.num - 1 + (rightChest ? 5 : 0)); + + LUSLOG_WARN("gPlayState->roomCtx.curRoom.num = %d", gPlayState->roomCtx.curRoom.num); + LUSLOG_WARN("rightChest = %d", rightChest); + LUSLOG_WARN("randInf = %d", randInf); + + *should = Flags_GetRandomizerInf(randInf); + }); + + COND_ID_HOOK(OnActorInit, ACTOR_DOOR_SHUTTER, shouldRegister, DoorShutter_RandomizerInit); + + COND_ID_HOOK(OnActorInit, ACTOR_ITEM_ETCETERA, shouldRegister, ItemEtcetera_RandomizerInit); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_CHANGER, shouldRegister, EnChanger_RandomizerInit); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_BOX, shouldRegister, EnBox_RandomizerInit); +} + +#define TREASURE_CHEST_GAME_CHECK(rc, params, name, rht, rg, rand_inf) \ + locationTable[rc] = Location::Chest(rc, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, \ + params, name, rht, rg, SpoilerCollectionCheck::RandomizerInf(rand_inf), false) + +void Rando::StaticData::RegisterTreasureChestGameLocations() { + static bool registered = false; + if (registered) + return; + registered = true; + // clang-format off + locationTable[RC_MARKET_TREASURE_CHEST_GAME_SHOPKEEPER_ITEM] = Location::Base(RC_MARKET_TREASURE_CHEST_GAME_SHOPKEEPER_ITEM, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, 0, "Treasure Chest Game Shopkeeper Item", RHT_NONE, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TREASURE_CHEST_GAME_SHOPKEEPER_ITEM)); + + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_LEFT_1, 20023, "Treasure Chest Game First Room Left Chest", RHT_MARKET_TREASURE_CHEST_GAME_LEFT_1, RG_GREEN_RUPEE, RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_1); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_LEFT_2, 20034, "Treasure Chest Game Second Room Left Chest", RHT_MARKET_TREASURE_CHEST_GAME_LEFT_2, RG_GREEN_RUPEE, RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_2); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_LEFT_3, 20068, "Treasure Chest Game Third Room Left Chest", RHT_MARKET_TREASURE_CHEST_GAME_LEFT_3, RG_BLUE_RUPEE, RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_3); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_LEFT_4, 20070, "Treasure Chest Game Fourth Room Left Chest", RHT_MARKET_TREASURE_CHEST_GAME_LEFT_4, RG_BLUE_RUPEE, RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_4); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_LEFT_5, 20104, "Treasure Chest Game Fifth Room Left Chest", RHT_MARKET_TREASURE_CHEST_GAME_LEFT_5, RG_RED_RUPEE, RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_5); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_1, 20001, "Treasure Chest Game First Room Right Chest", RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_1, RG_TREASURE_GAME_SMALL_KEY, RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_1); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_2, 20003, "Treasure Chest Game Second Room Right Chest", RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_2, RG_TREASURE_GAME_SMALL_KEY, RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_2); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_3, 20005, "Treasure Chest Game Third Room Right Chest", RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_3, RG_TREASURE_GAME_SMALL_KEY, RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_3); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_4, 20007, "Treasure Chest Game Fourth Room Right Chest", RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_4, RG_TREASURE_GAME_SMALL_KEY, RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_4); + TREASURE_CHEST_GAME_CHECK(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_5, 20009, "Treasure Chest Game Fifth Room Right Chest", RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_5, RG_TREASURE_GAME_SMALL_KEY, RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_5); + // clang-format-on +} + +static RegisterShipInitFunc initFunc(RegisterShuffleTreasureChestGame, { "IS_RANDO" }); +static RegisterShipInitFunc initTreasureChestGameLocations(Rando::StaticData::RegisterTreasureChestGameLocations); diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 2ee39006d..17ba351ca 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -170,7 +170,6 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_MASTER_SWORD].Is(RO_GENERIC_OFF)) || (location.GetRandomizerCheck() == RC_KAK_100_GOLD_SKULLTULA_REWARD && mOptions[RSK_SHUFFLE_100_GS_REWARD].Is(RO_GENERIC_OFF)) || - location.GetRCType() == RCTYPE_CHEST_GAME || // not supported yet location.GetRCType() == RCTYPE_STATIC_HINT || // can't have items location.GetRCType() == RCTYPE_GOSSIP_STONE || // can't have items (location.GetRCType() == RCTYPE_FROG_SONG && mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES].Is(RO_GENERIC_OFF)) || @@ -180,6 +179,7 @@ void Context::GenerateLocationPool() { location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) || (location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) || + (location.GetRCType() == RCTYPE_CHEST_GAME && mOptions[RSK_SHUFFLE_CHEST_MINIGAME].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_SONG_LOCATION && mOptions[RSK_SHUFFLE_SONGS].Is(RO_SONG_SHUFFLE_OFF)) || (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index d73cebca7..fee2179e0 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -571,43 +571,6 @@ u8 EnGm_RandoCanGetMedigoronItem() { !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); } -void RandomizerSetChestGameRandomizerInf(RandomizerCheck rc) { - switch (rc) { - case RC_MARKET_TREASURE_CHEST_GAME_ITEM_1: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1); - break; - case RC_MARKET_TREASURE_CHEST_GAME_ITEM_2: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2); - break; - case RC_MARKET_TREASURE_CHEST_GAME_ITEM_3: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3); - break; - case RC_MARKET_TREASURE_CHEST_GAME_ITEM_4: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4); - break; - case RC_MARKET_TREASURE_CHEST_GAME_ITEM_5: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5); - break; - case RC_MARKET_TREASURE_CHEST_GAME_KEY_1: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1); - break; - case RC_MARKET_TREASURE_CHEST_GAME_KEY_2: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2); - break; - case RC_MARKET_TREASURE_CHEST_GAME_KEY_3: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3); - break; - case RC_MARKET_TREASURE_CHEST_GAME_KEY_4: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4); - break; - case RC_MARKET_TREASURE_CHEST_GAME_KEY_5: - Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); - break; - default: - break; - } -} - void Player_Action_8084E6D4_override(Player* player, PlayState* play) { if (LinkAnimation_Update(play, &player->skelAnime)) { func_8084DFAC(play, player); @@ -812,9 +775,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } - // if this is a treasure chest game chest then set the appropriate rando inf - RandomizerSetChestGameRandomizerInf(rc); - Player* player = GET_PLAYER(gPlayState); Player_SetupWaitForPutAway(gPlayState, player, func_8083A434_override); @@ -1726,52 +1686,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } void RandomizerOnSceneInitHandler(int16_t sceneNum) { - // Treasure Chest Game - // todo: for now we're just unsetting all of them, we will - // probably need to do something different when we implement shuffle - if (sceneNum == SCENE_TREASURE_BOX_SHOP) { - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4) - ->SetCheckStatus(RCSHOW_UNCHECKED); - Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); - Rando::Context::GetInstance() - ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5) - ->SetCheckStatus(RCSHOW_UNCHECKED); - CheckTracker::RecalculateAllAreaTotals(); - } // ENTRTODO: Move all entrance rando handling to a dedicated file if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 7f22fe83f..a0f457319 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -169,7 +169,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_GERUDO_FORTRESS_SMALL_KEY] = Item(RG_GERUDO_FORTRESS_SMALL_KEY, Text{ "Gerudo Fortress Small Key", "Petite Clé du Repaire des Voleurs", "Kleiner Schlüssel (Diebesversteck)" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xB6, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_SMALL_KEY, RG_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GERUDO_FORTRESS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Kleiner Schlüssel (Ganons Schloß)" }, ITEMTYPE_SMALLKEY, 0xB7, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); - itemTable[RG_GANONS_CASTLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); + itemTable[RG_GANONS_CASTLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{ "Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors", "Kleiner Schlüssel (Truhenlotterie)" }, ITEMTYPE_SMALLKEY, GI_DOOR_KEY, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_SMALL_KEY, ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_NONE); itemTable[RG_TREASURE_GAME_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_GUARD_HOUSE_KEY] = Item(RG_GUARD_HOUSE_KEY, Text{ "Guard House Key", "Clé de la Maison des Gardes", "Schlüssel (Wachhaus)" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GUARD_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_GUARD_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); @@ -228,7 +228,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_WATER_TEMPLE_KEY_RING] = Item(RG_WATER_TEMPLE_KEY_RING, Text{ "Water Temple Key Ring", "Trousseau du Temple de l'Eau", "Schlüsselbund (Wassertempel)" }, ITEMTYPE_SMALLKEY, 0xD7, true, LOGIC_WATER_TEMPLE_KEYS, RHT_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_WATER_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_SPIRIT_TEMPLE_KEY_RING] = Item(RG_SPIRIT_TEMPLE_KEY_RING, Text{ "Spirit Temple Key Ring", "Trousseau du Temple de l'Esprit", "Schlüsselbund (Geistertempel)" }, ITEMTYPE_SMALLKEY, 0xD8, true, LOGIC_SPIRIT_TEMPLE_KEYS, RHT_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); - itemTable[RG_SPIRIT_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); + itemTable[RG_SPIRIT_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_SHADOW_TEMPLE_KEY_RING] = Item(RG_SHADOW_TEMPLE_KEY_RING, Text{ "Shadow Temple Key Ring", "Trousseau du Temple de l'Ombre", "Schlüsselbund (Schattentempel)" }, ITEMTYPE_SMALLKEY, 0xD9, true, LOGIC_SHADOW_TEMPLE_KEYS, RHT_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_SHADOW_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING] = Item(RG_BOTTOM_OF_THE_WELL_KEY_RING, Text{ "Bottom of the Well Key Ring", "Trousseau du Puits", "Schlüsselbund (Grund des Brunnens)" }, ITEMTYPE_SMALLKEY, 0xDA, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_KEY_RING, RG_BOTTOM_OF_THE_WELL_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 4f62d437f..0a76a0dae 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -191,18 +191,19 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", SCENE_TREASURE_BOX_SHOP, {}, { //Locations - LOCATION(RC_GREG_HINT, logic->HasItem(RG_CHILD_WALLET)), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_GREG_HINT, logic->HasItem(RG_CHILD_WALLET)), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_SHOPKEEPER_ITEM, logic->HasItem(RG_CHILD_WALLET) && ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_LEFT_1, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_1, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_LEFT_2, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_2, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_LEFT_3, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_3, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_LEFT_4, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_4, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_LEFT_5, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_RIGHT_5, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5) : logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME) ? logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6) : logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 2fea752cc..c079d60d8 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -193,16 +193,6 @@ void Rando::StaticData::InitLocationTable() { locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, "Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_191), true); locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), true); locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, "10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), true); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5)); // Hyrule Castle locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, "Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG), true); locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, "Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER), true); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 3c0c8345e..7a8268f32 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1508,6 +1508,7 @@ std::map Logic::RandoGetToDungeonScene = { { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, SCENE_BOTTOM_OF_THE_WELL }, { RG_GERUDO_TRAINING_GROUND_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND }, { RG_GERUDO_FORTRESS_SMALL_KEY, SCENE_THIEVES_HIDEOUT }, + { RG_TREASURE_CHEST_GAME_BUILDING_KEY, SCENE_TREASURE_BOX_SHOP }, { RG_GANONS_CASTLE_SMALL_KEY, SCENE_INSIDE_GANONS_CASTLE }, { RG_FOREST_TEMPLE_KEY_RING, SCENE_FOREST_TEMPLE }, { RG_FIRE_TEMPLE_KEY_RING, SCENE_FIRE_TEMPLE }, @@ -1517,6 +1518,7 @@ std::map Logic::RandoGetToDungeonScene = { { RG_BOTTOM_OF_THE_WELL_KEY_RING, SCENE_BOTTOM_OF_THE_WELL }, { RG_GERUDO_TRAINING_GROUND_KEY_RING, SCENE_GERUDO_TRAINING_GROUND }, { RG_GERUDO_FORTRESS_KEY_RING, SCENE_THIEVES_HIDEOUT }, + { RG_TREASURE_GAME_KEY_RING, SCENE_TREASURE_BOX_SHOP }, { RG_GANONS_CASTLE_KEY_RING, SCENE_INSIDE_GANONS_CASTLE }, { RG_FOREST_TEMPLE_BOSS_KEY, SCENE_FOREST_TEMPLE }, { RG_FIRE_TEMPLE_BOSS_KEY, SCENE_FIRE_TEMPLE }, @@ -1910,7 +1912,7 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case ITEMTYPE_FORTRESS_SMALLKEY: case ITEMTYPE_SMALLKEY: { auto randoGet = item.GetRandomizerGet(); - auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_GANONS_CASTLE_KEY_RING; + auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_TREASURE_GAME_KEY_RING; auto dungeonIndex = RandoGetToDungeonScene.find(randoGet)->second; auto count = GetSmallKeyCount(dungeonIndex); if (!state) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 50d11d9b2..53419df6a 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -460,6 +460,8 @@ void Settings::CreateOptionDescriptions() { "D-pad.\n" "\n" "If disabled, only the Claim Check will be found in the pool."; + mOptionDescriptions[RSK_SHUFFLE_CHEST_MINIGAME] = + "Shuffles the keys and rupees in the Treasure Chest Minigame"; mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD] = "Shuffle the item the cursed rich man in the House of Skulltula gives when you " "have collected all 100 Gold Skulltula Tokens.\n" @@ -532,7 +534,7 @@ void Settings::CreateOptionDescriptions() { "\n" "Off - No dungeons will have their keys replaced with keyrings.\n" "\n" - "Random - A random amount of dungeons (0-8 or 9) will have their keys replaced with keyrings.\n" + "Random - A random amount of dungeons (0-8 or 9 or 10) will have their keys replaced with keyrings.\n" "\n" "Count - A specified amount of randomly selected dungeons will have their keys replaced with keyrings.\n" "\n" @@ -541,9 +543,12 @@ void Settings::CreateOptionDescriptions() { "\n" "Selecting key ring for dungeons will have no effect if Small Keys are set to Start With or Vanilla.\n" "\n" + "Normally, the maximum amount of Key Rings will be 8.\n" "If Gerudo Fortress Carpenters is set to Normal, and Gerudo Fortress Keys is set to anything " "other than Vanilla, then the maximum amount of Key Rings that can be selected by Random or " - "Count will be 9. Otherwise, the maximum amount of Key Rings will be 8."; + "Count will be increased by 1.\n" + "If the Treasure Chest Game is shuffled, the maximum amount of Key Rings that can be selected by Random or " + "Count will be increased by 1."; mOptionDescriptions[RSK_GERUDO_KEYS] = "Vanilla - Thieves' Hideout Keys will appear in their vanilla locations.\n" "\n" "Any dungeon - Thieves' Hideout Keys can only appear inside of any dungon.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 5f9027d82..626ebd7e4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3340,22 +3340,6 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, (actorId == ACTOR_ITEM_ETCETERA && actorParams == 2572)) { specialRc = RC_MARKET_TREASURE_CHEST_GAME_REWARD; } - - // todo: handle the itemetc part of this so drawing works when we implement shuffle - if (actorId == ACTOR_EN_BOX) { - bool isAKey = (actorParams & 0x60) == 0x20; - if ((actorParams & 0xF) < 2) { - specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_1 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_1; - } else if ((actorParams & 0xF) < 4) { - specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_2 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_2; - } else if ((actorParams & 0xF) < 6) { - specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_3 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_3; - } else if ((actorParams & 0xF) < 8) { - specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_4 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_4; - } else if ((actorParams & 0xF) < 10) { - specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_5 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_5; - } - } break; } case SCENE_SACRED_FOREST_MEADOW: @@ -5916,8 +5900,8 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { } // dungeon items - if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || - (item >= RG_FOREST_TEMPLE_KEY_RING && item <= RG_GANONS_CASTLE_KEY_RING) || + if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_TREASURE_GAME_SMALL_KEY) || + (item >= RG_FOREST_TEMPLE_KEY_RING && item <= RG_TREASURE_GAME_KEY_RING) || (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) || (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) || (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) { @@ -6005,11 +5989,17 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { mapIndex = SCENE_INSIDE_GANONS_CASTLE; numOfKeysOnKeyring = GANONS_CASTLE_SMALL_KEY_MAX; break; + case RG_TREASURE_GAME_SMALL_KEY: + case RG_TREASURE_GAME_KEY_RING: + mapIndex = SCENE_TREASURE_BOX_SHOP; + numOfKeysOnKeyring = TREASURE_GAME_SMALL_KEY_MAX; + break; default: + assert(false); break; } - if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) { + if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_TREASURE_GAME_SMALL_KEY)) { gSaveContext.ship.stats.dungeonKeys[mapIndex]++; if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { gSaveContext.inventory.dungeonKeys[mapIndex] = 1; @@ -6019,7 +6009,7 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { return Return_Item_Entry(giEntry, RG_NONE); } - if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_GANONS_CASTLE_KEY_RING)) { + if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_TREASURE_GAME_KEY_RING)) { gSaveContext.ship.stats.dungeonKeys[mapIndex] = numOfKeysOnKeyring; gSaveContext.inventory.dungeonKeys[mapIndex] = numOfKeysOnKeyring; return Return_Item_Entry(giEntry, RG_NONE); @@ -6139,5 +6129,7 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { return -1; } + assert(false); + return Return_Item_Entry(giEntry, RG_NONE); } diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..880cee7ec 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1172,18 +1172,19 @@ typedef enum { RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RC_MARKET_LOST_DOG, - RC_MARKET_TREASURE_CHEST_GAME_REWARD, RC_MARKET_10_BIG_POES, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, - RC_MARKET_TREASURE_CHEST_GAME_KEY_1, - RC_MARKET_TREASURE_CHEST_GAME_KEY_2, - RC_MARKET_TREASURE_CHEST_GAME_KEY_3, - RC_MARKET_TREASURE_CHEST_GAME_KEY_4, - RC_MARKET_TREASURE_CHEST_GAME_KEY_5, + RC_MARKET_TREASURE_CHEST_GAME_REWARD, + RC_MARKET_TREASURE_CHEST_GAME_SHOPKEEPER_ITEM, + RC_MARKET_TREASURE_CHEST_GAME_LEFT_1, + RC_MARKET_TREASURE_CHEST_GAME_LEFT_2, + RC_MARKET_TREASURE_CHEST_GAME_LEFT_3, + RC_MARKET_TREASURE_CHEST_GAME_LEFT_4, + RC_MARKET_TREASURE_CHEST_GAME_LEFT_5, + RC_MARKET_TREASURE_CHEST_GAME_RIGHT_1, + RC_MARKET_TREASURE_CHEST_GAME_RIGHT_2, + RC_MARKET_TREASURE_CHEST_GAME_RIGHT_3, + RC_MARKET_TREASURE_CHEST_GAME_RIGHT_4, + RC_MARKET_TREASURE_CHEST_GAME_RIGHT_5, RC_MARKET_GS_GUARD_HOUSE, RC_MARKET_BAZAAR_ITEM_1, RC_MARKET_BAZAAR_ITEM_2, @@ -4313,16 +4314,16 @@ typedef enum { RHT_MARKET_LOST_DOG, RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RHT_MARKET_10_BIG_POES, - RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, - RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, - RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, - RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, - RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, - RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, - RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, - RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, - RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, - RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, + RHT_MARKET_TREASURE_CHEST_GAME_LEFT_1, + RHT_MARKET_TREASURE_CHEST_GAME_LEFT_2, + RHT_MARKET_TREASURE_CHEST_GAME_LEFT_3, + RHT_MARKET_TREASURE_CHEST_GAME_LEFT_4, + RHT_MARKET_TREASURE_CHEST_GAME_LEFT_5, + RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_1, + RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_2, + RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_3, + RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_4, + RHT_MARKET_TREASURE_CHEST_GAME_RIGHT_5, RHT_MARKET_GS_GUARD_HOUSE, RHT_MARKET_BAZAAR_ITEM_1, RHT_MARKET_BAZAAR_ITEM_2, @@ -5919,6 +5920,7 @@ typedef enum { RSK_KEYRINGS_SHADOW_TEMPLE, RSK_KEYRINGS_BOTTOM_OF_THE_WELL, RSK_KEYRINGS_GTG, + RSK_KEYRINGS_TREASURE_CHEST_GAME, RSK_KEYRINGS_GANONS_CASTLE, RSK_SHUFFLE_ENTRANCES, RSK_SHUFFLE_DUNGEON_ENTRANCES, @@ -6365,12 +6367,6 @@ typedef enum { RO_LOCATION_EXCLUDE, } RandoOptionLocationInclusion; -typedef enum { - RO_CHEST_GAME_OFF, - RO_CHEST_GAME_SINGLE_KEYS, - RO_CHEST_GAME_PACK, -} RandoOptionChestGame; - typedef enum { RO_MQ_SET_VANILLA, RO_MQ_SET_MQ, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index da05ee508..9f73c1a59 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -156,8 +156,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { RCTYPE_GOSSIP_STONE) && // don't show gossip stones (maybe gossipsanity will be a thing eventually?) (location.GetRCType() != RCTYPE_STATIC_HINT) && // don't show static hints (location.GetRCType() != RCTYPE_LINKS_POCKET) && // links pocket can be set to nothing if needed - (location.GetRCType() != - RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them + (location.GetRCType() != RCTYPE_CHEST_GAME || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleChestGame"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_SKULL_TOKEN || (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == RO_TOKENSANITY_ALL) || ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d6334b6a0..3c0ed920f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -78,6 +78,7 @@ bool showGanonBossKey; bool showOcarinas; bool show100SkullReward; bool showLinksPocket; +bool showChestGame; bool fortressFast; bool fortressNormal; @@ -1379,6 +1380,10 @@ void LoadSettings() { IS_RANDO ? // don't show Link's Pocket if not randomizer, or if rando and pocket is disabled OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING : false; + showChestGame = + IS_RANDO ? + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME) == RO_GENERIC_YES + : false; if (IS_RANDO) { switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS)) { @@ -1541,8 +1546,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { return (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations (loc->GetRCType() != RCTYPE_GOSSIP_STONE) && // TODO: Don't show hints until tracker supports them (loc->GetRCType() != RCTYPE_STATIC_HINT) && // TODO: Don't show hints until tracker supports them - (loc->GetRCType() != - RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them + (loc->GetRCType() != RCTYPE_CHEST_GAME || showChestGame) && // don't show non final reward chest game checks until we support shuffling them (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it (rc != RC_LINKS_POCKET || showLinksPocket) && OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index d42e14cb1..f1cd20815 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1078,16 +1078,17 @@ DEFINE_RAND_INF(RAND_INF_ZF_GREAT_FAIRY_REWARD) DEFINE_RAND_INF(RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD) DEFINE_RAND_INF(RAND_INF_OGC_GREAT_FAIRY_REWARD) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4) -DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5) +DEFINE_RAND_INF(RAND_INF_TREASURE_CHEST_GAME_SHOPKEEPER_ITEM) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_1) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_2) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_3) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_4) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_LEFT_5) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_1) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_2) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_3) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_4) +DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_RIGHT_5) DEFINE_RAND_INF(RAND_INF_TH_ITEM_FROM_LEADER_OF_FORTRESS) DEFINE_RAND_INF(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN) diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5f8c60ac0..9b14df79f 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -231,7 +231,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_MERCHANT_PRICES_AFFORDABLE, "Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]); OPT_BOOL(RSK_SHUFFLE_FROG_SONG_RUPEES, "Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]); OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, "Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); - OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); + OPT_BOOL(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", CVAR_RANDOMIZER_SETTING("ShuffleChestGame"), mOptionDescriptions[RSK_SHUFFLE_CHEST_MINIGAME]); OPT_BOOL(RSK_SHUFFLE_100_GS_REWARD, "Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_U8(RSK_SHUFFLE_BOSS_SOULS, "Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); OPT_BOOL(RSK_SHUFFLE_DEKU_STICK_BAG, "Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); @@ -253,7 +253,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_LACS_TOKEN_COUNT, "GCBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true); OPT_U8(RSK_LACS_OPTIONS, "GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), mOptionDescriptions[RSK_LACS_OPTIONS], WidgetType::Combobox, RO_LACS_STANDARD_REWARD); OPT_U8(RSK_KEYRINGS, "Key Rings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), mOptionDescriptions[RSK_KEYRINGS], WidgetType::Combobox, RO_KEYRINGS_OFF); - OPT_U8(RSK_KEYRINGS_RANDOM_COUNT, "Keyring Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WidgetType::Slider, 8); + OPT_U8(RSK_KEYRINGS_RANDOM_COUNT, "Keyring Dungeon Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WidgetType::Slider, 8); OPT_U8(RSK_KEYRINGS_GERUDO_FORTRESS, "Gerudo Fortress Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), "", WidgetType::Combobox, 0); OPT_U8(RSK_KEYRINGS_FOREST_TEMPLE, "Forest Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsForestTemple"), "", WidgetType::Combobox, 0); OPT_U8(RSK_KEYRINGS_FIRE_TEMPLE, "Fire Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsFireTemple"), "", WidgetType::Combobox, 0); @@ -262,6 +262,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_KEYRINGS_SHADOW_TEMPLE, "Shadow Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"), "", WidgetType::Combobox, 0); OPT_U8(RSK_KEYRINGS_BOTTOM_OF_THE_WELL, "Bottom of the Well Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"), "", WidgetType::Combobox, 0); OPT_U8(RSK_KEYRINGS_GTG, "Gerudo Training Ground Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), "", WidgetType::Combobox, 0); + OPT_U8(RSK_KEYRINGS_TREASURE_CHEST_GAME, "Treasure Chest Game Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsTreasureChestGame"), "", WidgetType::Combobox, 0); OPT_U8(RSK_KEYRINGS_GANONS_CASTLE, "Ganon's Castle Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"), "", WidgetType::Combobox, 0); //Dummied out due to redundancy with TimeSavers.SkipChildStealth until such a time that logic needs to consider child stealth e.g. because it's freestanding checks are added to freestanding shuffle. //To undo this dummying, readd this setting to an OptionGroup so it appears in the UI, then edit the timesaver check hooks to look at this, and the timesaver setting to lock itself as needed. @@ -1295,6 +1296,7 @@ void Settings::CreateOptions() { &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], + &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_FAIRIES], @@ -1326,6 +1328,7 @@ void Settings::CreateOptions() { &mOptions[RSK_KEYRINGS_SHADOW_TEMPLE], &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], &mOptions[RSK_KEYRINGS_GTG], + &mOptions[RSK_KEYRINGS_TREASURE_CHEST_GAME], &mOptions[RSK_KEYRINGS_GANONS_CASTLE], }, WidgetContainerType::COLUMN); @@ -1565,6 +1568,7 @@ void Settings::CreateOptions() { &mOptions[RSK_KEYRINGS_SHADOW_TEMPLE], &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], &mOptions[RSK_KEYRINGS_GTG], + &mOptions[RSK_KEYRINGS_TREASURE_CHEST_GAME], &mOptions[RSK_KEYRINGS_GANONS_CASTLE], }); mOptionGroups[RSG_STARTING_ITEMS] = @@ -2358,6 +2362,7 @@ void Settings::UpdateOptionProperties() { mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Hide(); mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Hide(); mOptions[RSK_KEYRINGS_GTG].Hide(); + mOptions[RSK_KEYRINGS_TREASURE_CHEST_GAME].Hide(); mOptions[RSK_KEYRINGS_GANONS_CASTLE].Hide(); switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_OFF)) { case RO_KEYRINGS_COUNT: @@ -2376,16 +2381,25 @@ void Settings::UpdateOptionProperties() { mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Unhide(); mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Unhide(); mOptions[RSK_KEYRINGS_GTG].Unhide(); + mOptions[RSK_KEYRINGS_TREASURE_CHEST_GAME].Unhide(); mOptions[RSK_KEYRINGS_GANONS_CASTLE].Unhide(); default: break; } - const uint8_t maxKeyringCount = - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == - RO_GF_CARPENTERS_NORMAL && - CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != RO_GERUDO_KEYS_VANILLA) - ? 9 - : 8; + + u8 maxKeyringCount = 8; + + if ( + CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_NORMAL && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != RO_GERUDO_KEYS_VANILLA + ) { + maxKeyringCount += 1; + } + + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleChestGame"), RO_GENERIC_NO)) { + maxKeyringCount += 1; + } + if (mOptions[RSK_KEYRINGS_RANDOM_COUNT].GetOptionCount() != maxKeyringCount + 1) { mOptions[RSK_KEYRINGS_RANDOM_COUNT].ChangeOptions(NumOpts(0, maxKeyringCount)); } @@ -2612,10 +2626,6 @@ void Context::FinalizeSettings(const std::set& excludedLocation mOptions[RSK_STARTING_NUTS].Set(false); } - // RANDOTODO implement chest shuffle with keysanity - // ShuffleChestMinigame.Set(cvarSettings[RSK_SHUFFLE_CHEST_MINIGAME]); - mOptions[RSK_SHUFFLE_CHEST_MINIGAME].Set(RO_CHEST_GAME_OFF); - // TODO: RandomizeAllSettings(true) when implementing the ability to randomize the options themselves. std::array dungeons = this->GetDungeons()->GetDungeonList(); @@ -2742,7 +2752,8 @@ void Context::FinalizeSettings(const std::set& excludedLocation &mOptions[RSK_KEYRINGS_FOREST_TEMPLE], &mOptions[RSK_KEYRINGS_FIRE_TEMPLE], &mOptions[RSK_KEYRINGS_WATER_TEMPLE], &mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE], &mOptions[RSK_KEYRINGS_SHADOW_TEMPLE], &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], - &mOptions[RSK_KEYRINGS_GTG], &mOptions[RSK_KEYRINGS_GANONS_CASTLE], + &mOptions[RSK_KEYRINGS_GTG], &mOptions[RSK_KEYRINGS_TREASURE_CHEST_GAME], + &mOptions[RSK_KEYRINGS_GANONS_CASTLE], }; if (mOptions[RSK_KEYRINGS]) { diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 7bdec17c1..a12966e3d 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -58,6 +58,7 @@ class StaticData { static void RegisterFreestandingLocations(); static void RegisterGrassLocations(); static void RegisterCrateLocations(); + static void RegisterTreasureChestGameLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 1a491064a..8197b9456 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -387,7 +387,9 @@ void func_80996B0C(DoorShutter* this, PlayState* play) { DoorShutter_SetupAction(this, func_80997004); this->dyna.actor.velocity.y = 0.0f; if (this->unk_16E != 0) { - Flags_SetSwitch(play, this->dyna.actor.params & 0x3F); + if (GameInteractor_Should(VB_DOOR_SHUTTER_SET_SWITCH_FLAG, true, this)) { + Flags_SetSwitch(play, this->dyna.actor.params & 0x3F); + } if (this->doorType != SHUTTER_BOSS) { gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]--; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_CHAIN_KEY_UNLOCK); diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index 9a3a8fb77..31002db83 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -140,7 +140,7 @@ void EnBox_Init(Actor* thisx, PlayState* play2) { if (play) {} // helps the compiler store play2 into s1 - if (Flags_GetTreasure(play, this->dyna.actor.params & 0x1F)) { + if (GameInteractor_Should(VB_CHEST_CONSIDER_CHEST_OPEN, Flags_GetTreasure(play, this->dyna.actor.params & 0x1F), this)) { this->alpha = 255; this->iceSmokeTimer = 100; EnBox_SetupAction(this, EnBox_Open); @@ -446,7 +446,9 @@ void EnBox_WaitOpen(EnBox* this, PlayState* play) { } } osSyncPrintf("Actor_Environment_Tbox_On() %d\n", this->dyna.actor.params & 0x1F); - Flags_SetTreasure(play, this->dyna.actor.params & 0x1F); + if (GameInteractor_Should(VB_CHEST_SET_TREASURE_FLAG, true, this)) { + Flags_SetTreasure(play, this->dyna.actor.params & 0x1F); + } } else { player = GET_PLAYER(play); Actor_WorldToActorCoords(&this->dyna.actor, &sp4C, &player->actor.world.pos); @@ -454,7 +456,7 @@ void EnBox_WaitOpen(EnBox* this, PlayState* play) { Player_IsFacingActor(&this->dyna.actor, 0x3000, play)) { Actor_OfferGetItemNearby(&this->dyna.actor, play, -(this->dyna.actor.params >> 5 & 0x7F)); } - if (Flags_GetTreasure(play, this->dyna.actor.params & 0x1F)) { + if (GameInteractor_Should(VB_CHEST_CONSIDER_CHEST_OPEN, Flags_GetTreasure(play, this->dyna.actor.params & 0x1F), this)) { EnBox_SetupAction(this, EnBox_Open); } } @@ -580,8 +582,8 @@ void EnBox_UpdateSizeAndTexture(EnBox* this, PlayState* play) { GetItemCategory getItemCategory; int isVanilla = csmc == CSMC_DISABLED || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)) || - (play->sceneNum == SCENE_TREASURE_BOX_SHOP && - this->dyna.actor.room != 6); // Exclude treasure game chests except for the final room + (!Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME) && play->sceneNum == SCENE_TREASURE_BOX_SHOP && + this->dyna.actor.room != 6); // exclude treasure game chests except for the final room when not shuffled if (!isVanilla) { GetItemEntry test = this->getItemEntry; diff --git a/soh/src/overlays/actors/ovl_En_Changer/z_en_changer.c b/soh/src/overlays/actors/ovl_En_Changer/z_en_changer.c index 5803633a1..7d32326f9 100644 --- a/soh/src/overlays/actors/ovl_En_Changer/z_en_changer.c +++ b/soh/src/overlays/actors/ovl_En_Changer/z_en_changer.c @@ -8,6 +8,8 @@ #include "vt.h" #include "overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h" #include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h" #define FLAGS 0 @@ -136,7 +138,7 @@ void EnChanger_Init(Actor* thisx, PlayState* play2) { this->rightChestGetItemId = GI_DOOR_KEY; rightChestItem = ITEM_ETC_KEY_SMALL_CHEST_GAME; - if (Rand_ZeroFloat(1.99f) < 1.0f) { + if (GameInteractor_Should(VB_EN_CHANGER_SWAP_CHESTS, Rand_ZeroFloat(1.99f) < 1.0f, this)) { rightChestParams = (sLoserGetItemIds[play->roomCtx.curRoom.num] << 5) | 0x4000; this->rightChestNum = new_var; this->rightChestGetItemId = sLoserGetItemIds[play->roomCtx.curRoom.num]; diff --git a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c index e1a0c3f90..23b5905ad 100644 --- a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c +++ b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c @@ -9,6 +9,8 @@ #include "objects/object_ts/object_ts.h" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h" #define FLAGS \ (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \ @@ -59,8 +61,10 @@ void EnTakaraMan_Init(Actor* thisx, PlayState* play) { osSyncPrintf("\n\n"); // "Bun! %x" (needs a better translation) osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ばぅん! ☆☆☆☆☆ %x\n" VT_RST, play->actorCtx.flags.chest); - play->actorCtx.flags.chest = 0; - gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = -1; + if (GameInteractor_Should(VB_TAKARA_MAN_RESET_CHESTS_AND_KEYS, true, this)) { + play->actorCtx.flags.chest = 0; + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = -1; + } SkelAnime_InitFlex(play, &this->skelAnime, &object_ts_Skel_004FE0, &object_ts_Anim_000498, this->jointTable, this->morphTable, 10); thisx->focus.pos = thisx->world.pos; @@ -151,7 +155,9 @@ void func_80B17934(EnTakaraMan* this, PlayState* play) { Rupees_ChangeBy(-10); this->unk_214 = 1; this->actor.parent = NULL; - Actor_OfferGetItem(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); + if (GameInteractor_Should(VB_TAKARA_MAN_OFFER_GET_ITEM, true, this)) { + Actor_OfferGetItem(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); + } this->actionFunc = func_80B17A6C; } else { Message_CloseTextbox(play); @@ -176,7 +182,9 @@ void func_80B17A6C(EnTakaraMan* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actionFunc = func_80B17AC4; } else { - Actor_OfferGetItem(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); + if (GameInteractor_Should(VB_TAKARA_MAN_OFFER_GET_ITEM, true, this)) { + Actor_OfferGetItem(&this->actor, play, GI_DOOR_KEY, 2000.0f, 1000.0f); + } } }