mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-09-01 08:22:58 -04:00
differentiate shop checks by room number
This commit is contained in:
@@ -56,6 +56,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 65
|
||||
Room: 1
|
||||
Item: 0x4B
|
||||
Name Lookup:
|
||||
- Sera Shop Slingshot
|
||||
@@ -1350,6 +1351,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 68
|
||||
Room: 3
|
||||
Item: 0x3E
|
||||
Name Lookup:
|
||||
- Kakariko Village Malo Mart Hawkeye
|
||||
@@ -1366,6 +1368,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 68
|
||||
Room: 3
|
||||
Item: 0x2C
|
||||
Name Lookup:
|
||||
- Kakariko Village Malo Mart Hylian Shield
|
||||
@@ -1382,6 +1385,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 68
|
||||
Room: 3
|
||||
Item: 0x61
|
||||
Name Lookup:
|
||||
- Kakariko Village Malo Mart Red Potion
|
||||
@@ -1398,6 +1402,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 68
|
||||
Room: 3
|
||||
Item: 0x2B
|
||||
Name Lookup:
|
||||
- Kakariko Village Malo Mart Wooden Shield
|
||||
@@ -1449,6 +1454,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 68
|
||||
Room: 1
|
||||
Item: 0x50
|
||||
Event Flag: 0x0908
|
||||
|
||||
@@ -2464,6 +2470,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 73
|
||||
Room: 4
|
||||
Item: 0x61
|
||||
Name Lookup:
|
||||
- Castle Town Goron Shop Red Potion
|
||||
@@ -2479,6 +2486,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 73
|
||||
Room: 4
|
||||
Item: 0x66
|
||||
Name Lookup:
|
||||
- Castle Town Goron Shop Lantern Oil
|
||||
@@ -2494,6 +2502,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 73
|
||||
Room: 4
|
||||
Item: 0x2C
|
||||
Name Lookup:
|
||||
- Castle Town Goron Shop Hylian Shield
|
||||
@@ -2509,6 +2518,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 53
|
||||
Room: 0
|
||||
Item: 0x10
|
||||
Name Lookup:
|
||||
- Castle Town Goron Shop Arrow Refill
|
||||
@@ -2523,6 +2533,7 @@
|
||||
Metadata:
|
||||
Shop:
|
||||
- Stage: 73
|
||||
Room: 0
|
||||
Item: 0x30
|
||||
Name Lookup:
|
||||
- Castle Town Malo Mart Magic Armor
|
||||
|
||||
@@ -764,7 +764,7 @@ HookAction hookPreShopSeqDecideYes(ModContext*, void* args, void*, void*) {
|
||||
int item_no = 0;
|
||||
|
||||
if (i_this->mFlow.getEventId(&item_no) == 1 && playerIsInRoomStage(3, "R_SP109")) {
|
||||
const u16 key = static_cast<u16>((getStageID() << 8) | (item_no & 0xFF));
|
||||
const u16 key = static_cast<u32>((getStageID() << 16) | (dStage_roomControl_c::getStayNo() << 8) | (item_no & 0xFF));
|
||||
if (randomizer_GetContext().mShopOverrides.contains(key)) {
|
||||
i_this->setSoldOutFlag();
|
||||
}
|
||||
|
||||
@@ -156,8 +156,8 @@ std::optional<std::string> RandomizerContext::WriteToFile() {
|
||||
const std::unordered_map<u16, u16> u16GoldenWolfOverrides(this->mGoldenWolfOverrides.begin(), this->mGoldenWolfOverrides.end());
|
||||
out["mGoldenWolfOverrides"] = u16GoldenWolfOverrides;
|
||||
|
||||
const std::unordered_map<u16, u16> u16ShopOverrides(this->mShopOverrides.begin(), this->mShopOverrides.end());
|
||||
out["mShopOverrides"] = u16ShopOverrides;
|
||||
const std::unordered_map<u32, u16> u32ShopOverrides(this->mShopOverrides.begin(), this->mShopOverrides.end());
|
||||
out["mShopOverrides"] = u32ShopOverrides;
|
||||
|
||||
out["mTwilitInsectOverrides"] = mTwilitInsectOverrides;
|
||||
|
||||
@@ -348,7 +348,7 @@ std::optional<std::string> RandomizerContext::LoadFromHash(const std::string& ha
|
||||
|
||||
// Shop Items
|
||||
for (const auto& shopNode : in["mShopOverrides"]) {
|
||||
u16 key = shopNode.first.as<u16>();
|
||||
u32 key = shopNode.first.as<u32>();
|
||||
u8 itemId = shopNode.second.as<u8>();
|
||||
this->mShopOverrides[key] = itemId;
|
||||
}
|
||||
@@ -1252,12 +1252,13 @@ RandomizerContext WriteSeedData(randomizer::logic::world::World* world) {
|
||||
}
|
||||
|
||||
// Shop Items
|
||||
// Keyed by u16 of the stage and original shop item
|
||||
// Keyed by u32 of 0xFF0000 (stage index), 0x00FF00 (room), and 0x0000FF (original shop item)
|
||||
if (location->HasCategories("Shop") && world->Setting("Shop Items") == "On") {
|
||||
for (const auto& shopNode : metaData["Shop"]) {
|
||||
u8 stage = shopNode["Stage"].as<u8>();
|
||||
u8 room = shopNode["Room"].as<u8>();
|
||||
u8 originalItem = shopNode["Item"].as<u8>();
|
||||
u16 key = (stage << 8) | originalItem;
|
||||
u32 key = (stage << 16) | (room << 8) | originalItem;
|
||||
randoData.mShopOverrides[key] = location->GetCurrentItem()->GetID();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
std::unordered_map<u8, u8> mBugRewardOverrides{};
|
||||
std::unordered_map<u16, u8> mSkyCharacterOverrides{};
|
||||
std::unordered_map<u16, u8> mGoldenWolfOverrides{};
|
||||
std::unordered_map<u16, u8> mShopOverrides{};
|
||||
std::unordered_map<u32, u8> mShopOverrides{};
|
||||
std::unordered_map<u16, u16> mTwilitInsectOverrides{}; // Just used in tracker for now
|
||||
std::unordered_map<std::string, itemLocationData> mItemLocations{};
|
||||
|
||||
|
||||
@@ -70,6 +70,31 @@ std::optional<DerivedKey> parse_derived(const char* name, std::string_view prefi
|
||||
return DerivedKey{stage_id, static_cast<u16>((stage_id << 8) | (n & 0xFF))};
|
||||
}
|
||||
|
||||
std::optional<u32> parse_shop_check(const char* name, std::string_view prefix) {
|
||||
if (std::strncmp(name, prefix.data(), prefix.size()) != 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const char* stage_begin = name + prefix.size();
|
||||
const char* stage_end = std::strchr(stage_begin, ':');
|
||||
if (stage_end == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const std::string stage{stage_begin, stage_end};
|
||||
const int stage_id = getStageID(stage.c_str());
|
||||
if (stage_id < 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const char* room_begin = stage_end + 1;
|
||||
const char* room_end = std::strchr(room_begin, ':');
|
||||
if (room_end == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const std::string roomStr{room_begin, room_end};
|
||||
u8 roomNo = std::atoi(roomStr.c_str());
|
||||
const int itemNo = std::atoi(room_end + 1);
|
||||
return static_cast<u32>((stage_id << 16) | (roomNo << 8) | (itemNo & 0xFF));
|
||||
}
|
||||
|
||||
std::optional<u16> parse_flag_check(const char* name, std::string_view prefix) {
|
||||
if (std::strncmp(name, prefix.data(), prefix.size()) != 0) {
|
||||
return std::nullopt;
|
||||
@@ -92,9 +117,9 @@ bool set_resolution(
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Map>
|
||||
template <typename Map, typename Key>
|
||||
bool lookup_override(
|
||||
const Map& map, u16 key, const ItemCheckInfo* info, ItemCheckResolution* outResult) {
|
||||
const Map& map, Key key, const ItemCheckInfo* info, ItemCheckResolution* outResult) {
|
||||
const auto it = map.find(key);
|
||||
if (it == map.end()) {
|
||||
return false;
|
||||
@@ -134,8 +159,8 @@ bool resolve_check(ModContext*, const ItemCheckInfo* info, ItemCheckResolution*
|
||||
const u16 key = static_cast<u16>((*stageId << 8) | 0x9F);
|
||||
return lookup_override(ctx.mFreestandingItemOverrides, key, info, outResult);
|
||||
}
|
||||
if (auto key = parse_derived(info->name, ITEM_CHECK_SHOP_PREFIX)) {
|
||||
return lookup_override(ctx.mShopOverrides, key->key, info, outResult);
|
||||
if (auto key = parse_shop_check(info->name, ITEM_CHECK_SHOP_PREFIX)) {
|
||||
return lookup_override(ctx.mShopOverrides, *key, info, outResult);
|
||||
}
|
||||
if (auto key = parse_derived(info->name, ITEM_CHECK_SKY_PREFIX)) {
|
||||
return lookup_override(ctx.mSkyCharacterOverrides, key->key, info, outResult);
|
||||
|
||||
@@ -531,15 +531,15 @@ std::string nameLookupOverride(const std::string& locationName) {
|
||||
{"Iza Raging Rapids Minigame", ITEM_CHECK_IZA_REWARD_2},
|
||||
{"Jovani 20 Poe Soul Reward", ITEM_CHECK_JOVANI_REWARD_1},
|
||||
{"Jovani 60 Poe Soul Reward", ITEM_CHECK_JOVANI_REWARD_2},
|
||||
{"Kakariko Village Malo Mart Hawkeye", "shop:R_SP109:62"},
|
||||
{"Kakariko Village Malo Mart Hylian Shield", "shop:R_SP109:44"},
|
||||
{"Kakariko Village Malo Mart Red Potion", "shop:R_SP109:97"},
|
||||
{"Kakariko Village Malo Mart Wooden Shield", "shop:R_SP109:43"},
|
||||
{"Castle Town Malo Mart Magic Armor", "shop:R_SP160:48"},
|
||||
{"Castle Town Goron Shop Arrow Refill", "shop:F_SP116:16"},
|
||||
{"Castle Town Goron Shop Hylian Shield", "shop:R_SP160:44"},
|
||||
{"Castle Town Goron Shop Lantern Oil", "shop:R_SP160:102"},
|
||||
{"Castle Town Goron Shop Red Potion", "shop:R_SP160:97"},
|
||||
{"Kakariko Village Malo Mart Hawkeye", "shop:R_SP109:3:62"},
|
||||
{"Kakariko Village Malo Mart Hylian Shield", "shop:R_SP109:3:44"},
|
||||
{"Kakariko Village Malo Mart Red Potion", "shop:R_SP109:3:97"},
|
||||
{"Kakariko Village Malo Mart Wooden Shield", "shop:R_SP109:3:43"},
|
||||
{"Castle Town Malo Mart Magic Armor", "shop:R_SP160:0:48"},
|
||||
{"Castle Town Goron Shop Arrow Refill", "shop:F_SP116:0:16"},
|
||||
{"Castle Town Goron Shop Hylian Shield", "shop:R_SP160:4:44"},
|
||||
{"Castle Town Goron Shop Lantern Oil", "shop:R_SP160:4:102"},
|
||||
{"Castle Town Goron Shop Red Potion", "shop:R_SP160:4:97"},
|
||||
{"Lakebed Temple Dungeon Reward", ITEM_CHECK_DUNGEON_REWARD_LAKEBED},
|
||||
{"Ordon Cat Rescue", ITEM_CHECK_SERA_REWARD},
|
||||
{"Ordon Shield", ITEM_CHECK_ORDON_SHIELD},
|
||||
@@ -549,7 +549,7 @@ std::string nameLookupOverride(const std::string& locationName) {
|
||||
{"Rutelas Blessing", ITEM_CHECK_ZORA_ARMOR},
|
||||
{"Sacred Grove Pedestal Master Sword", ITEM_CHECK_MASTER_SWORD},
|
||||
{"Sacred Grove Pedestal Shadow Crystal", ITEM_CHECK_SHADOW_CRYSTAL},
|
||||
{"Sera Shop Slingshot", "shop:R_SP01:75"},
|
||||
{"Sera Shop Slingshot", "shop:R_SP01:1:75"},
|
||||
{"Shad Dominion Rod", ITEM_CHECK_SHAD_DOMINION_ROD},
|
||||
{"Skybook From Impaz", ITEM_CHECK_SKYBOOK},
|
||||
{"Snowboard Racing Prize", ITEM_CHECK_SNOWBOARD_REWARD},
|
||||
@@ -662,8 +662,9 @@ int getLocationItem(randomizer::logic::location::Location* location) {
|
||||
}
|
||||
if (auto& shopNode = locationMeta["Shop"]) {
|
||||
u8 stage = shopNode[0]["Stage"].as<u8>();
|
||||
u8 room = shopNode[0]["Room"].as<u8>();
|
||||
u8 originalItem = shopNode[0]["Item"].as<u8>();
|
||||
u16 key = (stage << 8) | originalItem;
|
||||
u32 key = (stage << 16) | (room << 8) | originalItem;
|
||||
return context.mShopOverrides[key];
|
||||
}
|
||||
if (auto& twilitInsectNode = locationMeta["Twilit Insect"]) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#define ITEM_CHECK_FREESTANDING_PREFIX "freestanding:" /* <stage>:<bit> */
|
||||
#define ITEM_CHECK_GOLDEN_WOLF_PREFIX "golden_wolf:" /* <event_flag> */
|
||||
#define ITEM_CHECK_POE_PREFIX "poe:" /* <stage>:<switch> */
|
||||
#define ITEM_CHECK_SHOP_PREFIX "shop:" /* <stage>:<item> */
|
||||
#define ITEM_CHECK_SHOP_PREFIX "shop:" /* <stage>:<room>:<item> */
|
||||
#define ITEM_CHECK_SKY_PREFIX "sky:" /* <stage>:<room> */
|
||||
#define ITEM_CHECK_DUNGEON_REWARD_PREFIX "dungeon_reward:" /* <stage> */
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ std::string poe_check_name(uint8_t bitNo) {
|
||||
}
|
||||
|
||||
std::string shop_check_name(uint8_t itemNo) {
|
||||
return fmt::format("shop:{}:{}", current_stage_name(), itemNo);
|
||||
return fmt::format("shop:{}:{}:{}", current_stage_name(), dStage_roomControl_c::getStayNo(), itemNo);
|
||||
}
|
||||
|
||||
std::string bug_check_name(uint8_t insectId) {
|
||||
|
||||
Reference in New Issue
Block a user