From c4f34624bad0dc4aa823bda9ba6691eab6e43209 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 28 Nov 2023 19:25:48 -0700 Subject: [PATCH] Flag tracker (#3447) * Hook into flagset hooks for processing check tracking. Has some manual workarounds (some breaks still need to be found). Remove areaChecks and looping functionality as redundant. * Additional vanilla handling. * Fix tracker not showing MQ checks in MQ non-rando. Fix tracker marking non-MQ variants of dungeon checks (e.g. map chest, etc) when collecting in MQ. * Set all areas to spoiled if not rando. * Revert attempt to spoil in randomizer based on MQ dungeon count as I don't know how that works at the moment. * Restore and update spoiling based on MQ dungeon settings (none, selection, or count of 12). Fix Anju As Adult check. * Remove Anchor-specific code :baguette: * Use `ClearAreaTotals()` in `Teardown()` instead of the duplicate code there. * Update to `ClearAreaChecksAndTotals()` with `vec.clear()` added. * Fix type spoiling again. Now spoils on 0 MQ dungeons, not rando, if the option is enabled in check tracker settings, selection, or set number of 12. Fix vanilla checks being marked collected in MQ dungeons. * Fix 100 GS check. * ACTUALLY fix 100 GS: change flag type to `RandomizerInf()` in `item_location.cpp`, add RC to RandoInf for it to the table. Also don't send GI for flag if father, falsely triggers ZR frogs minigame. * Fix gravedigging tour tracking. * Fix membership card check tracking. Change scene and flag values to any existing enums. Clarifying formatting for the checking loop vOrMQ conditions. * Fix Gravedigging Tour tracking. Simplify Always Win Gravedigging Tour and Fix Gravedigging Tour Glitch applications. Modified all necessary paths to use vanilla GDT PoH collection flag instead of randomizer variant. * Fix Kak Potion Shop being "seen" when entering as child. --- .../randomizer/3drando/item_location.cpp | 36 +-- .../Enhancements/randomizer/randomizer.cpp | 1 + .../randomizer/randomizer_check_objects.cpp | 4 +- .../randomizer/randomizer_check_tracker.cpp | 268 ++++++++++-------- .../randomizer/randomizer_check_tracker.h | 3 - soh/soh/OTRGlobals.cpp | 4 - soh/src/code/z_message_PAL.c | 2 +- soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c | 4 +- soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c | 54 ++-- 9 files changed, 195 insertions(+), 181 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp index 577de1c19..0ab29d869 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp @@ -24,11 +24,11 @@ void LocationTable_Init() { //Lost Woods locationTable[LW_NEAR_SHORTCUTS_GROTTO_CHEST] = ItemLocation::Chest (RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, 0x3E, 0x14, "LW Near Shortcuts Grotto Chest", LW_NEAR_SHORTCUTS_GROTTO_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_SKULL_KID] = ItemLocation::Base (RC_LW_SKULL_KID, 0x5B, "LW Skull Kid", LW_SKULL_KID, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(30), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[LW_SKULL_KID] = ItemLocation::Base (RC_LW_SKULL_KID, 0x5B, "LW Skull Kid", LW_SKULL_KID, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(22), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_TRADE_COJIRO] = ItemLocation::Base (RC_LW_TRADE_COJIRO, 0x5B, "LW Trade Cojiro", LW_TRADE_COJIRO, ODD_MUSHROOM, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_TRADE_ODD_POTION] = ItemLocation::Base (RC_LW_TRADE_ODD_POTION, 0x5B, "LW Trade Odd Potion", LW_TRADE_ODD_POTION, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_OCARINA_MEMORY_GAME] = ItemLocation::Base (RC_LW_OCARINA_MEMORY_GAME, 0x5B, "LW Ocarina Memory Game", LW_OCARINA_MEMORY_GAME, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(31), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_TARGET_IN_WOODS] = ItemLocation::Base (RC_LW_TARGET_IN_WOODS, 0x5B, "LW Target in Woods", LW_TARGET_IN_WOODS, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[LW_TRADE_ODD_POTION] = ItemLocation::Base (RC_LW_TRADE_ODD_POTION, 0x5B, "LW Trade Odd Potion", LW_TRADE_ODD_POTION, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(49), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[LW_OCARINA_MEMORY_GAME] = ItemLocation::Base (RC_LW_OCARINA_MEMORY_GAME, 0x5B, "LW Ocarina Memory Game", LW_OCARINA_MEMORY_GAME, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(23), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[LW_TARGET_IN_WOODS] = ItemLocation::Base (RC_LW_TARGET_IN_WOODS, 0x5B, "LW Target in Woods", LW_TARGET_IN_WOODS, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, 0x5B, "LW Deku Scrub Near Deku Theater Right",LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, 0x5B, "LW Deku Scrub Near Deku Theater Left", LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, BUY_DEKU_STICK_1, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_DEKU_SCRUB_NEAR_BRIDGE] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_BRIDGE, 0x5B, "LW Deku Scrub Near Bridge", LW_DEKU_SCRUB_NEAR_BRIDGE, PROGRESSIVE_STICK_UPGRADE, {Category::cDekuScrub, Category::cDekuScrubUpgrades}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); @@ -53,7 +53,7 @@ void LocationTable_Init() { //Lake Hylia locationTable[LH_CHILD_FISHING] = ItemLocation::Base (RC_LH_CHILD_FISHING, 0x49, "LH Child Fishing", LH_CHILD_FISHING, PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); locationTable[LH_ADULT_FISHING] = ItemLocation::Base (RC_LH_ADULT_FISHING, 0x49, "LH Adult Fishing", LH_ADULT_FISHING, PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_LAB_DIVE] = ItemLocation::Base (RC_LH_LAB_DIVE, 0x38, "LH Lab Dive", LH_LAB_DIVE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(24), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[LH_LAB_DIVE] = ItemLocation::Base (RC_LH_LAB_DIVE, 0x38, "LH Lab Dive", LH_LAB_DIVE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(16), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); locationTable[LH_TRADE_FROG] = ItemLocation::Base (RC_LH_TRADE_FROG, 0x38, "LH Lab Trade Eyeball Frog", LH_TRADE_FROG, EYEDROPS, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); locationTable[LH_UNDERWATER_ITEM] = ItemLocation::Base (RC_LH_UNDERWATER_ITEM, 0x57, "LH Underwater Item", LH_UNDERWATER_ITEM, RUTOS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x31), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); locationTable[LH_SUN] = ItemLocation::Base (RC_LH_SUN, 0x57, "LH Sun", LH_SUN, FIRE_ARROWS, {}, SpoilerCollectionCheck::Chest(0x57, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); @@ -73,7 +73,7 @@ void LocationTable_Init() { //Gerudo Fortress locationTable[GF_CHEST] = ItemLocation::Chest (RC_GF_CHEST, 0x5D, 0x00, "GF Chest", GF_CHEST, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[GF_HBA_1000_POINTS] = ItemLocation::Base (RC_GF_HBA_1000_POINTS, 0x5D, "GF HBA 1000 Points", GF_HBA_1000_POINTS, PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x08), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_HBA_1500_POINTS] = ItemLocation::Base (RC_GF_HBA_1500_POINTS, 0x5D, "GF HBA 1500 Points", GF_HBA_1500_POINTS, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(7), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[GF_HBA_1500_POINTS] = ItemLocation::Base (RC_GF_HBA_1500_POINTS, 0x5D, "GF HBA 1500 Points", GF_HBA_1500_POINTS, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[GF_GERUDO_MEMBERSHIP_CARD] = ItemLocation::Base (RC_GF_GERUDO_MEMBERSHIP_CARD, 0x0C, "GF Gerudo Membership Card", GF_GERUDO_MEMBERSHIP_CARD, GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::GerudoToken(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[GF_NORTH_F1_CARPENTER] = ItemLocation::Collectable(RC_GF_NORTH_F1_CARPENTER, 0x0C, 0x0C, "GF North F1 Carpenter", GF_NORTH_F1_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[GF_NORTH_F2_CARPENTER] = ItemLocation::Collectable(RC_GF_NORTH_F2_CARPENTER, 0x0C, 0x0A, "GF North F2 Carpenter", GF_NORTH_F2_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); @@ -90,12 +90,12 @@ void LocationTable_Init() { locationTable[COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = ItemLocation::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, 0xFD, "Colossus Deku Scrub Grotto Front", COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); //Market - locationTable[MARKET_TREASURE_CHEST_GAME_REWARD] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_REWARD, 0x10, "MK Treasure Chest Game Reward", MARKET_TREASURE_CHEST_GAME_REWARD, TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(19), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, 0x4B, "MK Bombchu Bowling First Prize", MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(25), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, 0x4B, "MK Bombchu Bowling Second Prize", MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(26), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[MARKET_TREASURE_CHEST_GAME_REWARD] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_REWARD, 0x10, "MK Treasure Chest Game Reward", MARKET_TREASURE_CHEST_GAME_REWARD, TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(27), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, 0x4B, "MK Bombchu Bowling First Prize", MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, 0x4B, "MK Bombchu Bowling Second Prize", MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[MARKET_BOMBCHU_BOWLING_BOMBCHUS] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, 0x4B, "MK Bombchu Bowling Bombchus", NONE, BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[MARKET_LOST_DOG] = ItemLocation::Base (RC_MARKET_LOST_DOG, 0x35, "MK Lost Dog", MARKET_LOST_DOG, PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_MARKET_SHOOTING_GALLERY_REWARD, 0x42, "MK Shooting Gallery", MARKET_SHOOTING_GALLERY_REWARD, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[MARKET_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_MARKET_SHOOTING_GALLERY_REWARD, 0x42, "MK Shooting Gallery", MARKET_SHOOTING_GALLERY_REWARD, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(13), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[MARKET_10_BIG_POES] = ItemLocation::Base (RC_MARKET_10_BIG_POES, 0x4D, "MK 10 Big Poes", MARKET_10_BIG_POES, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_1] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, 0x10, 0x01, "MK Chest Game First Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_1, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_2] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, 0x10, 0x03, "MK Chest Game Second Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_2, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); @@ -115,14 +115,14 @@ void LocationTable_Init() { locationTable[KAK_30_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_30_GOLD_SKULLTULA_REWARD, 0x50, "Kak 30 Gold Skulltula Reward", KAK_30_GOLD_SKULLTULA_REWARD, PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDC), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_40_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_40_GOLD_SKULLTULA_REWARD, 0x50, "Kak 40 Gold Skulltula Reward", KAK_40_GOLD_SKULLTULA_REWARD, BOMBCHU_10, {}, SpoilerCollectionCheck::EventChkInf(0xDD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_50_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_50_GOLD_SKULLTULA_REWARD, 0x50, "Kak 50 Gold Skulltula Reward", KAK_50_GOLD_SKULLTULA_REWARD, PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_100_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_100_GOLD_SKULLTULA_REWARD, 0x50, "Kak 100 Gold Skulltula Reward", KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xDF), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_MAN_ON_ROOF] = ItemLocation::Base (RC_KAK_MAN_ON_ROOF, 0x52, "Kak Man on Roof", KAK_MAN_ON_ROOF, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_100_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_100_GOLD_SKULLTULA_REWARD, 0x50, "Kak 100 Gold Skulltula Reward", KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_MAN_ON_ROOF] = ItemLocation::Base (RC_KAK_MAN_ON_ROOF, 0x52, "Kak Man on Roof", KAK_MAN_ON_ROOF, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_KAK_SHOOTING_GALLERY_REWARD, 0x42, "Kak Shooting Gallery Reward", KAK_SHOOTING_GALLERY_REWARD, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(56), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_GRANNYS_SHOP] = ItemLocation::Base (RC_KAK_GRANNYS_SHOP, 0x4E, "Kak Granny's Shop", KAK_GRANNYS_SHOP, BLUE_POTION_REFILL, {Category::cMerchant}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(36), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_ANJU_AS_CHILD] = ItemLocation::Base (RC_KAK_ANJU_AS_CHILD, 0x52, "Kak Anju as Child", KAK_ANJU_AS_CHILD, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_TRADE_POCKET_CUCCO] = ItemLocation::Base (RC_KAK_TRADE_POCKET_CUCCO, 0x52, "Kak Trade Pocket Cucco", KAK_TRADE_POCKET_CUCCO, COJIRO, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(38), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_ANJU_AS_CHILD] = ItemLocation::Base (RC_KAK_ANJU_AS_CHILD, 0x52, "Kak Anju as Child", KAK_ANJU_AS_CHILD, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(12), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_TRADE_POCKET_CUCCO] = ItemLocation::Base (RC_KAK_TRADE_POCKET_CUCCO, 0x52, "Kak Trade Pocket Cucco", KAK_TRADE_POCKET_CUCCO, COJIRO, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(46), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_IMPAS_HOUSE_FREESTANDING_POH] = ItemLocation::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, 0x37, 0x01, "Kak Impas House Freestanding PoH", KAK_IMPAS_HOUSE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_WINDMILL_FREESTANDING_POH] = ItemLocation::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, 0x48, 0x01, "Kak Windmill Freestanding PoH", KAK_WINDMILL_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); @@ -133,7 +133,7 @@ void LocationTable_Init() { locationTable[GRAVEYARD_HOOKSHOT_CHEST] = ItemLocation::Chest (RC_GRAVEYARD_HOOKSHOT_CHEST, 0x48, 0x00, "GY Hookshot Chest", GRAVEYARD_HOOKSHOT_CHEST, PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, 0x48, 0x07, "GY Dampe Race Freestanding PoH", GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[GRAVEYARD_FREESTANDING_POH] = ItemLocation::Collectable(RC_GRAVEYARD_FREESTANDING_POH, 0x53, 0x04, "GY Freestanding PoH", GRAVEYARD_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, 0x53, "GY Dampe Gravedigging Tour", GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, PIECE_OF_HEART, {}, SpoilerCollectionCheck::Gravedigger(0x53, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, 0x53, "GY Dampe Gravedigging Tour", GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, PIECE_OF_HEART, {}, SpoilerCollectionCheck::Gravedigger(0x53, 0x19), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); //Death Mountain locationTable[DMT_CHEST] = ItemLocation::Chest (RC_DMT_CHEST, 0x60, 0x01, "DMT Chest", DMT_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); @@ -191,7 +191,7 @@ void LocationTable_Init() { locationTable[ZF_BOTTOM_FREESTANDING_POH] = ItemLocation::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, 0x59, 0x14, "ZF Bottom Freestanding PoH", ZF_BOTTOM_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); //Lon Lon Ranch - locationTable[LLR_TALONS_CHICKENS] = ItemLocation::Base (RC_LLR_TALONS_CHICKENS, 0x4C, "LLR Talons Chickens", LLR_TALONS_CHICKENS, BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(10), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[LLR_TALONS_CHICKENS] = ItemLocation::Base (RC_LLR_TALONS_CHICKENS, 0x4C, "LLR Talons Chickens", LLR_TALONS_CHICKENS, BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(2), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); locationTable[LLR_FREESTANDING_POH] = ItemLocation::Collectable(RC_LLR_FREESTANDING_POH, 0x4C, 0x01, "LLR Freestanding PoH", LLR_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); locationTable[LLR_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, 0xFC, "LLR Deku Scrub Grotto Left", LLR_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); locationTable[LLR_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, 0xFC, "LLR Deku Scrub Grotto Right", LLR_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 8f88a7299..b4964caf0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2547,6 +2547,7 @@ std::map rcToRandomizerInf = { { RC_LH_CHILD_FISHING, RAND_INF_CHILD_FISHING }, { RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING }, { RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES }, + { RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD }, }; RandomizerCheckObject Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index d7f99edfb..d55110861 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -39,7 +39,7 @@ std::map rcObjects = { RC_OBJECT(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, GI_STICKS_1, "Deku Scrub Near Deku Theater Left", "LW Deku Scrub Near Deku Theater Left", false), RC_OBJECT(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, GI_STICK_UPGRADE_20, "Deku Scrub Near Bridge", "LW Deku Scrub Near Bridge", true), RC_OBJECT(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03,0xF5), GI_SEEDS_30, "Deku Scrub Grotto Rear", "LW Deku Scrub Grotto Rear", false), - RC_OBJECT(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A,0xF5), GI_NUT_UPGRADE_30, "Deku Scrub Grotto Front", "LW Deku Scrub Grotto Front", false), + RC_OBJECT(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A,0xF5), GI_NUT_UPGRADE_30, "Deku Scrub Grotto Front", "LW Deku Scrub Grotto Front", true), RC_OBJECT(RC_DEKU_THEATER_SKULL_MASK, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, GI_NONE, "Deku Theater Skull Mask", "Deku Theater Skull Mask", true), RC_OBJECT(RC_DEKU_THEATER_MASK_OF_TRUTH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, GI_NONE, "Deku Theater Mask of Truth", "Deku Theater Mask of Truth", true), RC_OBJECT(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_LOST_WOODS, ACTOR_EN_SI, SCENE_LOST_WOODS, 27905, GI_SKULL_TOKEN, "GS Bean Patch Near Bridge", "LW GS Bean Patch Near Bridge", true), @@ -238,7 +238,7 @@ std::map rcObjects = { RC_OBJECT(RC_GRAVEYARD_HOOKSHOT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 4352, GI_HOOKSHOT, "Hookshot Chest", "GY Hookshot Chest", true), RC_OBJECT(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1798, GI_HEART_PIECE, "Dampe Race Freestanding PoH", "GY Dampe Race Freestanding PoH", true), RC_OBJECT(RC_GRAVEYARD_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 1030, GI_HEART_PIECE, "Freestanding PoH", "GY Freestanding PoH", true), - RC_OBJECT(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 7942, GI_HEART_PIECE, "Dampe Gravedigging Tour", "GY Dampe Gravedigging Tour", true), + RC_OBJECT(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 6406, GI_HEART_PIECE, "Dampe Gravedigging Tour", "GY Dampe Gravedigging Tour", true), RC_OBJECT(RC_GRAVEYARD_GS_WALL, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_GRAVEYARD, ACTOR_EN_SI, SCENE_GRAVEYARD, 20608, GI_SKULL_TOKEN, "GS Wall", "Graveyard GS Wall", true), RC_OBJECT(RC_GRAVEYARD_GS_BEAN_PATCH, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_GRAVEYARD, ACTOR_EN_SI, SCENE_GRAVEYARD, 28673, GI_SKULL_TOKEN, "GS Bean Patch", "Graveyard GS Bean Patch", true), RC_OBJECT(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCVORMQ_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "Song from Composers Grave", "Song from Composers Grave", true), diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 6123c1a27..003c8c135 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -73,21 +73,12 @@ bool showLinksPocket; bool fortressFast; bool fortressNormal; -bool bypassRandoCheck = true; // persistent during gameplay bool initialized; bool doAreaScroll; bool previousShowHidden = false; bool hideShopRightChecks = true; -bool checkCollected = false; -int checkLoops = 0; -int checkCounter = 0; -u16 savedFrames = 0; -bool messageCloseCheck = false; -bool pendingSaleCheck = false; -bool transitionCheck = false; - std::map startingShopItem = { { SCENE_KOKIRI_SHOP, RC_KF_SHOP_ITEM_1 }, { SCENE_BAZAAR, RC_MARKET_BAZAAR_ITEM_1 }, { SCENE_POTION_SHOP_MARKET, RC_MARKET_POTION_SHOP_ITEM_1 }, @@ -118,12 +109,9 @@ bool showVOrMQ; s8 areaChecksGotten[32]; //| "Kokiri Forest (4/9)" bool optCollapseAll; // A bool that will collapse all checks once bool optExpandAll; // A bool that will expand all checks once -RandomizerCheck lastItemGetCheck = RC_UNKNOWN_CHECK; RandomizerCheck lastLocationChecked = RC_UNKNOWN_CHECK; RandomizerCheckArea previousArea = RCAREA_INVALID; RandomizerCheckArea currentArea = RCAREA_INVALID; -std::vector checkAreas; -std::vector itemsReceived; OSContPad* trackerButtonsPressed; void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags = 0); @@ -194,10 +182,6 @@ Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; -void SetLastItemGetRC(RandomizerCheck rc) { - lastItemGetCheck = rc; -} - void DefaultCheckData(RandomizerCheck rc) { gSaveContext.checkTrackerData[rc].status = RCSHOW_UNCHECKED; gSaveContext.checkTrackerData[rc].skipped = 0; @@ -253,9 +237,6 @@ void SetCheckCollected(RandomizerCheck rc) { } else { gSaveContext.checkTrackerData[rc].skipped = false; } - if (!checkAreas.empty()) { - checkAreas.erase(checkAreas.begin()); - } SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); doAreaScroll = true; @@ -360,32 +341,18 @@ bool vector_contains_scene(std::vector vec, const int16_t scene) { std::vector skipScenes = {SCENE_GANON_BOSS, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, SCENE_GANON_BOSS, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR}; -bool EvaluateCheck(RandomizerCheckObject rco) { - if (HasItemBeenCollected(rco.rc) && gSaveContext.checkTrackerData[rco.rc].status != RCSHOW_COLLECTED && - gSaveContext.checkTrackerData[rco.rc].status != RCSHOW_SAVED) { - SetCheckCollected(rco.rc); - return true; - } - return false; -} - -bool CheckByArea(RandomizerCheckArea area = RCAREA_INVALID) { - if (area == RCAREA_INVALID) { - area = checkAreas.front(); - } - if (area != RCAREA_INVALID) { - auto areaChecks = checksByArea.find(area)->second; - if (checkCounter >= areaChecks.size()) { - checkCounter = 0; - checkLoops++; - } - auto rco = areaChecks.at(checkCounter); - return EvaluateCheck(rco); +void ClearAreaChecksAndTotals() { + for (auto& [rcArea, vec] : checksByArea) { + vec.clear(); + areaChecksGotten[rcArea] = 0; } } void SetShopSeen(uint32_t sceneNum, bool prices) { RandomizerCheck start = startingShopItem.find(sceneNum)->second; + if (sceneNum == SCENE_POTION_SHOP_KAKARIKO && !LINK_IS_ADULT) { + return; + } if (GetCheckArea() == RCAREA_KAKARIKO_VILLAGE && sceneNum == SCENE_BAZAAR) { start = RC_KAK_BAZAAR_ITEM_1; } @@ -509,12 +476,6 @@ void CheckTrackerLoadGame(int32_t fileNum) { UpdateInventoryChecks(); } -void CheckTrackerDialogClosed() { - if (messageCloseCheck) { - messageCloseCheck = false; - } -} - void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) { if (gPlayState->sceneNum == SCENE_HAPPY_MASK_SHOP) { // Happy Mask Shop is not used in rando, so is not tracked return; @@ -536,10 +497,6 @@ void CheckTrackerTransition(uint32_t sceneNum) { if (!GameInteractor::IsSaveLoaded()) { return; } - gSaveContext; - if (transitionCheck) { - transitionCheck = false; - } doAreaScroll = true; previousArea = currentArea; currentArea = GetCheckArea(); @@ -560,28 +517,12 @@ void CheckTrackerFrame() { if (!GameInteractor::IsSaveLoaded()) { return; } - if (!checkAreas.empty() && !transitionCheck && !messageCloseCheck && !pendingSaleCheck) { - for (int i = 0; i < 10; i++) { - if (CheckByArea()) { - checkCounter = 0; - break; - } else { - checkCounter++; - } + // TODO: Move to OnAmmoChange hook once it gets added. + if (gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_COLLECTED && + gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_SAVED) { + if (BEANS_BOUGHT >= 10) { + SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN); } - if (checkLoops > 15) { - checkAreas.erase(checkAreas.begin()); - checkLoops = 0; - } - } - if (savedFrames > 0 && !pendingSaleCheck && !messageCloseCheck) { - savedFrames--; - } -} - -void CheckTrackerSaleEnd(GetItemEntry giEntry) { - if (pendingSaleCheck) { - pendingSaleCheck = false; } } @@ -593,7 +534,7 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) { // Vanilla special item checks if (!IS_RANDO) { if (giEntry.itemId == ITEM_SHIELD_DEKU) { - SetCheckCollected(RC_KF_SHOP_ITEM_3); + SetCheckCollected(RC_KF_SHOP_ITEM_1); return; }else if (giEntry.itemId == ITEM_KOKIRI_EMERALD) { SetCheckCollected(RC_QUEEN_GOHMA); @@ -622,16 +563,19 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) { } else if (giEntry.itemId == ITEM_MEDALLION_LIGHT) { SetCheckCollected(RC_GIFT_FROM_SAGES); return; - } else if (giEntry.itemId == ITEM_SONG_LULLABY) { - SetCheckCollected(RC_SONG_FROM_IMPA); - return; } else if (giEntry.itemId == ITEM_SONG_EPONA) { SetCheckCollected(RC_SONG_FROM_MALON); return; } else if (giEntry.itemId == ITEM_SONG_SARIA) { SetCheckCollected(RC_SONG_FROM_SARIA); return; - } else if (giEntry.itemId == ITEM_SONG_SUN) { + } else if (giEntry.itemId == ITEM_BEAN) { + SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN); + return; + } else if (giEntry.itemId == ITEM_BRACELET) { + SetCheckCollected(RC_GC_DARUNIAS_JOY); + return; + }/* else if (giEntry.itemId == ITEM_SONG_SUN) { SetCheckCollected(RC_SONG_FROM_ROYAL_FAMILYS_TOMB); return; } else if (giEntry.itemId == ITEM_SONG_TIME) { @@ -658,42 +602,127 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) { } else if (giEntry.itemId == ITEM_SONG_PRELUDE) { SetCheckCollected(RC_SHEIK_AT_TEMPLE); return; - } else if (giEntry.itemId == ITEM_BRACELET) { - SetCheckCollected(RC_GC_DARUNIAS_JOY); - return; - } else if (giEntry.itemId == ITEM_LETTER_ZELDA) { - SetCheckCollected(RC_HC_ZELDAS_LETTER); - return; - } else if (giEntry.itemId == ITEM_WEIRD_EGG) { - SetCheckCollected(RC_HC_MALON_EGG); - return; - } else if (giEntry.itemId == ITEM_BEAN) { - SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN); + }*/ + } +} + +void CheckTrackerSceneFlagSet(int16_t sceneNum, int16_t flagType, int32_t flag) { + if (flagType != FLAG_SCENE_TREASURE && flagType != FLAG_SCENE_COLLECTIBLE) { + return; + } + if (sceneNum == SCENE_GRAVEYARD && flag == 0x19 && flagType == FLAG_SCENE_COLLECTIBLE) { // Gravedigging tour special case + SetCheckCollected(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR); + return; + } + for (auto [rc, rcObj] : RandomizerCheckObjects::GetAllRCObjects()) { + if (!IsVisibleInCheckTracker(rcObj)) { + continue; + } + SpoilerCollectionCheckType checkMatchType = flagType == FLAG_SCENE_TREASURE ? SpoilerCollectionCheckType::SPOILER_CHK_CHEST : SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE; + SpoilerCollectionCheck scCheck = Location(rc)->GetCollectionCheck(); + if (scCheck.scene == sceneNum && scCheck.flag == flag && scCheck.type == checkMatchType) { + SetCheckCollected(rc); return; } } - auto checkArea = GetCheckArea(); - if (gSaveContext.pendingSale != ITEM_NONE) { - pendingSaleCheck = true; - checkAreas.push_back(checkArea); +} + +void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { + SpoilerCollectionCheckType checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_NONE; + switch (flagType) { + case FLAG_GS_TOKEN: + checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA; + break; + case FLAG_EVENT_CHECK_INF: + if ((flag == EVENTCHKINF_CARPENTERS_FREE(0) || flag == EVENTCHKINF_CARPENTERS_FREE(1) || + flag == EVENTCHKINF_CARPENTERS_FREE(2) || flag == EVENTCHKINF_CARPENTERS_FREE(3)) + && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) { + SetCheckCollected(RC_GF_GERUDO_MEMBERSHIP_CARD); + return; + } + checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF; + break; + case FLAG_INF_TABLE: + if (flag == INFTABLE_190) { + SetCheckCollected(RC_GF_HBA_1000_POINTS); + return; + } else if (flag == INFTABLE_11E) { + SetCheckCollected(RC_GC_ROLLING_GORON_AS_CHILD); + return; + } else if (flag == INFTABLE_GORON_CITY_DOORS_UNLOCKED) { + SetCheckCollected(RC_GC_ROLLING_GORON_AS_ADULT); + return; + } else if (flag == INFTABLE_139) { + SetCheckCollected(RC_ZD_KING_ZORA_THAWED); + return; + } else if (flag == INFTABLE_191) { + SetCheckCollected(RC_MARKET_LOST_DOG); + return; + } + if (!IS_RANDO) { + if (flag == INFTABLE_192) { + SetCheckCollected(RC_LW_DEKU_SCRUB_NEAR_BRIDGE); + return; + } else if (flag == INFTABLE_193) { + SetCheckCollected(RC_LW_DEKU_SCRUB_GROTTO_FRONT); + return; + } + } + break; + case FLAG_ITEM_GET_INF: + if (!IS_RANDO) { + if (flag == ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE) { + SetCheckCollected(RC_DEKU_THEATER_SKULL_MASK); + return; + } else if (flag == ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE) { + SetCheckCollected(RC_DEKU_THEATER_MASK_OF_TRUTH); + return; + } else if (flag == ITEMGETINF_0B) { + SetCheckCollected(RC_HF_DEKU_SCRUB_GROTTO); + return; + } + } + checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF; + break; + case FLAG_RANDOMIZER_INF: + checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF; + break; + } + if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_NONE) { return; } - if (scene == SCENE_DESERT_COLOSSUS && (gSaveContext.entranceIndex == 485 || gSaveContext.entranceIndex == 489)) { - checkAreas.push_back(RCAREA_SPIRIT_TEMPLE); - return; - } - if (GET_PLAYER(gPlayState) == nullptr) { - transitionCheck = true; - return; - } - if (gPlayState->msgCtx.msgMode != MSGMODE_NONE) { - checkAreas.push_back(checkArea); - messageCloseCheck = true; - return; - } - if (IS_RANDO || (!IS_RANDO && giEntry.getItemCategory != ITEM_CATEGORY_JUNK)) { - checkAreas.push_back(checkArea); - checkCollected = true; + for (auto [rc, rcObj] : RandomizerCheckObjects::GetAllRCObjects()) { + if ((!IS_RANDO && ((rcObj.vOrMQ == RCVORMQ_MQ && !IS_MASTER_QUEST) || + (rcObj.vOrMQ == RCVORMQ_VANILLA && IS_MASTER_QUEST))) || + (IS_RANDO && ((OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) && + rcObj.vOrMQ == RCVORMQ_VANILLA) || + !OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) && + rcObj.vOrMQ == RCVORMQ_MQ))) { + continue; + } + SpoilerCollectionCheck scCheck = Location(rc)->GetCollectionCheck(); + SpoilerCollectionCheckType scCheckType = scCheck.type; + if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF && + (scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT || + scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM || + scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_COW || + scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SCRUB || + scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD || + scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF)) { + if (flag == OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)) { + SetCheckCollected(rc); + return; + } + continue; + } + int16_t checkFlag = scCheck.flag; + if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA) { + checkFlag = rcObj.actorParams; + } + if (checkFlag == flag && scCheck.type == checkMatchType) { + SetCheckCollected(rc); + return; + } } } @@ -711,7 +740,7 @@ void InitTrackerData(bool isDebug) { void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) { SaveManager::Instance->SaveArray("checks", ARRAY_COUNT(saveContext->checkTrackerData), [&](size_t i) { if (saveContext->checkTrackerData[i].status == RCSHOW_COLLECTED) { - if (gameSave || savedFrames > 0) { + if (gameSave) { gSaveContext.checkTrackerData[i].status = saveContext->checkTrackerData[i].status = RCSHOW_SAVED; UpdateAllOrdering(); UpdateInventoryChecks(); @@ -730,9 +759,6 @@ void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) { void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) { SaveTrackerData(saveContext, sectionID, fullSave); - if (fullSave) { - savedFrames = 40; - } } void LoadFile() { @@ -748,14 +774,9 @@ void LoadFile() { void Teardown() { initialized = false; - for (auto& [rcArea, vec] : checksByArea) { - vec.clear(); - areaChecksGotten[rcArea] = 0; - } + ClearAreaChecksAndTotals(); checksByArea.clear(); areasSpoiled = 0; - checkCollected = false; - checkLoops = 0; lastLocationChecked = RC_UNKNOWN_CHECK; } @@ -925,7 +946,11 @@ void CheckTrackerWindow::DrawElement() { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f, extraColor.b / 255.0f, extraColor.a / 255.0f)); - isThisAreaSpoiled = areasSpoiled & areaMask || CVarGetInteger("gCheckTrackerOptionMQSpoilers", 0); + isThisAreaSpoiled = areasSpoiled & areaMask || CVarGetInteger("gCheckTrackerOptionMQSpoilers", 0) || !IS_RANDO || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_RANDOM_MQ_DUNGEONS) == RO_MQ_DUNGEONS_NONE || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_RANDOM_MQ_DUNGEONS) == RO_MQ_DUNGEONS_SELECTION || + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_RANDOM_MQ_DUNGEONS) == RO_MQ_DUNGEONS_SET_NUMBER && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12); if (isThisAreaSpoiled) { if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) { @@ -1151,8 +1176,8 @@ bool IsVisibleInCheckTracker(RandomizerCheckObject rcObj) { } else if (rcObj.vanillaCompletion) { return (rcObj.vOrMQ == RCVORMQ_BOTH || - rcObj.vOrMQ == RCVORMQ_MQ && OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) || - rcObj.vOrMQ == RCVORMQ_VANILLA && !OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) || + (rcObj.vOrMQ == RCVORMQ_MQ && IS_MASTER_QUEST) || + (rcObj.vOrMQ == RCVORMQ_VANILLA && !IS_MASTER_QUEST) || rcObj.rc == RC_GIFT_FROM_SAGES) && rcObj.rc != RC_LINKS_POCKET; } return false; @@ -1541,10 +1566,11 @@ void CheckTrackerWindow::InitElement() { Teardown(); }); GameInteractor::Instance->RegisterGameHook(CheckTrackerItemReceive); - GameInteractor::Instance->RegisterGameHook(CheckTrackerSaleEnd); GameInteractor::Instance->RegisterGameHook(CheckTrackerFrame); GameInteractor::Instance->RegisterGameHook(CheckTrackerTransition); GameInteractor::Instance->RegisterGameHook(CheckTrackerShopSlotChange); + GameInteractor::Instance->RegisterGameHook(CheckTrackerSceneFlagSet); + GameInteractor::Instance->RegisterGameHook(CheckTrackerFlagSet); LocationTable_Init(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index b2193f696..a8928cca3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -48,10 +48,7 @@ void Teardown(); void UpdateAllOrdering(); bool IsVisibleInCheckTracker(RandomizerCheckObject rcObj); void InitTrackerData(bool isDebug); -void SetLastItemGetRC(RandomizerCheck rc); RandomizerCheckArea GetCheckArea(); -void CheckTrackerDialogClosed(); -void ToggleShopRightChecks(); void UpdateCheck(uint32_t, RandomizerCheckTrackerData); } // namespace CheckTracker diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index eece2c361..7587450b5 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2573,7 +2573,3 @@ extern "C" void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex) { extern "C" void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement) { gfx_register_blended_texture(name, mask, replacement); } - -extern "C" void CheckTracker_OnMessageClose() { - CheckTracker::CheckTrackerDialogClosed(); -} diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index da0f5f55f..7bb3803fc 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -3384,7 +3384,7 @@ void Message_Update(PlayState* play) { } sLastPlayedSong = 0xFF; osSyncPrintf("OCARINA_MODE=%d chk_ocarina_no=%d\n", play->msgCtx.ocarinaMode, msgCtx->unk_E3F2); - CheckTracker_OnMessageClose(); + // TODO: OnMessageClose hook break; case MSGMODE_PAUSED: break; diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index 81242aa77..908a1af96 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -313,7 +313,9 @@ void EnSth_GiveReward(EnSth* this, PlayState* play) { this->actor.parent = NULL; EnSth_SetupAction(this, EnSth_RewardObtainedTalk); gSaveContext.eventChkInf[EVENTCHKINF_SKULLTULA_REWARD_INDEX] |= this->eventFlag; - GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SKULLTULA_REWARD_INDEX << 4) + sEventFlagsShift[this->actor.params]); + if (this->eventFlag != 0) { + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SKULLTULA_REWARD_INDEX << 4) + sEventFlagsShift[this->actor.params]); + } } else { EnSth_GivePlayerItem(this, play); } diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 738db714d..55fbed824 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -408,7 +408,7 @@ s32 EnTk_ChooseReward(EnTk* this) { f32 luck; s32 reward; - if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, 0x1F) && this->heartPieceSpawned == 0) { + if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) { return 3; } @@ -624,10 +624,8 @@ void EnTk_Dig(EnTk* this, PlayState* play) { this->currentReward = EnTk_ChooseReward(this); - // merging in dampe tour fix seems messy, so i'm just wrapping this whole thing - // in an n64dd check for now - if (IS_RANDO || CVarGetInteger("gDampeWin", 0)) { - if (this->currentReward == 3) { + if (this->currentReward == 3) { + if (IS_RANDO || CVarGetInteger("gDampeWin", 0)) { /* * Upgrade the purple rupee reward to the heart piece if this * is the first grand prize dig. @@ -635,37 +633,31 @@ void EnTk_Dig(EnTk* this, PlayState* play) { if (!Flags_GetItemGetInf(ITEMGETINF_1C) && !(IS_RANDO || CVarGetInteger("gDampeWin", 0))) { Flags_SetItemGetInf(ITEMGETINF_1C); this->currentReward = 4; - } else if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, 0x1F) && this->heartPieceSpawned == 0) { + } else if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) { this->currentReward = 4; } } - - if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && this->currentReward == 4) { - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, rewardPos.x, rewardPos.y, rewardPos.z, 0, - 0, 0, 0x1F06, true); - this->heartPieceSpawned = 1; - } else { - Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]); + /* + * Upgrade the purple rupee reward to the heart piece if this + * is the first grand prize dig. + */ + // If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true. + // Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true. + // If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag. + if (!heartPieceSpawned && + (!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) || + CVarGetInteger("gGravediggingTourFix", 0) && + !Flags_GetCollectible(play, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) { + this->currentReward = 4; + gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE; + heartPieceSpawned = true; } + } + + if (IS_RANDO && this->currentReward == 4) { + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, rewardPos.x, rewardPos.y, rewardPos.z, 0, 0, 0, 0x1906, true); + this->heartPieceSpawned = 1; } else { - if (this->currentReward == 3) { - /* - * Upgrade the purple rupee reward to the heart piece if this - * is the first grand prize dig. - */ - // If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true. - // Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true. - // If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag. - if (!heartPieceSpawned && - (!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) || - CVarGetInteger("gGravediggingTourFix", 0) && - !Flags_GetCollectible(play, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) { - this->currentReward = 4; - gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE; - heartPieceSpawned = true; - } - } - EnItem00* reward = Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]); if (this->currentReward == 4) { reward->collectibleFlag = COLLECTFLAG_GRAVEDIGGING_HEART_PIECE;