diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index 59591fc078..015a07a93f 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -10575,9 +10575,16 @@ void daAlink_c::decideDoStatus() { (actor_name == fpcNm_TAG_KMSG_e && static_cast(field_0x27f4)->getType() == 3)) { - if (!checkEquipAnime() && checkMasterSwordEquip()) { + // Don't check vanilla condition in randomizer + if (!checkEquipAnime() && checkMasterSwordEquip() IF_DUSK(&& !randomizer_IsActive())) { setDoStatus(BUTTON_STATUS_STRIKE); } +#if TARGET_PC + // Separate check for striking sword into the pedestal for randomizer + if (!checkEquipAnime() && randomizer_IsActive() && randomizer_checkTempleOfTimeRequirement()) { + setDoStatus(BUTTON_STATUS_STRIKE); + } +#endif } } else if (mTargetedActor != NULL && checkGoatCatchActor(mTargetedActor) && mAttention->getActionBtnB() != NULL && diff --git a/src/d/d_save.cpp b/src/d/d_save.cpp index 4a5605a7f4..533cb847ac 100644 --- a/src/d/d_save.cpp +++ b/src/d/d_save.cpp @@ -1778,6 +1778,12 @@ u32 dSv_info_c::createZone(int i_roomNo) { } void dSv_info_c::onSwitch(int i_no, int i_roomNo) { +#if TARGET_PC + // Set custom flag for temple of time pedestal strike + if (getStageID() == Sacred_Grove && i_no == 0xEE) { + onSwitch(0x63, i_roomNo); + } +#endif JUT_ASSERT(4210, (0 <= i_no && i_no < (MEMORY_SWITCH+ DAN_SWITCH+ ZONE_SWITCH+ ONEZONE_SWITCH)) || i_no == -1 || i_no == 255); if (i_no == -1 || i_no == 255) { diff --git a/src/dusk/randomizer/game/randomizer_context.cpp b/src/dusk/randomizer/game/randomizer_context.cpp index c0ec0c2577..217558064c 100644 --- a/src/dusk/randomizer/game/randomizer_context.cpp +++ b/src/dusk/randomizer/game/randomizer_context.cpp @@ -267,7 +267,7 @@ int RandomizerContext::SettingToEnum(const std::string& settingName) { {"Palace of Twilight Requirements", PALACE_OF_TWILIGHT_REQUIREMENTS}, {"Skip Minor Cutscenes", SKIP_MINOR_CUTSCENES}, {"Skip Major Cutscenes", SKIP_MAJOR_CUTSCENES}, - + {"Temple of Time Sword Requirement", TEMPLE_OF_TIME_SWORD_REQUIREMENT}, }; if (nameToEnum.contains(settingName)) { @@ -289,6 +289,10 @@ int RandomizerContext::OptionToEnum(const std::string& optionName) { {"Poe Souls", POE_SOULS}, {"Hearts", HEARTS}, {"Dungeons", DUNGEONS}, + {"Wooden Sword", WOODEN_SWORD}, + {"Ordon Sword", ORDON_SWORD}, + {"Master Sword", MASTER_SWORD}, + {"Light Sword", LIGHT_SWORD}, }; if (nameToEnum.contains(optionName)) { @@ -710,6 +714,44 @@ int randomizer_getItemAtLocation(const std::string& locationName) { return randomizer_GetContext().mItemLocations[locationName]; } +bool randomizer_checkTempleOfTimeRequirement() { + auto swordRequirement = randomizer_GetContext().mSettings[RandomizerContext::TEMPLE_OF_TIME_SWORD_REQUIREMENT]; + u8 roomNo = dComIfGp_getStartStageRoomNo(); + + // Don't strike the pedestal again if we've already set the flag for striking it + if (roomNo == 1 && dComIfGs_isSwitch(0x63, roomNo)) { + return false; + } + + // Make sure we have a sword in Link's hands. + auto equippedSword = dComIfGs_getSelectEquipSword(); + if (equippedSword != 0xFF) { + // Fallthrough is intentional to check each potential sword requirement below the current equipped sword + switch (equippedSword) { + case dItemNo_LIGHT_SWORD_e: + if (swordRequirement == RandomizerContext::LIGHT_SWORD) { + return true; + } + case dItemNo_MASTER_SWORD_e: + if (swordRequirement == RandomizerContext::MASTER_SWORD) { + return true; + } + case dItemNo_SWORD_e: + if (swordRequirement == RandomizerContext::ORDON_SWORD) { + return true; + } + case dItemNo_WOOD_STICK_e: + if (swordRequirement == RandomizerContext::WOODEN_SWORD) { + return true; + } + default: + return false; + } + } + + return false; +} + u32 getActorPatchesCurrentStageKey(u8 roomNo) { u32 actorPatchesStageKey{}; actorPatchesStageKey |= getStageID(dComIfGp_getStartStageName()) << 16; diff --git a/src/dusk/randomizer/game/randomizer_context.hpp b/src/dusk/randomizer/game/randomizer_context.hpp index b1e9765492..297d398c0d 100644 --- a/src/dusk/randomizer/game/randomizer_context.hpp +++ b/src/dusk/randomizer/game/randomizer_context.hpp @@ -75,6 +75,7 @@ public: HYRULE_BIG_KEY_HEARTS, HYRULE_BIG_KEY_DUNGEONS, PALACE_OF_TWILIGHT_REQUIREMENTS, + TEMPLE_OF_TIME_SWORD_REQUIREMENT, SKIP_MINOR_CUTSCENES, SKIP_MAJOR_CUTSCENES, }; @@ -90,6 +91,10 @@ public: POE_SOULS, HEARTS, DUNGEONS, + WOODEN_SWORD, + ORDON_SWORD, + MASTER_SWORD, + LIGHT_SWORD, }; static int SettingToEnum(const std::string& settingName); @@ -164,6 +169,7 @@ bool randomizer_IsActive(); int randomizer_getItemAtLocation(const std::string& locationName); +bool randomizer_checkTempleOfTimeRequirement(); /** * Helper function to convert raw bytes of a container to a hex string */ diff --git a/src/dusk/randomizer/generator/data/object_patches.yaml b/src/dusk/randomizer/generator/data/object_patches.yaml index 20ab707e31..eff5106152 100644 --- a/src/dusk/randomizer/generator/data/object_patches.yaml +++ b/src/dusk/randomizer/generator/data/object_patches.yaml @@ -1508,6 +1508,68 @@ F_SP117: layers: - 2 + # Door to the past + - action: patch + name: smgdoor + parameters: 0x064010FF + position: + x: 0.0 + y: 1725.0 + z: 6900.0 + angle: + x: 0x0000 + y: 0x0000 + z: 0x0000 + set id: 0xFFFF + patch: + # Give the door a custom flag not tied to the portal + parameters: 0x063010FF + layers: + - 2 + + # Statue guarding door to the past + - action: patch + name: Sekizoa + parameters: 0x3000EE64 + position: + x: 0.0 + y: 1725.0 + z: 7020.0 + angle: + x: 0x0000 + y: 0x0000 + z: 0x0000 + set id: 0xFFFF + patch: + # Give the statue a custom flag not tied to the portal + parameters: 0x3000EE63 + layers: + - 2 + + # Msg Tag for striking pedestal + - action: patch + name: KMsg + parameters: 0x03AA96C7 + position: + x: 0.0 + y: 1700.0 + z: -5435.0 + angle: + x: 0x8064 + y: 0x0000 + z: 0x0000 + set id: 0xFFFF + scale: + x: 0x23 + y: 0x23 + z: 0x23 + patch: + # Give the tag a custom flag not tied to the portal + angle: + x: 0x80FF + layers: + - 2 + # Spawn in the Master Sword actor - action: add name: mstrsrd diff --git a/src/dusk/randomizer/generator/data/settings_list.yaml b/src/dusk/randomizer/generator/data/settings_list.yaml index 9aeed4c0b9..19265b7d5c 100644 --- a/src/dusk/randomizer/generator/data/settings_list.yaml +++ b/src/dusk/randomizer/generator/data/settings_list.yaml @@ -471,6 +471,7 @@ - Open: description - Name: Temple of Time Sword Requirement + Need In Game: True Tracker Important: True Default Option: None Options: diff --git a/src/dusk/randomizer/generator/data/startflags.yaml b/src/dusk/randomizer/generator/data/startflags.yaml index 6f26398797..4381f9f3e7 100644 --- a/src/dusk/randomizer/generator/data/startflags.yaml +++ b/src/dusk/randomizer/generator/data/startflags.yaml @@ -276,7 +276,7 @@ RegionFlags: - 0x49 # Stairs to Temple of time created. - 0x4A # Struck master sword pedestal with sword. - 0x4B # Stairs and window appear and work properly (Past). - - 0xBC # Statue in present is gone. + - 0xBC # Statue in present is gone. (custom flag) - Sacred_Grove_Does_Not_Require_Skull_Kid == On: - 0xB6 # Skull Kid - Human defeated. - 0xB7 # Lost Woods Turns to day after defeating Skull Kid - Human