Check Tracker

- Adds support for merchants
- Fixes #7 for Bomchu Salesman
- Fixes #12 for Medigoron
This commit is contained in:
sonoftunk 2022-11-12 08:39:46 -05:00
parent 65b4125c7c
commit b4d9b4cad2
4 changed files with 62 additions and 53 deletions

View File

@ -83,7 +83,7 @@ void LocationTable_Init() {
//Haunted Wasteland //Haunted Wasteland
locationTable[WASTELAND_CHEST] = ItemLocation::Chest (RC_WASTELAND_CHEST, 0x5E, 0x00, "Wasteland Chest", WASTELAND_CHEST, PURPLE_RUPEE, {Category::cHauntedWasteland,}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[WASTELAND_CHEST] = ItemLocation::Chest (RC_WASTELAND_CHEST, 0x5E, 0x00, "Wasteland Chest", WASTELAND_CHEST, PURPLE_RUPEE, {Category::cHauntedWasteland,}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
locationTable[WASTELAND_BOMBCHU_SALESMAN] = ItemLocation::Base (RC_WASTELAND_BOMBCHU_SALESMAN, 0x5E, 0x03, "Wasteland Carpet Salesman", WASTELAND_BOMBCHU_SALESMAN, BOMBCHU_10, {Category::cHauntedWasteland, Category::cMerchant,}, SpoilerCollectionCheck::EventChkInf(0x34), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[WASTELAND_BOMBCHU_SALESMAN] = ItemLocation::Base (RC_WASTELAND_BOMBCHU_SALESMAN, 0x5E, 0x03, "Wasteland Carpet Salesman", WASTELAND_BOMBCHU_SALESMAN, BOMBCHU_10, {Category::cHauntedWasteland, Category::cMerchant,}, SpoilerCollectionCheck::Merchant(0x5E, 0x86), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
//Desert Colossus //Desert Colossus
locationTable[COLOSSUS_FREESTANDING_POH] = ItemLocation::Collectable(RC_COLOSSUS_FREESTANDING_POH, 0x5C, 0x0D, "Colossus Freestanding PoH", COLOSSUS_FREESTANDING_POH, PIECE_OF_HEART, {Category::cDesertColossus,}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); locationTable[COLOSSUS_FREESTANDING_POH] = ItemLocation::Collectable(RC_COLOSSUS_FREESTANDING_POH, 0x5C, 0x0D, "Colossus Freestanding PoH", COLOSSUS_FREESTANDING_POH, PIECE_OF_HEART, {Category::cDesertColossus,}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
@ -153,7 +153,7 @@ void LocationTable_Init() {
locationTable[GC_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_LEFT, 0xFB, 0x30, "GC Deku Scrub Grotto Left", GC_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cGoronCity, Category::cDekuScrub, Category::cGrotto}, SpoilerCollectionCheck::Scrub(0x25, 0x01), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); locationTable[GC_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_LEFT, 0xFB, 0x30, "GC Deku Scrub Grotto Left", GC_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cGoronCity, Category::cDekuScrub, Category::cGrotto}, SpoilerCollectionCheck::Scrub(0x25, 0x01), SpoilerCollectionCheckGroup::GROUP_GORON_CITY);
locationTable[GC_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, 0xFB, 0x37, "GC Deku Scrub Grotto Right", GC_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cGoronCity, Category::cDekuScrub, Category::cGrotto}, SpoilerCollectionCheck::Scrub(0x25, 0x06), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); locationTable[GC_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, 0xFB, 0x37, "GC Deku Scrub Grotto Right", GC_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cGoronCity, Category::cDekuScrub, Category::cGrotto}, SpoilerCollectionCheck::Scrub(0x25, 0x06), SpoilerCollectionCheckGroup::GROUP_GORON_CITY);
locationTable[GC_DEKU_SCRUB_GROTTO_CENTER] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_CENTER, 0xFB, 0x33, "GC Deku Scrub Grotto Center", GC_DEKU_SCRUB_GROTTO_CENTER, BUY_ARROWS_30, {Category::cGoronCity, Category::cDekuScrub, Category::cGrotto}, SpoilerCollectionCheck::Scrub(0x25, 0x04), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); locationTable[GC_DEKU_SCRUB_GROTTO_CENTER] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_CENTER, 0xFB, 0x33, "GC Deku Scrub Grotto Center", GC_DEKU_SCRUB_GROTTO_CENTER, BUY_ARROWS_30, {Category::cGoronCity, Category::cDekuScrub, Category::cGrotto}, SpoilerCollectionCheck::Scrub(0x25, 0x04), SpoilerCollectionCheckGroup::GROUP_GORON_CITY);
locationTable[GC_MEDIGORON] = ItemLocation::Base (RC_GC_MEDIGORON, 0x62, 0x51, "GC Medigoron", GC_MEDIGORON, GIANTS_KNIFE, {Category::cGoronCity, Category::cMerchant,}, SpoilerCollectionCheck::EventChkInf(0x35), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); locationTable[GC_MEDIGORON] = ItemLocation::Base (RC_GC_MEDIGORON, 0x62, 0x51, "GC Medigoron", GC_MEDIGORON, GIANTS_KNIFE, {Category::cGoronCity, Category::cMerchant,}, SpoilerCollectionCheck::Merchant(0x62, 0x87), SpoilerCollectionCheckGroup::GROUP_GORON_CITY);
//Death Mountain Crater //Death Mountain Crater
locationTable[DMC_UPPER_GROTTO_CHEST] = ItemLocation::Chest (RC_DMC_UPPER_GROTTO_CHEST, 0x3E, 0x1A, "DMC Upper Grotto Chest", DMC_UPPER_GROTTO_CHEST, BOMBS_20, {Category::cDeathMountainCrater, Category::cDeathMountain, Category::cGrotto}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); locationTable[DMC_UPPER_GROTTO_CHEST] = ItemLocation::Chest (RC_DMC_UPPER_GROTTO_CHEST, 0x3E, 0x1A, "DMC Upper Grotto Chest", DMC_UPPER_GROTTO_CHEST, BOMBS_20, {Category::cDeathMountainCrater, Category::cDeathMountain, Category::cGrotto}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN);

View File

@ -83,73 +83,77 @@ enum class ItemLocationType {
}; };
class SpoilerCollectionCheck { class SpoilerCollectionCheck {
public: public:
SpoilerCollectionCheckType type = SpoilerCollectionCheckType::SPOILER_CHK_NONE; SpoilerCollectionCheckType type = SpoilerCollectionCheckType::SPOILER_CHK_NONE;
uint8_t scene = 0; uint8_t scene = 0;
uint8_t flag = 0; uint8_t flag = 0;
SpoilerCollectionCheck() {} SpoilerCollectionCheck() {}
SpoilerCollectionCheck(SpoilerCollectionCheckType type_, uint8_t scene_, uint8_t flag_) : type(type_), scene(scene_), flag(flag_) {} SpoilerCollectionCheck(SpoilerCollectionCheckType type_, uint8_t scene_, uint8_t flag_) : type(type_), scene(scene_), flag(flag_) {}
static auto None() { static auto None() {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_NONE, 0x00, 0x00); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_NONE, 0x00, 0x00);
} }
static auto AlwaysCollected() { static auto AlwaysCollected() {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_ALWAYS_COLLECTED, 0x00, 0x00); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_ALWAYS_COLLECTED, 0x00, 0x00);
} }
static auto ItemGetInf(uint8_t slot) { static auto ItemGetInf(uint8_t slot) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF, 0x00, slot); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF, 0x00, slot);
} }
static auto EventChkInf(uint8_t flag) { static auto EventChkInf(uint8_t flag) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF, 0xFF, flag); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF, 0xFF, flag);
} }
static auto InfTable(uint8_t offset, uint8_t bit) { static auto InfTable(uint8_t offset, uint8_t bit) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_INF_TABLE, offset, bit); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_INF_TABLE, offset, bit);
} }
static auto Collectable(uint8_t scene, uint8_t flag) { static auto Collectable(uint8_t scene, uint8_t flag) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE, scene, flag); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE, scene, flag);
} }
static auto Chest(uint8_t scene, uint8_t flag) { static auto Chest(uint8_t scene, uint8_t flag) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_CHEST, scene, flag); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_CHEST, scene, flag);
} }
static auto Cow(uint8_t scene, uint8_t flag) { static auto Cow(uint8_t scene, uint8_t flag) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COW, scene, flag); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COW, scene, flag);
} }
static auto Fishing(uint8_t bit) { static auto Fishing(uint8_t bit) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MINIGAME, 0x00, bit); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MINIGAME, 0x00, bit);
} }
static auto Scrub(uint8_t scene, uint8_t bit) { static auto Scrub(uint8_t scene, uint8_t bit) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SCRUB, scene, bit); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SCRUB, scene, bit);
} }
static auto Biggoron(uint8_t mask) { static auto Biggoron(uint8_t mask) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_BIGGORON, 0x00, mask); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_BIGGORON, 0x00, mask);
} }
static auto GerudoToken() { static auto GerudoToken() {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, 0x00, 0x00); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, 0x00, 0x00);
} }
static auto BigPoePoints() { static auto BigPoePoints() {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_POE_POINTS, 0x00, 0x00); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_POE_POINTS, 0x00, 0x00);
} }
static auto ShopItem(uint8_t scene, uint8_t itemSlot) { static auto ShopItem(uint8_t scene, uint8_t itemSlot) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM, scene, itemSlot); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM, scene, itemSlot);
} }
static auto MagicBeans(uint8_t scene, uint8_t flag) { static auto MagicBeans(uint8_t scene, uint8_t flag) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MAGIC_BEANS, scene, flag); return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MAGIC_BEANS, scene, flag);
} }
static auto Merchant(int8_t scene, uint8_t flag) {
return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT, scene, flag);
}
}; };
class ItemLocation { class ItemLocation {
@ -591,6 +595,9 @@ static std::unordered_map<RandomizerCheck, RandomizerInf> randomizerFlagLookup =
{ RC_MARKET_BOMBCHU_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6 }, { RC_MARKET_BOMBCHU_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6 },
{ RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 }, { RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 },
{ RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 }, { RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 },
{ RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN },
{ RC_GC_MEDIGORON, RAND_INF_MERCHANTS_MEDIGORON },
}; };

