diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 7db9f3c14..14da6a2fc 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -184,7 +184,6 @@ typedef struct { char ganonText[250]; u8 seedIcons[5]; u16 randomizerInf[2]; - u8 scrubsPurchased[35]; u8 temporaryWeapon; u16 adultTradeItems; } SaveContext; // size = 0x1428 diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index b78e3f630..e23f9633d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -1040,7 +1040,7 @@ int Fill() { std::vector remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); FastFill(remainingPool, GetAllEmptyLocations(), false); - // Add prices for scrubsanity + //Add prices for scrubsanity, this is unique to SoH because we write/read scrub prices to/from the spoilerfile. if (Scrubsanity.Is(SCRUBSANITY_AFFORDABLE)) { for (size_t i = 0; i < ScrubLocations.size(); i++) { Location(ScrubLocations[i])->SetScrubsanityPrice(10); diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 29d57292c..98ce64ef1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -673,12 +673,20 @@ static void WriteHints(int language) { static void WriteAllLocations(int language) { for (const uint32_t key : allLocations) { ItemLocation* location = Location(key); - std::string placedItemName = language == 2 ? location->GetPlacedItemName().french : location->GetPlacedItemName().english; + std::string placedItemName; + + switch (language) { + case 0: + default: + location->GetPlacedItemName().english; + case 2: + location->GetPlacedItemName().french; + } // Eventually check for other things here like fake name if (location->HasScrubsanityPrice() || location->HasShopsanityPrice()) { jsonData["locations"][location->GetName()]["item"] = placedItemName; - jsonData["locations"][location->GetName()]["price"] = location->GetPrice();; + jsonData["locations"][location->GetName()]["price"] = location->GetPrice(); } else { jsonData["locations"][location->GetName()] = placedItemName; } diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 23c0f45dc..2e73b3ed0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -104,7 +104,7 @@ Sprite* Randomizer::GetSeedTexture(uint8_t index) { Randomizer::~Randomizer() { this->randoSettings.clear(); this->itemLocations.clear(); - this->scrubPrices.clear(); + this->randomizerMerchantPrices.clear(); } std::unordered_map getItemIdToItemId = { @@ -1118,8 +1118,7 @@ void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent gSaveContext.itemLocations[index].check = SpoilerfileCheckNameToEnum[it.key()]; gSaveContext.itemLocations[index].get = SpoilerfileGetNameToEnum[itemit.value()]; } else if (itemit.key() == "price") { - scrubPrices[gSaveContext.itemLocations[index].check] = itemit.value(); - // TODO: Handle shop prices + randomizerMerchantPrices[gSaveContext.itemLocations[index].check] = itemit.value(); } } } else { @@ -1606,12 +1605,12 @@ std::string Randomizer::GetGanonHintText() const { ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respawnData) { struct ScrubIdentity scrubIdentity; - scrubIdentity.scrubId = -1; scrubIdentity.randomizerCheck = RC_UNKNOWN_CHECK; scrubIdentity.getItemId = GI_NONE; scrubIdentity.itemPrice = -1; scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) > 0; + // Based on z_en_dns.c 93-113 switch (actorParams) { case 0x00: scrubIdentity.getItemId = GI_NUTS_5_2; @@ -1653,20 +1652,20 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case SCENE_DDAN: // Dodongo's Cavern switch (actorParams) { case 0x00: - scrubIdentity.scrubId = 0x00; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT; scrubIdentity.randomizerCheck = RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT; break; case 0x01: - scrubIdentity.scrubId = 0x01; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS; scrubIdentity.randomizerCheck = RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS; break; case 0x03: case 0x06: - scrubIdentity.scrubId = 0x02; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT; scrubIdentity.randomizerCheck = RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT; break; case 0x04: - scrubIdentity.scrubId = 0x03; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY; scrubIdentity.randomizerCheck = RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY; break; } @@ -1674,7 +1673,7 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case SCENE_BDAN: // Jabu Jabu's Belly switch (actorParams) { case 0x00: - scrubIdentity.scrubId = 0x04; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB; scrubIdentity.randomizerCheck = RC_JABU_JABUS_BELLY_DEKU_SCRUB; break; } @@ -1682,20 +1681,20 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case SCENE_GANONTIKA: // Ganon's Castle switch (actorParams) { case 0x05: - scrubIdentity.scrubId = 0x05; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT; scrubIdentity.randomizerCheck = RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT; break; case 0x03: case 0x06: - scrubIdentity.scrubId = 0x06; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT; scrubIdentity.randomizerCheck = RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT; break; case 0x07: - scrubIdentity.scrubId = 0x07; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT; scrubIdentity.randomizerCheck = RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT; break; case 0x08: - scrubIdentity.scrubId = 0x08; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT; scrubIdentity.randomizerCheck = RC_GANONS_CASTLE_DEKU_SCRUB_LEFT; break; } @@ -1705,7 +1704,7 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xE6: // Hyrule Field Scrub Grotto switch (actorParams) { case 0x02: - scrubIdentity.scrubId = 0x09; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO; scrubIdentity.randomizerCheck = RC_HF_DEKU_SCRUB_GROTTO; scrubIdentity.isShuffled = true; break; @@ -1714,11 +1713,11 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xEB: // ZR Scrub Grotto switch (actorParams) { case 0x07: - scrubIdentity.scrubId = 0x0A; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR; scrubIdentity.randomizerCheck = RC_ZR_DEKU_SCRUB_GROTTO_REAR; break; case 0x08: - scrubIdentity.scrubId = 0x0B; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT; scrubIdentity.randomizerCheck = RC_ZR_DEKU_SCRUB_GROTTO_FRONT; break; } @@ -1726,11 +1725,11 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xEE: // Sacred Forest Meadow Scrub Grotto switch (actorParams) { case 0x07: - scrubIdentity.scrubId = 0x0C; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR; scrubIdentity.randomizerCheck = RC_SFM_DEKU_SCRUB_GROTTO_REAR; break; case 0x08: - scrubIdentity.scrubId = 0x0D; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT; scrubIdentity.randomizerCheck = RC_SFM_DEKU_SCRUB_GROTTO_FRONT; break; } @@ -1738,16 +1737,16 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xEF: // Lake Hylia Scrub Grotto switch (actorParams) { case 0x00: - scrubIdentity.scrubId = 0x0E; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT; scrubIdentity.randomizerCheck = RC_LH_DEKU_SCRUB_GROTTO_LEFT; break; case 0x05: - scrubIdentity.scrubId = 0x0F; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT; scrubIdentity.randomizerCheck = RC_LH_DEKU_SCRUB_GROTTO_RIGHT; break; case 0x03: case 0x06: - scrubIdentity.scrubId = 0x10; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER; scrubIdentity.randomizerCheck = RC_LH_DEKU_SCRUB_GROTTO_CENTER; break; } @@ -1755,11 +1754,11 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xF0: // Gerudo Valley Scrub Grotto switch (actorParams) { case 0x07: - scrubIdentity.scrubId = 0x11; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR; scrubIdentity.randomizerCheck = RC_GV_DEKU_SCRUB_GROTTO_REAR; break; case 0x08: - scrubIdentity.scrubId = 0x12; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT; scrubIdentity.randomizerCheck = RC_GV_DEKU_SCRUB_GROTTO_FRONT; break; } @@ -1768,11 +1767,11 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa switch (actorParams) { case 0x03: case 0x06: - scrubIdentity.scrubId = 0x13; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR; scrubIdentity.randomizerCheck = RC_LW_DEKU_SCRUB_GROTTO_REAR; break; case 0x0A: - scrubIdentity.scrubId = 0x14; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT; scrubIdentity.randomizerCheck = RC_LW_DEKU_SCRUB_GROTTO_FRONT; scrubIdentity.isShuffled = true; break; @@ -1781,16 +1780,16 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xF9: // Death Mountain Crater Scrub Grotto switch (actorParams) { case 0x00: - scrubIdentity.scrubId = 0x15; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT; scrubIdentity.randomizerCheck = RC_DMC_DEKU_SCRUB_GROTTO_LEFT; break; case 0x05: - scrubIdentity.scrubId = 0x16; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT; scrubIdentity.randomizerCheck = RC_DMC_DEKU_SCRUB_GROTTO_RIGHT; break; case 0x03: case 0x06: - scrubIdentity.scrubId = 0x17; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER; scrubIdentity.randomizerCheck = RC_DMC_DEKU_SCRUB_GROTTO_CENTER; break; } @@ -1798,16 +1797,16 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xFB: // Gerudo City Scrub Grotto switch (actorParams) { case 0x00: - scrubIdentity.scrubId = 0x18; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT; scrubIdentity.randomizerCheck = RC_GC_DEKU_SCRUB_GROTTO_LEFT; break; case 0x05: - scrubIdentity.scrubId = 0x19; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT; scrubIdentity.randomizerCheck = RC_GC_DEKU_SCRUB_GROTTO_RIGHT; break; case 0x03: case 0x06: - scrubIdentity.scrubId = 0x1A; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER; scrubIdentity.randomizerCheck = RC_GC_DEKU_SCRUB_GROTTO_CENTER; break; } @@ -1815,16 +1814,16 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xFC: // Lon Lon Ranch Scrub Grotto switch (actorParams) { case 0x00: - scrubIdentity.scrubId = 0x1B; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT; scrubIdentity.randomizerCheck = RC_LLR_DEKU_SCRUB_GROTTO_LEFT; break; case 0x05: - scrubIdentity.scrubId = 0x1C; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT; scrubIdentity.randomizerCheck = RC_LLR_DEKU_SCRUB_GROTTO_RIGHT; break; case 0x03: case 0x06: - scrubIdentity.scrubId = 0x1D; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER; scrubIdentity.randomizerCheck = RC_LLR_DEKU_SCRUB_GROTTO_CENTER; break; } @@ -1832,11 +1831,11 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case 0xFD: // Desert Colossus Scrub Grotto switch (actorParams) { case 0x07: - scrubIdentity.scrubId = 0x1E; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR; scrubIdentity.randomizerCheck = RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR; break; case 0x08: - scrubIdentity.scrubId = 0x1F; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT; scrubIdentity.randomizerCheck = RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT; break; } @@ -1846,15 +1845,15 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case SCENE_SPOT10: // Lost woods switch (actorParams) { case 0x00: - scrubIdentity.scrubId = 0x20; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT; scrubIdentity.randomizerCheck = RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT; break; case 0x01: - scrubIdentity.scrubId = 0x21; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT; scrubIdentity.randomizerCheck = RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT; break; case 0x09: - scrubIdentity.scrubId = 0x22; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE; scrubIdentity.randomizerCheck = RC_LW_DEKU_SCRUB_NEAR_BRIDGE; scrubIdentity.isShuffled = true; break; @@ -1863,15 +1862,15 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa case SCENE_SPOT17: // Death Mountain Crater switch (actorParams) { case 0x05: - scrubIdentity.scrubId = 0x23; + scrubIdentity.randomizerInf = RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB; scrubIdentity.randomizerCheck = RC_DMC_DEKU_SCRUB; break; } break; } - if (scrubPrices.find(scrubIdentity.randomizerCheck) != scrubPrices.end()) { - scrubIdentity.itemPrice = scrubPrices[scrubIdentity.randomizerCheck]; + if (randomizerMerchantPrices.find(scrubIdentity.randomizerCheck) != randomizerMerchantPrices.end()) { + scrubIdentity.itemPrice = randomizerMerchantPrices[scrubIdentity.randomizerCheck]; } return scrubIdentity; @@ -3398,9 +3397,13 @@ void DrawRandoEditor(bool& open) { // Shuffle Scrubs ImGui::Text(Settings::Scrubsanity.GetName().c_str()); InsertHelpHoverText( - "Off - Scrubs will not be shuffled.\n" + "Off - Scrubs will not be shuffled. The 3 Scrubs that give one-time items in the vanilla game (PoH, Deku Nut capacity, and Deku Stick capacity) will have random items.\n" "\n" "Affordable - Scrubs will be shuffled and their item will cost 10 rupees.\n" + "\n" + "Expensive - Scrubs will be shuffled and their item will cost the vanilla price.\n" + "\n" + "Random - Scrubs will be shuffled and their item will cost will be between 0-95 rupees.\n" ); SohImGui::EnhancementCombobox("gRandomizeShuffleScrubs", randoShuffleScrubs, 4, 0); PaddedSeparator(); @@ -4019,6 +4022,8 @@ void CreateGetItemMessages(std::vector messageEntries) { } } +// Currently these are generated at runtime, one for each price between 0-95. We're soon going to migrate this +// to being generated at save load, with only messages specific to each scrub. void CreateScrubMessages() { CustomMessageManager* customMessageManager = CustomMessageManager::Instance; customMessageManager->AddCustomMessageTable(Randomizer::scrubMessageTableID); diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 209ced506..c5df36e2c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -19,7 +19,7 @@ class Randomizer { std::string ganonHintText; std::string ganonText; std::unordered_map randoSettings; - std::unordered_map scrubPrices; + std::unordered_map randomizerMerchantPrices; s16 GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId); s16 GetItemFromActor(s16 actorId, s16 actorParams, s16 sceneNum, GetItemID ogItemId); void ParseRandomizerSettingsFile(const char* spoilerFileName); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 02adad1a5..0cbbb1eaf 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2,6 +2,7 @@ #include #include "z64item.h" +#include "randomizer_inf.h" // This should probably go in a less rando-specific location // but the best location will probably be in the modding engine @@ -1019,7 +1020,7 @@ typedef enum { } RandomizerSettingKey; typedef struct ScrubIdentity { - int32_t scrubId; + RandomizerInf randomizerInf; RandomizerCheck randomizerCheck; GetItemID getItemId; int32_t itemPrice; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index e5f41a5d3..c55e2d2ec 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -29,6 +29,43 @@ typedef enum { RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW, RAND_INF_COWS_MILKED_HF_COW_GROTTO_GOSSIP_STONE, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, + RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB, + RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, + RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, + RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT, + RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT, + RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO, + RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR, + RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT, + RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR, + RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT, + RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT, + RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT, + RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER, + RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR, + RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT, + RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR, + RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT, + RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT, + RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT, + RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER, + RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT, + RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT, + RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER, + RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT, + RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT, + RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER, + RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, + RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, + RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, + RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, + RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE, + RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB, + // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 092ad3ead..8d8e7cd77 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -761,10 +761,6 @@ void SaveManager::LoadBaseVersion1() { SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]); }); - - SaveManager::Instance->LoadArray("scrubsPurchased", ARRAY_COUNT(gSaveContext.scrubsPurchased), [](size_t i) { - SaveManager::Instance->LoadData("", gSaveContext.scrubsPurchased[i]); - }); } void SaveManager::LoadBaseVersion2() { @@ -922,10 +918,6 @@ void SaveManager::LoadBaseVersion2() { SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]); }); - - SaveManager::Instance->LoadArray("scrubsPurchased", ARRAY_COUNT(gSaveContext.scrubsPurchased), [](size_t i) { - SaveManager::Instance->LoadData("", gSaveContext.scrubsPurchased[i]); - }); } void SaveManager::SaveBase() { @@ -1079,10 +1071,6 @@ void SaveManager::SaveBase() { SaveManager::Instance->SaveArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) { SaveManager::Instance->SaveData("", gSaveContext.randomizerInf[i]); }); - - SaveManager::Instance->SaveArray("scrubsPurchased", ARRAY_COUNT(gSaveContext.scrubsPurchased), [](size_t i) { - SaveManager::Instance->SaveData("", gSaveContext.scrubsPurchased[i]); - }); } void SaveManager::SaveArray(const std::string& name, const size_t size, SaveArrayFunc func) { diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 270fd87a8..a5f35bcaa 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -709,11 +709,6 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { gSaveContext.randomizerInf[i] = 0; } - // Sets all scrubs to not purchased when generating a rando save. - for (u8 i = 0; i < NUM_SCRUBS; i++) { - gSaveContext.scrubsPurchased[i] = 0; - } - // Set Cutscene flags to skip them gSaveContext.eventChkInf[0xC] |= 0x10; // returned to tot with medallions gSaveContext.eventChkInf[0xC] |= 0x20; //sheik at tot pedestal diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index d2c42794e..5b6f097d0 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -181,6 +181,8 @@ void EnDns_Init(Actor* thisx, GlobalContext* globalCtx) { this->dnsItemEntry->purchaseableCheck = EnDns_RandomizerPurchaseableCheck; this->dnsItemEntry->setRupeesAndFlags = EnDns_RandomizerPurchase; this->dnsItemEntry->itemAmount = 1; + // Currently the textID is simply identified by the item price since that is the only thing + // unique to it, later on this will change to identifying by scrubIdentity.randomizerInf this->actor.textId = 0x9000 + this->dnsItemEntry->itemPrice; } } @@ -205,7 +207,7 @@ void EnDns_ChangeAnim(EnDns* this, u8 index) { /* Item give checking functions */ u32 EnDns_RandomizerPurchaseableCheck(EnDns* this) { - if (gSaveContext.rupees < this->dnsItemEntry->itemPrice || gSaveContext.scrubsPurchased[this->scrubIdentity.scrubId] == 1) { + if (gSaveContext.rupees < this->dnsItemEntry->itemPrice || Flags_GetRandomizerInf(this->scrubIdentity.randomizerInf)) { return 0; } return 4; @@ -309,7 +311,7 @@ u32 func_809EF9A4(EnDns* this) { /* Paying and flagging functions */ void EnDns_RandomizerPurchase(EnDns* this) { Rupees_ChangeBy(-this->dnsItemEntry->itemPrice); - gSaveContext.scrubsPurchased[this->scrubIdentity.scrubId] = 1; + Flags_SetRandomizerInf(this->scrubIdentity.randomizerInf); } void func_809EF9F8(EnDns* this) { @@ -514,6 +516,8 @@ void EnDns_Update(Actor* thisx, GlobalContext* globalCtx) { this->dustTimer++; this->actor.textId = D_809F040C[this->actor.params]; if (gSaveContext.n64ddFlag && this->scrubIdentity.isShuffled) { + // Currently the textID is simply identified by the item price since that is the only thing + // unique to it, later on this will change to identifying by scrubIdentity.randomizerInf this->actor.textId = 0x9000 + this->dnsItemEntry->itemPrice; } Actor_SetFocus(&this->actor, 60.0f); diff --git a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c index 6655b3aea..70a4c8e10 100644 --- a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c +++ b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c @@ -73,7 +73,7 @@ void EnShopnuts_Init(Actor* thisx, GlobalContext* globalCtx) { s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); ScrubIdentity scrubIdentity = Randomizer_IdentifyScrub(globalCtx->sceneNum, this->actor.params, respawnData); - if (scrubIdentity.isShuffled && gSaveContext.scrubsPurchased[scrubIdentity.scrubId] == 1) { + if (scrubIdentity.isShuffled && Flags_GetRandomizerInf(scrubIdentity.randomizerInf)) { Actor_Kill(&this->actor); } }