diff --git a/src/d/actor/d_a_tag_statue_evt.cpp b/src/d/actor/d_a_tag_statue_evt.cpp index 806d8ee3b6..1890500a33 100644 --- a/src/d/actor/d_a_tag_statue_evt.cpp +++ b/src/d/actor/d_a_tag_statue_evt.cpp @@ -9,6 +9,8 @@ #include "d/actor/d_a_tag_statue_evt.h" #include "d/d_com_inf_game.h" #include "d/d_debug_viewer.h" +#include "dusk/randomizer/game/tools.h" +#include "dusk/randomizer/game/verify_item_functions.h" class daTagStatue_HIO_c : public mDoHIO_entry_c { public: @@ -352,15 +354,26 @@ int daTagStatue_c::demoProc() { } break; case DEMO_ACTION_AWARD_ITEM: - // If the player already has 5 Sky Characters, reward them with the completed - // Ancient Sky Book, otherwise, reward another character - if (getLetterCount() == 5) { - item = dItemNo_ANCIENT_DOCUMENT2_e; - /* Sky character - Sky character 6 */ - dComIfGs_onEventBit(dSv_event_flag_c::F_0796); +#if TARGET_PC + if (randomizer_IsActive()) { + u8 stageIdx = getStageID(); + u8 roomNo = dStage_roomControl_c::mStayNo; + u16 key = (stageIdx << 8) | roomNo; + item = verifyProgressiveItem(randomizer_GetContext().mSkyCharacterOverrides[key]); } else { - item = dItemNo_AIR_LETTER_e; +#endif + // If the player already has 5 Sky Characters, reward them with the completed + // Ancient Sky Book, otherwise, reward another character + if (getLetterCount() == 5) { + item = dItemNo_ANCIENT_DOCUMENT2_e; + /* Sky character - Sky character 6 */ + dComIfGs_onEventBit(dSv_event_flag_c::F_0796); + } else { + item = dItemNo_AIR_LETTER_e; + } +#if TARGET_PC } +#endif mItemId = fopAcM_createItemForTrBoxDemo(¤t.pos, item, -1, diff --git a/src/dusk/imgui/ImGuiMenuRandomizer.cpp b/src/dusk/imgui/ImGuiMenuRandomizer.cpp index 190b8ed5e6..a8fe5c6984 100644 --- a/src/dusk/imgui/ImGuiMenuRandomizer.cpp +++ b/src/dusk/imgui/ImGuiMenuRandomizer.cpp @@ -42,6 +42,7 @@ namespace dusk { // Put seed generation on a separate thread so it doesn't freeze the game std::thread randoGenerationThread(StartSeedGeneration); randoGenerationThread.detach(); + // StartSeedGeneration(); m_showRandoGeneration = true; } diff --git a/src/dusk/randomizer/game/randomizer_context.cpp b/src/dusk/randomizer/game/randomizer_context.cpp index c6f7ef8686..0fe39ef986 100644 --- a/src/dusk/randomizer/game/randomizer_context.cpp +++ b/src/dusk/randomizer/game/randomizer_context.cpp @@ -55,6 +55,9 @@ std::optional RandomizerContext::WriteToFile() { const std::unordered_map u16BugRewardOverrides(this->mBugRewardOverrides.begin(), this->mBugRewardOverrides.end()); out["mBugRewardOverrides"] = u16BugRewardOverrides; + const std::unordered_map u16SkyCharacterOverrides(this->mSkyCharacterOverrides.begin(), this->mSkyCharacterOverrides.end()); + out["mSkyCharacterOverrides"] = u16SkyCharacterOverrides; + out["mItemLocations"] = this->mItemLocations; out["mStartHour"] = static_cast(this->mStartHour); @@ -138,6 +141,13 @@ std::optional RandomizerContext::LoadFromHash(const std::string& ha this->mBugRewardOverrides[bugItemId] = itemId; } + // Sky Characters + for (const auto& skyCharacterNode : in["mSkyCharacterOverrides"]) { + u16 key = skyCharacterNode.first.as(); + u8 itemId = skyCharacterNode.second.as(); + this->mSkyCharacterOverrides[key] = itemId; + } + // Items we call by location name for (const auto& locationNode : in["mItemLocations"]) { const auto& locationName = locationNode.first.as(); @@ -245,6 +255,7 @@ void GenerateAndWriteSeed(std::string& generationStatusMsg) { } // Freestanding Overrides + // Keyed by the stage index and collectible flag of the item if (location->HasCategories("Freestanding Item")) { u8 stage = metaData[0]["Stage"].as(); u8 flag = metaData[0]["Flag"].as(); @@ -253,12 +264,23 @@ void GenerateAndWriteSeed(std::string& generationStatusMsg) { } // Bug Rewards + // Keyed by the item id of the original bug if (location->HasCategories("Bug Reward")) { u8 bugItemId = metaData[0]["Bug Item Id"].as(); u8 itemId = location->GetCurrentItem()->GetID(); randoData.mBugRewardOverrides[bugItemId] = itemId; } + // Sky Characters + // Keyed by u16 of 0xFF00 (stage index) and 0x00FF (roomNo) + if (location->HasCategories("Sky Book")) { + u8 stageIdx = metaData[0]["Stage"].as(); + u8 roomNo = metaData[0]["Room"].as(); + u8 itemId = location->GetCurrentItem()->GetID(); + u16 key = (stageIdx << 8) | roomNo; + randoData.mSkyCharacterOverrides[key] = itemId; + } + // Items that we lookup just by calling their location name if (location->HasCategories("Location Name Lookup")) { const auto& locationName = metaData.as(); diff --git a/src/dusk/randomizer/game/randomizer_context.hpp b/src/dusk/randomizer/game/randomizer_context.hpp index 83c1e36d38..5ecf1bcd36 100644 --- a/src/dusk/randomizer/game/randomizer_context.hpp +++ b/src/dusk/randomizer/game/randomizer_context.hpp @@ -28,6 +28,7 @@ public: std::unordered_map> mPoeOverrides{}; std::unordered_map> mFreestandingItemOverrides{}; std::unordered_map mBugRewardOverrides{}; + std::unordered_map mSkyCharacterOverrides{}; std::unordered_map mItemLocations{}; u8 mStartHour{0}; u8 mMapBits{}; diff --git a/src/dusk/randomizer/generator/data/locations.yaml b/src/dusk/randomizer/generator/data/locations.yaml index 92e0491dea..d608b97f86 100644 --- a/src/dusk/randomizer/generator/data/locations.yaml +++ b/src/dusk/randomizer/generator/data/locations.yaml @@ -577,7 +577,6 @@ - Tbox ID: 63 Stage: F_SP108 -# TODO - Name: Faron Woods Owl Statue Sky Character Original Item: Progressive Sky Book Categories: @@ -585,7 +584,8 @@ - Faron Woods - Sky Book Metadata: - - None + - Stage: 45 + Room: 8 - Name: Faron Woods Owl Statue Chest Original Item: Piece of Heart @@ -1009,7 +1009,6 @@ - Tbox ID: 4 Stage: F_SP121 -# TODO - Name: Kakariko Gorge Owl Statue Sky Character Original Item: Progressive Sky Book Categories: @@ -1017,7 +1016,8 @@ - Hyrule Field - Eldin Province - Sky Book Metadata: - - None + - Stage: 56 + Room: 3 # TODO - Name: Kakariko Gorge Owl Statue Boulder Rupee @@ -1627,7 +1627,6 @@ - Tbox ID: 3 Stage: F_SP121 -# TODO - Name: Bridge of Eldin Owl Statue Sky Character Original Item: Progressive Sky Book Categories: @@ -1635,7 +1634,8 @@ - Hyrule Field - Eldin Province - Sky Book Metadata: - - None + - Stage: 56 + Room: 0 # TODO - Name: Bridge of Eldin Boulder Rupee @@ -2146,7 +2146,6 @@ - Tbox ID: 11 Stage: F_SP122 -# TODO - Name: Hyrule Field Amphitheater Owl Statue Sky Character Original Item: Progressive Sky Book Categories: @@ -2154,7 +2153,8 @@ - Hyrule Field - Lanayru Province - Sky Book Metadata: - - None + - Stage: 57 + Room: 8 # TODO - Name: Hyrule Field Amphitheater Poe @@ -2681,7 +2681,6 @@ - Tbox ID: 15 Stage: F_SP121 -# TODO - Name: Lake Hylia Bridge Owl Statue Sky Character Original Item: Progressive Sky Book Categories: @@ -2689,7 +2688,8 @@ - Hyrule Field - Lanayru Province - Sky Book Metadata: - - None + - Stage: 56 + Room: 13 # TODO - Name: Lake Hylia Bridge Owl Statue Boulder Rupee @@ -4112,7 +4112,6 @@ - Tbox ID: 1 Stage: F_SP124 -# TODO - Name: Gerudo Desert Owl Statue Sky Character Original Item: Progressive Sky Book Categories: @@ -4120,7 +4119,8 @@ - Gerudo Desert - Sky Book Metadata: - - None + - Stage: 59 + Room: 0 # TODO - Name: Gerudo Desert Poe Above Cave of Ordeals