View File

@ -24,6 +24,7 @@ typedef enum {
SPOILER_CHK_POE_POINTS, SPOILER_CHK_POE_POINTS,
SPOILER_CHK_SHOP_ITEM, SPOILER_CHK_SHOP_ITEM,
SPOILER_CHK_MAGIC_BEANS, SPOILER_CHK_MAGIC_BEANS,
SPOILER_CHK_MERCHANT,
} SpoilerCollectionCheckType; } SpoilerCollectionCheckType;
// Location groups for checks, used to group the checks by logical location // Location groups for checks, used to group the checks by logical location

View File

@ -663,6 +663,7 @@ bool HasItemBeenCollected(RandomizerCheckObject obj) {
return gSaveContext.sceneFlags[scene].chest & (1 << flag); return gSaveContext.sceneFlags[scene].chest & (1 << flag);
case SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE: case SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE:
return gSaveContext.sceneFlags[scene].collect & (1 << flag); return gSaveContext.sceneFlags[scene].collect & (1 << flag);
case SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT:
case SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM: case SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM:
case SpoilerCollectionCheckType::SPOILER_CHK_COW: case SpoilerCollectionCheckType::SPOILER_CHK_COW:
case SpoilerCollectionCheckType::SPOILER_CHK_SCRUB: case SpoilerCollectionCheckType::SPOILER_CHK_SCRUB: