From 69678bde4db89d25ea5eeafb77a81bbdf6aa437a Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Fri, 26 Sep 2025 20:26:52 -0400 Subject: [PATCH 01/12] Initial commit + test achievement + TWW backup --- ...egend of Zelda, The Skyward Sword.rascript | 67 ++++++++++++++++++ The Wind Waker.ods | Bin 667 -> 35141 bytes 2 files changed, 67 insertions(+) create mode 100644 RA Scripts/Legend of Zelda, The Skyward Sword.rascript diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript new file mode 100644 index 0000000..22a277d --- /dev/null +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -0,0 +1,67 @@ +// The Legend of Zelda: Skyward Sword +// #ID = 202 + +// $955E56: Sword [8-bit] +// +// 0x01 = Practice Sword +function equippedSword() => byte(0x955E56) + +// $95A766: Current HP [16-bit BE] +// +// Every 4 = 1 heart container, maximum of 80. +function hp() => word_be(0x95A766) + +// $95A768: Maximum HP [16-bit BE] +// +// Every 4 = 1 heart container, maximum of 80. +function maxHp() => word_be(0x95A768) + +function Hearts() => maxHp() / 4 + +// $B7A9C4: Stamina [32-bit BE] +function stamina() => dword_be(0xB7A9C4) + +function areaId() => dword_be(0x005b51e0) + +areas = { + 0x46303031: { "name": "Knight Academy", },0x46303039: { "name": "Sparring Hall", },0x46303030: { "name": "Skyloft", },0x44303030: { "name": "Waterfall", }, +} + +rpLookup = {} + +for id in areas +{ + rpLookup[id] = areas[id]["name"] +} + +function Delta(mem) => prev(mem) + +function WasValueJustChanged(mem, oldValue, newValue) +{ + return Delta(mem) == oldValue && mem == newValue +} + +function IsInArea(id) => areaId() == id +function IsInAreaByName(name) +{ + for id in areas + { + if (rpLookup[id] == name) + { + return areaId() == id + } + } +} + +rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️", + rich_presence_lookup("Locations", areaId(), rpLookup, "Somewhere in the sky..."), + rich_presence_value("Hearts", Hearts()) +) + +//rich_presence_conditional_display(IsOnTitleScreen(), "On the title screen...") +//rich_presence_conditional_display(IsSelectingFile(), "Selecting a file...") +rich_presence_display("Somewhere in the sky...") + +achievement(title = "My Body Is Ready", description = "Obtain the Training Sword.", points = 0, + trigger = IsInAreaByName("Sparring Hall") && WasValueJustChanged(equippedSword(), 0, 1) +) diff --git a/The Wind Waker.ods b/The Wind Waker.ods index acb7e250eb426b36df6d5ce3a7dcb94c67a35cec..c1933e85ed0f2a4a1e5844eb88a1f29a7b2746d9 100644 GIT binary patch literal 35141 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 MfYz|qQJDY!4^W#7vj6}9 literal 667 zcmWIWW@Zs#0D(7F2LoDjEW7l8Y!K!E;@r&K)RM}A)Wm{!u#8`oW$`|sD)3vUpfVE}rDxv?#z6X=QmK+Fxq$@zIDAm0PM z5Zix|>yQDD>-?|U$L_uUVtVGUw{Nh{ma`E-1@-xbc@dw5-r1VR7;XB_$SITTIpwNC z`r6&qOJ}f}RlPqwsc|h!V~#MV2GjW|-?e}E9)4T&c6o7l`X8$%?-`-H7H+M5YjjUZ z(p|#-#}?!0DU+`@xRvx?ImEtu>nZ2cdnS~AQn{pSZgSB1U%lmC#sF_dCJ|=bkqUG+ z7;I?-QLrdR=)xXt5IqbGTN*=vOstWJYy`HzLKvY4ObbXs7vRmx29jh3!c9Q>GEka< F0RU=# Date: Sun, 2 Nov 2025 20:36:54 -0500 Subject: [PATCH 02/12] Added "To Forgotten Lands" and "Less Lethal" --- ...egend of Zelda, The Skyward Sword.rascript | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index 22a277d..bf19912 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -23,8 +23,10 @@ function stamina() => dword_be(0xB7A9C4) function areaId() => dword_be(0x005b51e0) +function lightingState() => byte(0x00593941) + areas = { - 0x46303031: { "name": "Knight Academy", },0x46303039: { "name": "Sparring Hall", },0x46303030: { "name": "Skyloft", },0x44303030: { "name": "Waterfall", }, +0x46303031: { "name": "Knight Academy", },0x46303039: { "name": "Sparring Hall", },0x46303030: { "name": "Skyloft", },0x44303030: { "name": "Waterfall", },0x46303230: { "name": "The Sky", },0x46303038: { "name": "Chamber of the Sword", },0x46303231: { "name": "Sealed Grounds", },0x46343031: { "name": "Sealed Grounds", },0x46343032: { "name": "Sealed Temple", },0x46343030: { "name": "Sealed Grounds", },0x46313030: { "name": "Faron Woods", },0x46313031: { "name": "Deep Woods", },0x44313030: { "name": "Skyview Temple", }, } rpLookup = {} @@ -36,11 +38,23 @@ for id in areas function Delta(mem) => prev(mem) +function FileIsLoading() => IsInAreaByName("Skyloft") && (lightingState() == 0xc || lightingState() == 0x4) + function WasValueJustChanged(mem, oldValue, newValue) { return Delta(mem) == oldValue && mem == newValue } +function WasBitflagJustSet(mem) +{ + return WasValueJustChanged(mem, 0, 1) +} + +function WasBitflagJustSetInGame(mem) +{ + return WasBitflagJustSet(mem) && !FileIsLoading() +} + function IsInArea(id) => areaId() == id function IsInAreaByName(name) { @@ -62,6 +76,16 @@ rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️", //rich_presence_conditional_display(IsSelectingFile(), "Selecting a file...") rich_presence_display("Somewhere in the sky...") -achievement(title = "My Body Is Ready", description = "Obtain the Training Sword.", points = 0, - trigger = IsInAreaByName("Sparring Hall") && WasValueJustChanged(equippedSword(), 0, 1) +achievement(title = "My Body Is Ready", description = "Obtain the Training Sword.", points = 0, type = "progression", + trigger = IsInAreaByName("Sparring Hall") && WasBitflagJustSetInGame(equippedSword()) +) + +function descentToTheSurfaceForTheFirstTime() => bit4(0x00955d94) +achievement(title = "To Forgotten Lands", description = "Descend to the surface for the first time.", points = 3, type = "progression", + trigger = IsInAreaByName("The Sky") && WasBitflagJustSetInGame(descentToTheSurfaceForTheFirstTime()) +) + +function slingshot() => bit4(0x00955e4a) +achievement(title = "Less Lethal", description = "Obtain the Slingshot.", points = 3, type = "progression", + trigger = WasBitflagJustSetInGame(slingshot()) ) From 4dd5418b1fbd573f0ee7c9c5b1caea95257e391c Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Sat, 6 Dec 2025 23:37:34 -0500 Subject: [PATCH 03/12] Finished achievements up until the end of the Skyview Temple --- ...egend of Zelda, The Skyward Sword.rascript | 136 ++++++++++++++++-- 1 file changed, 125 insertions(+), 11 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index bf19912..16ad271 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -6,15 +6,8 @@ // 0x01 = Practice Sword function equippedSword() => byte(0x955E56) -// $95A766: Current HP [16-bit BE] -// -// Every 4 = 1 heart container, maximum of 80. -function hp() => word_be(0x95A766) - -// $95A768: Maximum HP [16-bit BE] -// -// Every 4 = 1 heart container, maximum of 80. -function maxHp() => word_be(0x95A768) +function hp() => word_be(0x0095a76a) +function maxHp() => word_be(0x0095a766) function Hearts() => maxHp() / 4 @@ -26,7 +19,7 @@ function areaId() => dword_be(0x005b51e0) function lightingState() => byte(0x00593941) areas = { -0x46303031: { "name": "Knight Academy", },0x46303039: { "name": "Sparring Hall", },0x46303030: { "name": "Skyloft", },0x44303030: { "name": "Waterfall", },0x46303230: { "name": "The Sky", },0x46303038: { "name": "Chamber of the Sword", },0x46303231: { "name": "Sealed Grounds", },0x46343031: { "name": "Sealed Grounds", },0x46343032: { "name": "Sealed Temple", },0x46343030: { "name": "Sealed Grounds", },0x46313030: { "name": "Faron Woods", },0x46313031: { "name": "Deep Woods", },0x44313030: { "name": "Skyview Temple", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", }, } rpLookup = {} @@ -45,6 +38,11 @@ function WasValueJustChanged(mem, oldValue, newValue) return Delta(mem) == oldValue && mem == newValue } +function WasValueJustChangedInGame(mem, oldValue, newValue) +{ + return WasValueJustChanged(mem, oldValue, newValue) && !FileIsLoading() +} + function WasBitflagJustSet(mem) { return WasValueJustChanged(mem, 0, 1) @@ -67,6 +65,17 @@ function IsInAreaByName(name) } } +function IsInAreaByInternalName(name) +{ + for id in areas + { + if (areas[id]["internalName"] == name) + { + return areaId() == id + } + } +} + rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️", rich_presence_lookup("Locations", areaId(), rpLookup, "Somewhere in the sky..."), rich_presence_value("Hearts", Hearts()) @@ -76,7 +85,7 @@ rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️", //rich_presence_conditional_display(IsSelectingFile(), "Selecting a file...") rich_presence_display("Somewhere in the sky...") -achievement(title = "My Body Is Ready", description = "Obtain the Training Sword.", points = 0, type = "progression", +achievement(title = "My Body Is Ready", description = "Obtain the Training Sword.", points = 3, type = "progression", trigger = IsInAreaByName("Sparring Hall") && WasBitflagJustSetInGame(equippedSword()) ) @@ -89,3 +98,108 @@ function slingshot() => bit4(0x00955e4a) achievement(title = "Less Lethal", description = "Obtain the Slingshot.", points = 3, type = "progression", trigger = WasBitflagJustSetInGame(slingshot()) ) + +function animationId() => word_be(0x00b76966) +function JustClankedGivenNumberOfTimes(times) +{ + clankIds = [ + 0xc0, + 0xc2, + 0xc4, + 0xc6, + 0xc8, + 0xca, + 0xcc, + 0xce, + 0xd0, + 0xd2 + ] + + triggers = [] + + for id in clankIds + { + array_push(triggers, Delta(animationId()) != id && animationId() == id) + } + + return tally(times, triggers) +} + +function JustUsedSpinAttack() +{ + spinIds = [ + 0x4f, // Horizontal, counterclockwise + 0x50, // Horizontal, clockwise + 0x51, // Vertical, downward + 0x52, // Vertical, upward + ] + + trigger = always_false() + + for id in spinIds + { + trigger = trigger || Delta(animationId()) != id && animationId() == id + } + + return trigger +} + +function beetleChestAppeared() => bit6(0x00956f78) +function beetle() => bit5(0x00955e4a) +function xCoordinate() => float_be(0x005a28b8) +function yCoordinate() => float_be(0x005a28bc) +function zCoordinate() => float_be(0x005a28c0) +function BattleCheckpointStarted(when, neverWhen = always_false()) => once(when) && never(hp() <= 0) && never(neverWhen) +achievement(title = "Deft Strikes", type = "missable", points = 5, + description = "Defeat the Stalfos in the Skyview Temple without clashing more than three times and without using Spin Attacks (no resurrections).", + trigger = BattleCheckpointStarted(xCoordinate() == 0.0 && yCoordinate() == -60.0 && zCoordinate() == -7765.0 && Delta(animationId()) == 0x12d && animationId() == 0x12, + neverWhen = !IsInAreaByInternalName("SkyviewTemple")) + && trigger_when(beetleChestAppeared() == 1) + && never(beetle() == 1) + && never(JustClankedGivenNumberOfTimes(4)) + && never(lightingState() != 6) + && never(JustUsedSpinAttack()) +) + +achievement(title = "Droning On", description = "Obtain the Beetle.", points = 3, type = "progression", + trigger = WasBitflagJustSetInGame(beetle()) +) + +function fieldPointer() => dword_be(0x00ec936c) +function ghirahimIHp() => word_be(0x00b68122) +function activeKunai() => word_be(fieldPointer() - 0x80000000 + 0x29c) +function ghirahimIXCoord() => float_be(0x00b65008) +function ghirahimIZCoord() => float_be(0x00b65010) +function actualXCoord() => float_be(0x00b747c4) +function actualZCoord() => float_be(0x00b747cc) +function GhirahimIBattleCheckpointReached() => BattleCheckpointStarted(xCoordinate() == 0.0 && yCoordinate() == 150.0 && zCoordinate() == -1100.0 && prior(animationId()) == 0xffff + && animationId() == 0x12, + neverWhen = !IsInAreaByInternalName("STBossRoom")) +function GhirahimIBattleTriggered() => trigger_when(Delta(activeKunai()) > activeKunai()) + && trigger_when(ghirahimIHp() <= 0 && prior(ghirahimIHp()) > 0) + && never(repeated(5, GhirahimIBattleCheckpointReached() && ghirahimIHp() == 0)) // His HP drops to zero a frame before his kunai actually disappear from hitting him, so there needs to be + // a delay to make sure that stray kunai disappearing don't trigger the achievement. And since his HP is at 0 for three frames before the fight starts, we set this to 4 to prevent + // the achievement from being reset prematurely. +// Limitation: This triggers when his kunai disappear, not just when he's defeated with them. However, the odds of a player finishing him off on the frame that any stray kunai disappear +// are low. But if this ever does become an issue, we can update the description to specify to defeat him right as his kunai disappear, though it'll be a far less elegant description. +achievement(title = "Like a Monk", type = "missable", points = 10, + description = "Finish off Ghirahim in Skyview Temple with projectiles (no resurrections).", + trigger = GhirahimIBattleCheckpointReached() + && GhirahimIBattleTriggered() +) + +leaderboard(title = "Ghirahim I HP Remaining", description = "This leaderboard is for informative purposes only.", + start = GhirahimIBattleCheckpointReached(), + cancel = GhirahimIBattleTriggered(), + submit = always_false(), + value = ghirahimIHp() +) + +function rubyTablet() => bit2(0x00955e5a) +achievement(title = "Skyview Prayers", type = "progression", description = "Obtain the Ruby Tablet.", points = 3, + trigger = WasBitflagJustSetInGame(rubyTablet()) +) + +achievement(title = "Heartthrob", description = "Have a total of 20 hearts' worth of life energy.", points = 10, + trigger = measured(maxHp() == 80, format = "percent") && Delta(maxHp() == 76) && WasValueJustChangedInGame(maxHp(), 76, 80) +) From 68dea6a8a5ce6dd407604c04761070e4843db8e5 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Tue, 30 Dec 2025 23:44:49 -0500 Subject: [PATCH 04/12] Implemented Mole Mitts achievement + a few others --- ...egend of Zelda, The Skyward Sword.rascript | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index 16ad271..2ba5348 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -18,8 +18,10 @@ function areaId() => dword_be(0x005b51e0) function lightingState() => byte(0x00593941) +function dialogueIdAddr() => 0x005a88f4 + areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", }, } rpLookup = {} @@ -32,10 +34,11 @@ for id in areas function Delta(mem) => prev(mem) function FileIsLoading() => IsInAreaByName("Skyloft") && (lightingState() == 0xc || lightingState() == 0x4) +function UnlessSavingAndQuitting() => disable_when(WasInAreaByInternalName("SaveAndQuitTransition") && IsInAreaByName("Skyloft"), until = repeated(210, IsInAreaByName("Skyloft"))) function WasValueJustChanged(mem, oldValue, newValue) { - return Delta(mem) == oldValue && mem == newValue + return Delta(mem) == oldValue && mem == newValue && UnlessSavingAndQuitting() // todo: UnlessSavingAndQuitting() needs to be moved to WasValueChangedInGame() once the RATools bug is fixed. } function WasValueJustChangedInGame(mem, oldValue, newValue) @@ -76,9 +79,22 @@ function IsInAreaByInternalName(name) } } -rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️", +function WasInAreaByInternalName(name) +{ + for id in areas + { + if (areas[id]["internalName"] == name) + { + return prior(areaId()) == id + } + } +} + +function sessionPlayTime() => dword_be(0x00577e50) / 600 +rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️ • Session time: {2}", rich_presence_lookup("Locations", areaId(), rpLookup, "Somewhere in the sky..."), - rich_presence_value("Hearts", Hearts()) + rich_presence_value("Hearts", Hearts()), + rich_presence_value("Session", sessionPlayTime(), "SECS") ) //rich_presence_conditional_display(IsOnTitleScreen(), "On the title screen...") @@ -203,3 +219,30 @@ achievement(title = "Skyview Prayers", type = "progression", description = "Obta achievement(title = "Heartthrob", description = "Have a total of 20 hearts' worth of life energy.", points = 10, trigger = measured(maxHp() == 80, format = "percent") && Delta(maxHp() == 76) && WasValueJustChangedInGame(maxHp(), 76, 80) ) + +achievement(title = "Defenestration Shopping", description = "Leave Beedle's Airshop without buying anything.", points = 1, + trigger = once(ascii_string_equals(dialogueIdAddr(), "TERY_09", 8)) + && once(ascii_string_equals(dialogueIdAddr(), "TERY_10", 8)) + && IsInAreaByName("Skyloft") +) + +function bugNet() => bit0(0x00955e4c) +achievement(title = "Swoosh", description = "Purchase the Bug Net.", points = 3, + trigger = WasBitflagJustSetInGame(bugNet()) +) + +function moleMitts() => bit6(0x00955e4a) +achievement(title = "Honorary Mole Man", description = "Obtain the Mole Mitts.", points = 3, type = "progression", + trigger = WasBitflagJustSetInGame(moleMitts()) +) + +function numberOfPouchUpgrades() => (byte(0x00955eb4) & 0x1c) / 4 +achievement(title = "For Every Occasion", description = "Acquire all four Adventure Pouch upgrades.", points = 10, + trigger = WasValueJustChangedInGame(numberOfPouchUpgrades(), 3, 4) + && measured(numberOfPouchUpgrades() == 4) +) + +achievement(title = "I.O.U.", description = "Pick up a Rupoor.", points = 1, + trigger = ascii_string_equals(dialogueIdAddr(), "ITEM_034", 9) + && IsInAreaByInternalName("EldinThrillDigger") +) From 7f74944f7431b72faa0d7c76c3281293c28015b1 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Wed, 21 Jan 2026 00:21:34 -0500 Subject: [PATCH 05/12] Added achievements up to the end of the Earth Temple --- ...egend of Zelda, The Skyward Sword.rascript | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index 2ba5348..f46df8a 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -21,7 +21,7 @@ function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Mine", "internalName": "", }, } rpLookup = {} @@ -34,7 +34,8 @@ for id in areas function Delta(mem) => prev(mem) function FileIsLoading() => IsInAreaByName("Skyloft") && (lightingState() == 0xc || lightingState() == 0x4) -function UnlessSavingAndQuitting() => disable_when(WasInAreaByInternalName("SaveAndQuitTransition") && IsInAreaByName("Skyloft"), until = repeated(210, IsInAreaByName("Skyloft"))) +function UnlessSavingAndQuitting() => disable_when( + (WasInAreaByInternalName("SaveAndQuitTransition") || WasInAreaByInternalName("GameOverTransition")) && IsInAreaByName("Skyloft"), until = repeated(210, IsInAreaByName("Skyloft"))) function WasValueJustChanged(mem, oldValue, newValue) { @@ -90,6 +91,17 @@ function WasInAreaByInternalName(name) } } +function WasJustInAreaByInternalName(name) +{ + for id in areas + { + if (areas[id]["internalName"] == name) + { + return Delta(areaId()) == id + } + } +} + function sessionPlayTime() => dword_be(0x00577e50) / 600 rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️ • Session time: {2}", rich_presence_lookup("Locations", areaId(), rpLookup, "Somewhere in the sky..."), @@ -202,6 +214,7 @@ achievement(title = "Like a Monk", type = "missable", points = 10, description = "Finish off Ghirahim in Skyview Temple with projectiles (no resurrections).", trigger = GhirahimIBattleCheckpointReached() && GhirahimIBattleTriggered() + && never(hp() <= 0) ) leaderboard(title = "Ghirahim I HP Remaining", description = "This leaderboard is for informative purposes only.", @@ -246,3 +259,64 @@ achievement(title = "I.O.U.", description = "Pick up a Rupoor.", points = 1, trigger = ascii_string_equals(dialogueIdAddr(), "ITEM_034", 9) && IsInAreaByInternalName("EldinThrillDigger") ) + +function rupees() => word_be(0x00955ec2) +function thrillDiggerRupeeValueCollected() => dword_be(0x00b6c5cc) +function thrillDiggerRupeesCollected() => byte(0x00b6ffda) +function thrillDiggerTotalCollectableRupees() => byte(0x00b6ffdb) +function thrillDiggerUnpickedBombFlowers() => byte(0x00b6ffdc) +function ThrillDiggerStarted() => once(thrillDiggerRupeesCollected() == 0 && Delta(thrillDiggerTotalCollectableRupees()) != thrillDiggerTotalCollectableRupees()) +function ThrillDiggerJustRevealedBoard() => Delta(thrillDiggerUnpickedBombFlowers()) == 0 && thrillDiggerUnpickedBombFlowers() > 0 +function ThrillDiggerJustEnded() => Delta(thrillDiggerUnpickedBombFlowers()) > 0 && thrillDiggerUnpickedBombFlowers() == 0 +function ThrillDiggerChoseBeginner() => once(Delta(rupees()) - rupees() == 30) +function ThrillDiggerChoseIntermediate() => once(Delta(rupees()) - rupees() == 50) +function ThrillDiggerChoseExpert() => once(Delta(rupees()) - rupees() == 70) +achievement(title = "Greenbeard", description = "Win a game of Thrill Digger on Beginner difficulty.", points = 3, + trigger = ThrillDiggerStarted() && trigger_when(ThrillDiggerJustRevealedBoard() && thrillDiggerRupeesCollected() == thrillDiggerTotalCollectableRupees()) + && ThrillDiggerChoseBeginner() + && never(ThrillDiggerJustEnded()) +) + +achievement(title = "Longbeard", description = "Win a game of Thrill Digger on Intermediate difficulty.", points = 5, + trigger = ThrillDiggerStarted() && trigger_when(ThrillDiggerJustRevealedBoard() && thrillDiggerRupeesCollected() == thrillDiggerTotalCollectableRupees()) + && ThrillDiggerChoseIntermediate() + && never(ThrillDiggerJustEnded()) +) + +achievement(title = "Lord of the Deep", description = "Win a game of Thrill Digger on Expert difficulty.", points = 10, + trigger = ThrillDiggerStarted() && trigger_when(ThrillDiggerJustRevealedBoard() && thrillDiggerRupeesCollected() == thrillDiggerTotalCollectableRupees()) + && ThrillDiggerChoseExpert() + && never(ThrillDiggerJustEnded()) +) + +function bombBag() => bit2(0x00955e51) +achievement(title = "One Errant Twitch...", description = "Obtain the Bomb Bag.", points = 3, type = "progression", + trigger = WasBitflagJustSetInGame(bombBag()) +) + +function dragonSculpture() => bit7(0x00956fab) +function boulderComplete() => bit7(0x00956fa8) +// A "false start" in this case simply means sprinting before the cutscene starts. It's difficult to distinguish between cutscene recovery or Stamina Fruit recovery because both +// fully recover stamina. Therefore, we need the player to jog normally up to the "starting line," so to speak. +achievement(title = "Pace Yourself", description = "Escape the rolling boulder in the Earth Temple without recovering stamina with Stamina Fruit (no resurrections; no false starts).", points = 3, + type = "missable", + trigger = once(dragonSculpture() == 1 && Delta(dragonSculpture()) == 0 && IsInAreaByInternalName("ETMain")) + && trigger_when(boulderComplete() == 1) + && never(hp() <= 0) + && never(stamina() > Delta(stamina()) + 12000) +) + +function ScalderaBattleCheckpointReached() => BattleCheckpointStarted(WasJustInAreaByInternalName("ETMain") && IsInAreaByInternalName("ETBossRoom"), + neverWhen = !IsInAreaByInternalName("ETBossRoom")) +function scalderaHp() => byte(0x00b4dc63) +function bombsInBombBag() => byte(0x00955ec6) * 2 + bit7(0x00955ec7) +achievement(title = "Handle with Care", type = "missable", description = "Defeat Scaldera without pulling out more than six bombs out of your Bomb Bag (no resurrections).", points = 10, + trigger = ScalderaBattleCheckpointReached() + && trigger_when(scalderaHp() <= 0 && Delta(scalderaHp()) > 0) + && never(repeated(7, bombsInBombBag() < Delta(bombsInBombBag()))) +) + +function amberTablet() => bit3(0x00955e5a) +achievement(title = "Earth Prayers", type = "progression", description = "Obtain the Amber Tablet.", points = 3, + trigger = WasBitflagJustSetInGame(amberTablet()) +) \ No newline at end of file From 18ffa588ea132d484c9f8ff04ef0abc292649466 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Mon, 16 Feb 2026 23:40:26 -0500 Subject: [PATCH 06/12] Added achievements up to Farore's Silent Realm --- ...egend of Zelda, The Skyward Sword.rascript | 147 +++++++++++++++++- 1 file changed, 139 insertions(+), 8 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index f46df8a..11e744a 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -1,6 +1,20 @@ // The Legend of Zelda: Skyward Sword // #ID = 202 +function SecondsToFrames(value) => value * 30 +function SecondsToFormat(value) +{ + leadingZero = "" + if (value % 60 < 10) + { + leadingZero = "0" + } + return value / 60 + ":" + leadingZero + value % 60 +} + +function LMeasured(condition) => measured(repeated(0, condition)) // Legacy `measured` polyfill. measured(A && B) is no longer supported as of v1.10.0. +function Delta(mem) => prev(mem) + // $955E56: Sword [8-bit] // // 0x01 = Practice Sword @@ -14,14 +28,16 @@ function Hearts() => maxHp() / 4 // $B7A9C4: Stamina [32-bit BE] function stamina() => dword_be(0xB7A9C4) -function areaId() => dword_be(0x005b51e0) +function areaIdAddr() => 0x005b51e0 +function areaId() => dword_be(areaIdAddr()) +function topAreaByte() => byte(areaIdAddr()) function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Mine", "internalName": "", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", }, } rpLookup = {} @@ -31,11 +47,11 @@ for id in areas rpLookup[id] = areas[id]["name"] } -function Delta(mem) => prev(mem) +function WasTransitioningFromSaveOrQuit() => prior(topAreaByte()) == 0 function FileIsLoading() => IsInAreaByName("Skyloft") && (lightingState() == 0xc || lightingState() == 0x4) -function UnlessSavingAndQuitting() => disable_when( - (WasInAreaByInternalName("SaveAndQuitTransition") || WasInAreaByInternalName("GameOverTransition")) && IsInAreaByName("Skyloft"), until = repeated(210, IsInAreaByName("Skyloft"))) +function UnlessSavingAndQuitting() => disable_when(WasTransitioningFromSaveOrQuit() && IsInAreaByName("Skyloft"), until = repeated(240, IsInAreaByName("Skyloft"))) + && never(Delta(areaId()) != areaId()) function WasValueJustChanged(mem, oldValue, newValue) { @@ -114,7 +130,7 @@ rich_presence_conditional_display(IsInArea(areaId()), "{0} • {1} ❤️ • Se rich_presence_display("Somewhere in the sky...") achievement(title = "My Body Is Ready", description = "Obtain the Training Sword.", points = 3, type = "progression", - trigger = IsInAreaByName("Sparring Hall") && WasBitflagJustSetInGame(equippedSword()) + trigger = IsInAreaByName("Sparring Hall") && WasValueJustChangedInGame(equippedSword(), 0, 1) ) function descentToTheSurfaceForTheFirstTime() => bit4(0x00955d94) @@ -310,7 +326,9 @@ function ScalderaBattleCheckpointReached() => BattleCheckpointStarted(WasJustInA neverWhen = !IsInAreaByInternalName("ETBossRoom")) function scalderaHp() => byte(0x00b4dc63) function bombsInBombBag() => byte(0x00955ec6) * 2 + bit7(0x00955ec7) -achievement(title = "Handle with Care", type = "missable", description = "Defeat Scaldera without pulling out more than six bombs out of your Bomb Bag (no resurrections).", points = 10, +// This achievement can be done in as few as five bombs, perhaps fewer. However, hitting Scaldera's weak point can be quite finicky, and it's randomly predetermined what parts of its shell +// will break off first, limiting predictability. May want to consider increasing the point value to 25 to make up for the considerable iteration time, too. +achievement(title = "Handle with Care", type = "missable", description = "Defeat Scaldera without pulling more than six bombs out of your Bomb Bag (no resurrections).", points = 10, trigger = ScalderaBattleCheckpointReached() && trigger_when(scalderaHp() <= 0 && Delta(scalderaHp()) > 0) && never(repeated(7, bombsInBombBag() < Delta(bombsInBombBag()))) @@ -319,4 +337,117 @@ achievement(title = "Handle with Care", type = "missable", description = "Defeat function amberTablet() => bit3(0x00955e5a) achievement(title = "Earth Prayers", type = "progression", description = "Obtain the Amber Tablet.", points = 3, trigger = WasBitflagJustSetInGame(amberTablet()) -) \ No newline at end of file +) + +function extraWalletsObtained() => byte(0x00955ec6) / 64 +achievement(title = "I Don't NEED Credit", description = "Obtain a wallet maximum of 9,900 Rupees.", points = 5, + trigger = always_false() +) + +function hookBeetle() => bit1(0x00955e4f) +achievement(title = "Death from Above", type = "progression", description = "Upgrade the Beetle into the Hook Beetle.", points = 3, + trigger = WasBitflagJustSetInGame(hookBeetle()) +) + +function gustBellows() => bit1(0x00955e4a) +achievement(title = "Wonderful Rush", type = "progression", description = "Obtain the Gust Bellows.", points = 3, + trigger = WasBitflagJustSetInGame(gustBellows()) +) + +function shieldSlotIndex() => byte(0x0095a815) +function ShieldIsEquipped() => shieldSlotIndex() != 8 +function moldarachHp() => byte(0x00b6d9e5) +achievement(title = "Fleet-footed", description = "Defeat Moldarach in the Lanayru Mining Facility without having a shield equipped and without recovering life energy.", points = 5, + type = "missable", + trigger = BattleCheckpointStarted(WasJustInAreaByInternalName("LMFMain") && IsInAreaByInternalName("LMFBossRoom"), + neverWhen = !IsInAreaByInternalName("LMFBossRoom")) + && never(Delta(hp()) < hp()) + && never(ShieldIsEquipped()) + && trigger_when(moldarachHp() <= 0 && Delta(moldarachHp()) > 0) +) + +function goddessHarp() => bit1(0x00955e58) +achievement(title = "In Harmonia", type = "progression", description = "Obtain the Goddess's Harp.", points = 3, + trigger = WasBitflagJustSetInGame(goddessHarp()) +) + +function balladOfTheGoddess() => bit5(0x00955e5f) +achievement(title = "Canon Cancrizans", description = "Learn the Ballad of the Goddess.", points = 3, type = "progression", + trigger = WasBitflagJustSetInGame(balladOfTheGoddess()) +) + +function playerSealPromptI() => bit1(0x00956f6b) +function imprisonedBaseAddr() => 0x00b19b65 +function imprisonedIHp() => byte(imprisonedBaseAddr()) + +function ImprisonedToeWasJustAttacked() +{ + trigger = always_false() + for i in range(1, 8) + { + toeHp = byte(imprisonedBaseAddr() + 12 * i) + trigger = trigger || Delta(toeHp) > toeHp + } + + return trigger +} + +function ImprisonedICheckpointReached() => BattleCheckpointStarted(once(ascii_string_equals(dialogueIdAddr(), "CF_05", 6)) + && once(ascii_string_equals(dialogueIdAddr(), "CF_05", 6)) + && IsInAreaByInternalName("SealedGroundsCutscene"), neverWhen = !IsInAreaByInternalName("SealedGroundsCutscene") + || ascii_string_equals(dialogueIdAddr(), "CF_47", 6)) // Nonstandard game over dialogue +achievement(title = "What Am I, A Podiatrist?", description = "Defeat the Imprisoned I without attacking its toes (no resurrections).", points = 5, type = "missable", + trigger = ImprisonedICheckpointReached() && never(playerSealPromptI() == 1) + && never(ImprisonedToeWasJustAttacked()) + && trigger_when(imprisonedIHp() == 0 && Delta(imprisonedIHp()) == 1) +) + +function faroresCourage() => bit6(0x00955e5f) +achievement(title = "The Melody of Valor", description = "Learn Farore's Courage.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(faroresCourage()) +) + +function tearsCollected() => byte(0x0097bbb3) +function silentRealmTimeRemaining() => dword_be(0x0097b46c) +function SilentRealmFrameElapsed() => silentRealmTimeRemaining() < Delta(silentRealmTimeRemaining()) +function SilentRealmFramesElapsed30FPS() => tally(0, [ SilentRealmFrameElapsed(), SilentRealmFrameElapsed() ]) +function faroreWiltlessTimeLimit() => 45 +function TearsWereReset() => Delta(tearsCollected()) > 0 && tearsCollected() == 0 +function SilentRealmCompleted() => tearsCollected() == 15 && (Delta(silentRealmTimeRemaining()) == 0 || Delta(silentRealmTimeRemaining()) == 91000) && silentRealmTimeRemaining() == 1000 +function LeftFaroresSilentRealm() => !IsInAreaByInternalName("FaroreSilentRealm") +function FaroresSilentRealmCheckpointReached() => once(Delta(tearsCollected()) == 0 && tearsCollected() == 1) + && never(LeftFaroresSilentRealm()) + && disable_when(repeated(SecondsToFrames(faroreWiltlessTimeLimit()), SilentRealmFrameElapsed()), TearsWereReset()) + +leaderboard(title = "Wiltless Courage", description = "Complete Farore's Silent Realm while spending as little Spirit Vessel time as possible.", + start = FaroresSilentRealmCheckpointReached() && never(LeftFaroresSilentRealm()), + cancel = LeftFaroresSilentRealm(), + submit = SilentRealmCompleted(), + value = SilentRealmFramesElapsed30FPS() && never(TearsWereReset()), + format = "FRAMES", + lower_is_better = true +) + +achievement(title = "Wiltless Courage", description = "Complete Farore's Silent Realm before a total of " + faroreWiltlessTimeLimit() + " seconds passes from your Spirit Vessel.", points = 25, + trigger = FaroresSilentRealmCheckpointReached() && trigger_when(SilentRealmCompleted()) +) + +function waterDragonsScale() => bit5(0x00955e4d) +achievement(title = "Swimming Phenom", description = "Obtain the Water Dragon's Scale.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(waterDragonsScale()) +) + +function nayrusWisdom() => bit7(0x00955e5f) +achievement(title = "The Melody of Percipience", description = "Learn Nayru's Wisdom.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(nayrusWisdom()) +) + +function dinsPower() => bit0(0x00955e5e) +achievement(title = "The Melody of Might", description = "Learn Din's Power.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(dinsPower()) +) + +function songOfTheHero() => bit4(0x00955e5e) +achievement(title = "The Melody of Legend", description = "Learn the Song of the Hero.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(songOfTheHero()) +) From b580ac83e0a9c1044b79f47d9f2e6c4dadaf9496 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Sat, 21 Feb 2026 01:43:55 -0500 Subject: [PATCH 07/12] Added achievement up to Nayru's Silent Realm --- ...egend of Zelda, The Skyward Sword.rascript | 154 +++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index 11e744a..7ec7e27 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -37,7 +37,7 @@ function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", }, } rpLookup = {} @@ -50,7 +50,7 @@ for id in areas function WasTransitioningFromSaveOrQuit() => prior(topAreaByte()) == 0 function FileIsLoading() => IsInAreaByName("Skyloft") && (lightingState() == 0xc || lightingState() == 0x4) -function UnlessSavingAndQuitting() => disable_when(WasTransitioningFromSaveOrQuit() && IsInAreaByName("Skyloft"), until = repeated(240, IsInAreaByName("Skyloft"))) +function UnlessSavingAndQuitting() => disable_when(WasTransitioningFromSaveOrQuit() && IsInAreaByName("Skyloft"), until = repeated(300, IsInAreaByName("Skyloft"))) && never(Delta(areaId()) != areaId()) function WasValueJustChanged(mem, oldValue, newValue) @@ -188,6 +188,29 @@ function JustUsedSpinAttack() return trigger } +function JustSwungSword() +{ + ids = [ + 0xbf, // top-right -> bottom-left + 0xc1, // top -> bottom + 0xc3, // top-left -> bottom-right + 0xc5, // left -> right + 0xc7, // bottom -> top + 0xc9, // bottom-right -> top-left + 0xcb, // right -> left + 0xcf // bottom-left -> top-right + ] + + trigger = always_false() + + for id in ids + { + trigger = trigger || Delta(animationId()) != id && animationId() == id + } + + return trigger || JustUsedSpinAttack() +} + function beetleChestAppeared() => bit6(0x00956f78) function beetle() => bit5(0x00955e4a) function xCoordinate() => float_be(0x005a28b8) @@ -437,11 +460,138 @@ achievement(title = "Swimming Phenom", description = "Obtain the Water Dragon's trigger = WasBitflagJustSetInGame(waterDragonsScale()) ) +function tripleStalfosVictory() => bit0(0x00956f87) +function TripleStalfosCheckpointReached() => BattleCheckpointStarted(xCoordinate() == 0.0 && yCoordinate() == 150.0 && zCoordinate() == -1600.0 && prior(animationId()) == 0x12d + && animationId() == 0x12 && tripleStalfosVictory() == 0 && waterDragonsScale() == 1, + neverWhen = !IsInAreaByInternalName("STBossRoom")) +achievement(title = "Respect for the Undead", type = "missable", points = 5, + description = "Defeat the Stalfos trio in the Skyview Temple without pulling out a bomb (no resurrections).", + trigger = TripleStalfosCheckpointReached() + && trigger_when(WasBitflagJustSet(tripleStalfosVictory())) + && never(bombsInBombBag() < Delta(bombsInBombBag())) +) + +function CreateChain(permutation, predicate = a => a) +{ + trigger = always_true() + + for condition in permutation + { + trigger = predicate(trigger && condition) + } + + return trigger +} + +function guardState() => byte(0x00b7689b) +function ShieldHitboxWasJustActive() => Delta(guardState()) == 0x49 +function JustSuccessfullyParried() => ShieldHitboxWasJustActive() && guardState() != Delta(guardState()) && animationId() == 0xe1 +function JustUsedAttack(id) => animationId() == id && Delta(animationId()) != animationId() +function always_truthy() => byte(0) == 0x53 + +neverUsedAttackTrigger = always_false() +attackIds = [ + 0xbf, // top-right -> bottom-left + 0xc1, // top -> bottom + 0xc3, // top-left -> bottom-right + 0xc5, // left -> right + 0xc7, // bottom -> top + 0xc9, // bottom-right -> top-left + 0xcb, // right -> left + 0xcf, // bottom-left -> top-right + 0x4f, // Horizontal, counterclockwise + 0x50, // Horizontal, clockwise + 0x51, // Vertical, downward + 0x52, // Vertical, upward + 0xd1 // Stab +] + +for id in attackIds +{ + neverUsedAttackTrigger = neverUsedAttackTrigger || never(CreateChain([ repeated(90, always_truthy() && never(JustSuccessfullyParried())), JustUsedAttack(id), always_true() ])) +} + +function stalmasterVictoryAncientCistern() => bit1(0x00956f94) +achievement(title = "Stunlocked in Combat", points = 10, + description = "Defeat the Stalmaster in the Ancient Cistern using only follow-up attacks within three seconds of a parry (no resurrections).", type = "missable", + trigger = BattleCheckpointStarted(xCoordinate() == 0.0 && yCoordinate() == -2250.0 && zCoordinate() == 350.0 && prior(animationId()) == 0x12d + && animationId() == 0x12 && stalmasterVictoryAncientCistern() == 0, + neverWhen = !IsInAreaByInternalName("ACMain")) + && trigger_when(stalmasterVictoryAncientCistern() == 1) + && neverUsedAttackTrigger +) + +function whip() => bit4(0x00955e57) +achievement(title = "You Can Whip It!", description = "Obtain the Whip.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(whip()) +) + +function koloktosVictory() => bit4(0x00956f90) +function JustUsedTheWhip() +{ + trigger = always_false() + drawIds = [ + 0xf7, + 0xf8, // From top + 0xf9, // From top-left + 0xfa, // From left + 0xfb, // From bottom + 0xfc, + 0xfd + ] + + for id in drawIds + { + trigger = trigger || Delta(animationId()) == id && animationId() != Delta(animationId()) + } + + return trigger +} + +achievement(title = "Getting Right to the Stabbing", type = "missable", description = "Defeat Koloktos without whipping more than eight times (no resurrections).", points = 5, + trigger = BattleCheckpointStarted(xCoordinate() == 0.0 && yCoordinate() == 150.0 && zCoordinate() == 850.0 && prior(animationId()) == 0x26 + && animationId() == 0x12 && koloktosVictory() == 0, + neverWhen = !IsInAreaByInternalName("ACBossRoom")) + && trigger_when(koloktosVictory() == 1) + && never(repeated(9, JustUsedTheWhip())) +) + +function goddessLongsword() => bit1(0x00955e48) +achievement(title = "Towards Mastery", type = "progression", points = 3, description = "Forge the Goddess Longsword.", + trigger = WasBitflagJustSetInGame(goddessLongsword()) +) + function nayrusWisdom() => bit7(0x00955e5f) achievement(title = "The Melody of Percipience", description = "Learn Nayru's Wisdom.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(nayrusWisdom()) ) +// My record: 1:42.50 +function LeftNayrusSilentRealm() => !IsInAreaByInternalName("NayruSilentRealm") +function nayruWiltlessTimeLimit() => 110 +function NayrusSilentRealmCheckpointReached() => once(Delta(tearsCollected()) == 0 && tearsCollected() == 1) + && never(LeftNayrusSilentRealm()) + && disable_when(repeated(SecondsToFrames(nayruWiltlessTimeLimit()), SilentRealmFrameElapsed()), TearsWereReset()) + +leaderboard(title = "Wiltless Wisdom", description = "Complete Nayru's Silent Realm while spending as little Spirit Vessel time as possible.", + start = NayrusSilentRealmCheckpointReached() && never(LeftNayrusSilentRealm()), + cancel = LeftNayrusSilentRealm(), + submit = SilentRealmCompleted(), + value = SilentRealmFramesElapsed30FPS() && never(TearsWereReset()), + format = "FRAMES", + lower_is_better = true +) + +achievement(title = "Wiltless Wisdom", description = "Complete Nayru's Silent Realm before a total of " + SecondsToFormat(nayruWiltlessTimeLimit()) + + " passes from your Spirit Vessel.", points = 25, + trigger = NayrusSilentRealmCheckpointReached() && trigger_when(SilentRealmCompleted()) +) + +function clawshots() => bit5(0x00955e48) +achievement(title = "Skulltula-Man", description = "Obtain the Clawshots.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(clawshots()) +) + function dinsPower() => bit0(0x00955e5e) achievement(title = "The Melody of Might", description = "Learn Din's Power.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(dinsPower()) From d02812bb00d7fc7988b0b4be66d605d9e572cbf6 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Fri, 6 Mar 2026 17:44:48 -0500 Subject: [PATCH 08/12] Added achievements up to the Bow --- .../Legend of Zelda, The Skyward Sword.rascript | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index 7ec7e27..a1de158 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -37,7 +37,7 @@ function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", }, } rpLookup = {} @@ -592,6 +592,19 @@ achievement(title = "Skulltula-Man", description = "Obtain the Clawshots.", type trigger = WasBitflagJustSetInGame(clawshots()) ) +function scervoVictory() => bit1(0x00956fef) +achievement(title = "Three Strikes, And...", description = "Defeat LD-002G Scervo without getting hit more than twice (no resurrections).", type = "missable", points = 10, + trigger = BattleCheckpointStarted(prior(animationId()) == 0x10c && animationId() == 0x26 && scervoVictory() == 0, + neverWhen = !IsInAreaByInternalName("SMain")) + && trigger_when(WasBitflagJustSet(scervoVictory())) + && never(repeated(3, Delta(hp()) > hp())) +) + +function bow() => bit4(0x00955e48) +achievement(title = "Piercer", description = "Obtain the Bow.", type = "progression", points = 3, + trigger = WasBitflagJustSetInGame(bow()) +) + function dinsPower() => bit0(0x00955e5e) achievement(title = "The Melody of Might", description = "Learn Din's Power.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(dinsPower()) From f39aa2bc815cb17723658ee96e0e79b8ea7853c4 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Sun, 15 Mar 2026 16:36:12 -0400 Subject: [PATCH 09/12] Added achievements up until the Fireshield Earrings --- ...egend of Zelda, The Skyward Sword.rascript | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index a1de158..f5c0264 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -37,7 +37,7 @@ function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", },0x42333031: { "name": "Sandship", "internalName": "SBossRoom", },0x53323030: { "name": "Din's Silent Realm", "internalName": "DinSilentRealm", },0x46323031: { "name": "Volcano Summit", "internalName": "", }, } rpLookup = {} @@ -467,7 +467,7 @@ function TripleStalfosCheckpointReached() => BattleCheckpointStarted(xCoordinate achievement(title = "Respect for the Undead", type = "missable", points = 5, description = "Defeat the Stalfos trio in the Skyview Temple without pulling out a bomb (no resurrections).", trigger = TripleStalfosCheckpointReached() - && trigger_when(WasBitflagJustSet(tripleStalfosVictory())) + && trigger_when(tripleStalfosVictory() == 1) && never(bombsInBombBag() < Delta(bombsInBombBag())) ) @@ -596,7 +596,7 @@ function scervoVictory() => bit1(0x00956fef) achievement(title = "Three Strikes, And...", description = "Defeat LD-002G Scervo without getting hit more than twice (no resurrections).", type = "missable", points = 10, trigger = BattleCheckpointStarted(prior(animationId()) == 0x10c && animationId() == 0x26 && scervoVictory() == 0, neverWhen = !IsInAreaByInternalName("SMain")) - && trigger_when(WasBitflagJustSet(scervoVictory())) + && trigger_when(scervoVictory() == 1) && never(repeated(3, Delta(hp()) > hp())) ) @@ -605,11 +605,51 @@ achievement(title = "Piercer", description = "Obtain the Bow.", type = "progress trigger = WasBitflagJustSetInGame(bow()) ) +function arrowsInQuiver() => byte(0x00955ec7) & 0x7f +function tentalusVictory() => bit2(0x00956ff3) +achievement(title = "Eyecupuncture", description = "Defeat Tentalus using ten arrows or fewer (new resurrections).", type = "missable", points = 10, + trigger = BattleCheckpointStarted(Delta(animationId()) != 0xe && animationId() == 0xe && tentalusVictory() == 0, + neverWhen = !IsInAreaByInternalName("SBossRoom")) + && trigger_when(tentalusVictory() == 1) + && never(repeated(11, Delta(arrowsInQuiver()) > arrowsInQuiver())) +) + +function goddessWhiteSword() => bit4(0x00955e5f) +achievement(title = "Glistening Ivory", type = "progression", points = 3, description = "Forge the Goddess White Sword.", + trigger = WasBitflagJustSetInGame(goddessWhiteSword()) +) + function dinsPower() => bit0(0x00955e5e) achievement(title = "The Melody of Might", description = "Learn Din's Power.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(dinsPower()) ) +// My record: 1:42.26 +function LeftDinsSilentRealm() => !IsInAreaByInternalName("DinSilentRealm") +function dinWiltlessTimeLimit() => 125 +function DinsSilentRealmCheckpointReached() => once(Delta(tearsCollected()) == 0 && tearsCollected() == 1) + && never(LeftDinsSilentRealm()) + && disable_when(repeated(SecondsToFrames(dinWiltlessTimeLimit()), SilentRealmFrameElapsed()), TearsWereReset()) + +leaderboard(title = "Wiltless Power", description = "Complete Din's Silent Realm while spending as little Spirit Vessel time as possible.", + start = DinsSilentRealmCheckpointReached() && never(LeftDinsSilentRealm()), + cancel = LeftDinsSilentRealm(), + submit = SilentRealmCompleted(), + value = SilentRealmFramesElapsed30FPS() && never(TearsWereReset()), + format = "FRAMES", + lower_is_better = true +) + +achievement(title = "Wiltless Power", description = "Complete Din's Silent Realm before a total of " + SecondsToFormat(dinWiltlessTimeLimit()) + + " passes from your Spirit Vessel.", points = 25, + trigger = DinsSilentRealmCheckpointReached() && trigger_when(SilentRealmCompleted()) +) + +function fireshieldEarrings() => bit5(0x00955e57) +achievement(title = "Fireproof", description = "Obtain the Fireshield Earrings.", points = 3, type = "progression", + trigger = WasBitflagJustSetInGame(fireshieldEarrings()) +) + function songOfTheHero() => bit4(0x00955e5e) achievement(title = "The Melody of Legend", description = "Learn the Song of the Hero.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(songOfTheHero()) From 37cbb7c5e4f9e99fefc7a1a946446cfc7a3e9e3e Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Wed, 15 Apr 2026 16:29:20 -0400 Subject: [PATCH 10/12] "The Predecessor"--'nuff said --- ...egend of Zelda, The Skyward Sword.rascript | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index f5c0264..6fca849 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -37,7 +37,7 @@ function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", },0x42333031: { "name": "Sandship", "internalName": "SBossRoom", },0x53323030: { "name": "Din's Silent Realm", "internalName": "DinSilentRealm", },0x46323031: { "name": "Volcano Summit", "internalName": "", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", },0x42333031: { "name": "Sandship", "internalName": "SBossRoom", },0x53323030: { "name": "Din's Silent Realm", "internalName": "DinSilentRealm", },0x46323031: { "name": "Volcano Summit", "internalName": "", },0x44323031: { "name": "Fire Sanctuary", "internalName": "", },0x42323031: { "name": "Fire Sanctuary", "internalName": "FSBossRoom", }, } rpLookup = {} @@ -607,7 +607,7 @@ achievement(title = "Piercer", description = "Obtain the Bow.", type = "progress function arrowsInQuiver() => byte(0x00955ec7) & 0x7f function tentalusVictory() => bit2(0x00956ff3) -achievement(title = "Eyecupuncture", description = "Defeat Tentalus using ten arrows or fewer (new resurrections).", type = "missable", points = 10, +achievement(title = "Eyecupuncture", description = "Defeat Tentalus using ten arrows or fewer (no resurrections).", type = "missable", points = 10, trigger = BattleCheckpointStarted(Delta(animationId()) != 0xe && animationId() == 0xe && tentalusVictory() == 0, neverWhen = !IsInAreaByInternalName("SBossRoom")) && trigger_when(tentalusVictory() == 1) @@ -650,6 +650,32 @@ achievement(title = "Fireproof", description = "Obtain the Fireshield Earrings." trigger = WasBitflagJustSetInGame(fireshieldEarrings()) ) +function mogmaMitts() => bit1(0x00955e50) +achievement(title = "Tunnel Rat", description = "Obtain the Mogma Mitts.", points = 3, type = "progression", + trigger = WasBitflagJustSetInGame(mogmaMitts()) +) + +function guardianPotionTimeLeft() => word_be(0x0095a760) +function guardianPotionPlusTimeLeft() => word_be(0x0095a762) +function AnyGuardianPotionEffectIsActive() => guardianPotionTimeLeft() > 0 || guardianPotionPlusTimeLeft() > 0 +function ghirahimIIDefeated() => bit5(0x00956fc6) +function ghirahimIIHp() => word_be(0x00b6c10a) +achievement(title = "Bee Stings", type = "missable", points = 5, + description = "Defeat Ghirahim in the Fire Sanctuary without getting hit by his swords (no resurrections; no Guardian Potions).", + trigger = BattleCheckpointStarted(xCoordinate() == 0.0 && yCoordinate() == 150.0 && zCoordinate() == 900.0 && prior(animationId()) == 0x1bb + && animationId() == 0x12, + neverWhen = !IsInAreaByInternalName("FSBossRoom")) + && trigger_when(ghirahimIIDefeated() == 1) + && never(Delta(hp()) - hp() > 2) + && never(Delta(ghirahimIIDefeated()) == 1) +) + +function masterSword() => bit2(0x00955e48) +achievement(title = "The Predecessor", type = "progression", points = 3, + description = "Forge the Master Sword.", + trigger = WasBitflagJustSetInGame(masterSword()) +) + function songOfTheHero() => bit4(0x00955e5e) achievement(title = "The Melody of Legend", description = "Learn the Song of the Hero.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(songOfTheHero()) From 366ab9ba256ffe5e64573b15d4eff1df0c966963 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Fri, 24 Apr 2026 00:43:02 -0400 Subject: [PATCH 11/12] "Hylia's Chosen" --- ...egend of Zelda, The Skyward Sword.rascript | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index 6fca849..da41ef4 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -37,7 +37,7 @@ function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", },0x42333031: { "name": "Sandship", "internalName": "SBossRoom", },0x53323030: { "name": "Din's Silent Realm", "internalName": "DinSilentRealm", },0x46323031: { "name": "Volcano Summit", "internalName": "", },0x44323031: { "name": "Fire Sanctuary", "internalName": "", },0x42323031: { "name": "Fire Sanctuary", "internalName": "FSBossRoom", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", },0x42333031: { "name": "Sandship", "internalName": "SBossRoom", },0x53323030: { "name": "Din's Silent Realm", "internalName": "DinSilentRealm", },0x46323031: { "name": "Volcano Summit", "internalName": "", },0x44323031: { "name": "Fire Sanctuary", "internalName": "", },0x42323031: { "name": "Fire Sanctuary", "internalName": "FSBossRoom", },0x46343037: { "name": "Sealed Temple", "internalName": "GoTCutscene", },0x46343034: { "name": "Temple of Hylia", "internalName": "", }, } rpLookup = {} @@ -143,6 +143,11 @@ achievement(title = "Less Lethal", description = "Obtain the Slingshot.", points trigger = WasBitflagJustSetInGame(slingshot()) ) +function scattershot() => bit7(0x00955e50) +achievement(title = "A Bit More Lethal", description = "Upgrade the Slingshot to the Scattershot.", points = 3, + trigger = WasBitflagJustSetInGame(scattershot()) && slingshot() == 1 +) + function animationId() => word_be(0x00b76966) function JustClankedGivenNumberOfTimes(times) { @@ -305,6 +310,7 @@ function thrillDiggerRupeesCollected() => byte(0x00b6ffda) function thrillDiggerTotalCollectableRupees() => byte(0x00b6ffdb) function thrillDiggerUnpickedBombFlowers() => byte(0x00b6ffdc) function ThrillDiggerStarted() => once(thrillDiggerRupeesCollected() == 0 && Delta(thrillDiggerTotalCollectableRupees()) != thrillDiggerTotalCollectableRupees()) + && never(!IsInAreaByInternalName("EldinThrillDigger")) function ThrillDiggerJustRevealedBoard() => Delta(thrillDiggerUnpickedBombFlowers()) == 0 && thrillDiggerUnpickedBombFlowers() > 0 function ThrillDiggerJustEnded() => Delta(thrillDiggerUnpickedBombFlowers()) > 0 && thrillDiggerUnpickedBombFlowers() == 0 function ThrillDiggerChoseBeginner() => once(Delta(rupees()) - rupees() == 30) @@ -676,7 +682,26 @@ achievement(title = "The Predecessor", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(masterSword()) ) +function imprisonedIIHp() => byte(0x00b18f35) +function groosenatorState() => byte(0x00b69db3) +function playerSealPromptII() => bit2(0x00956f6b) +function ImprisonedIICheckpointReached() => BattleCheckpointStarted(once(ascii_string_equals(dialogueIdAddr(), "BOSS_07", 8)) + && IsInAreaByInternalName("SealedGroundsCutscene"), neverWhen = !IsInAreaByInternalName("SealedGroundsCutscene") + || ascii_string_equals(dialogueIdAddr(), "CF_47", 6)) // Nonstandard game over dialogue +achievement(title = "Nice Paperweight, Groose", description = "Defeat the Imprisoned II without firing more than two shots from the Groosenator (no resurrections).", points = 25, type = "missable", + trigger = ImprisonedIICheckpointReached() && never(playerSealPromptII() == 1) + && never(repeated(3, Delta(groosenatorState()) == 1 && groosenatorState() == 2)) + && trigger_when(imprisonedIIHp() == 0 && Delta(imprisonedIIHp()) == 1) +) + +function trueMasterSword() => bit7(0x00955e57) +achievement(title = "Hylia's Chosen", type = "progression", points = 3, + description = "Forge the True Master Sword.", + trigger = WasBitflagJustSetInGame(trueMasterSword()) +) + function songOfTheHero() => bit4(0x00955e5e) achievement(title = "The Melody of Legend", description = "Learn the Song of the Hero.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(songOfTheHero()) ) + From 6627c2faf4f4fcd0294182a79c3ad9289ac7de27 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Tue, 12 May 2026 20:43:39 -0400 Subject: [PATCH 12/12] Achievements up to Bilocyte and the Imprisoned III --- ...egend of Zelda, The Skyward Sword.rascript | 86 ++++++++++++++----- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript index da41ef4..65fb7f2 100644 --- a/RA Scripts/Legend of Zelda, The Skyward Sword.rascript +++ b/RA Scripts/Legend of Zelda, The Skyward Sword.rascript @@ -37,7 +37,7 @@ function lightingState() => byte(0x00593941) function dialogueIdAddr() => 0x005a88f4 areas = { -0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", },0x42333031: { "name": "Sandship", "internalName": "SBossRoom", },0x53323030: { "name": "Din's Silent Realm", "internalName": "DinSilentRealm", },0x46323031: { "name": "Volcano Summit", "internalName": "", },0x44323031: { "name": "Fire Sanctuary", "internalName": "", },0x42323031: { "name": "Fire Sanctuary", "internalName": "FSBossRoom", },0x46343037: { "name": "Sealed Temple", "internalName": "GoTCutscene", },0x46343034: { "name": "Temple of Hylia", "internalName": "", }, +0x46303031: { "name": "Knight Academy", "internalName": "", },0x46303039: { "name": "Sparring Hall", "internalName": "", },0x46303030: { "name": "Skyloft", "internalName": "", },0x44303030: { "name": "Waterfall", "internalName": "", },0x46303230: { "name": "The Sky", "internalName": "", },0x46303038: { "name": "Chamber of the Sword", "internalName": "", },0x46303231: { "name": "Sealed Grounds", "internalName": "", },0x46343031: { "name": "Sealed Grounds", "internalName": "SealedGroundsCutscene", },0x46343032: { "name": "Sealed Temple", "internalName": "", },0x46343030: { "name": "Sealed Grounds", "internalName": "BehindTheTemple", },0x46313030: { "name": "Faron Woods", "internalName": "FaronWoods", },0x46313031: { "name": "Deep Woods", "internalName": "", },0x44313030: { "name": "Skyview Temple", "internalName": "SkyviewTemple", },0x42313030: { "name": "Skyview Temple", "internalName": "STBossRoom", },0x00313031: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition", },0x46303032: { "name": "Beedle's Airshop", "internalName": "", },0x46323030: { "name": "Eldin Volcano", "internalName": "", },0x46323130: { "name": "Eldin Volcano", "internalName": "EldinVolcanoInterior", },0x46323131: { "name": "Eldin Volcano", "internalName": "EldinThrillDigger", },0x44323030: { "name": "Earth Temple", "internalName": "ETMain", },0x00323030: { "name": "Somewhere in the sky...", "internalName": "GameOverTransition", },0x42323030: { "name": "Earth Temple", "internalName": "ETBossRoom", },0x42323130: { "name": "Earth Spring", "internalName": "", },0x46333030: { "name": "Lanayru Desert", "internalName": "", },0x46303034: { "name": "Bazaar", "internalName": "", },0x44333030: { "name": "Lanayru Mining Facility", "internalName": "LMFMain", },0x42333030: { "name": "Lanayru Mining Facility", "internalName": "LMFBossRoom", },0x333030: { "name": "Somewhere in the sky...", "internalName": "SaveAndQuitTransition2", },0x46303037: { "name": "Piper's House", "internalName": "", },0x46303138: { "name": "Peatrice's House", "internalName": "", },0x46303036: { "name": "Kukiel's House", "internalName": "", },0x46303134: { "name": "Bertie's House", "internalName": "", },0x46303135: { "name": "Gondo's House", "internalName": "", },0x46303133: { "name": "Sparrot's House", "internalName": "", },0x46303233: { "name": "Inside the Thunderhead", "internalName": "", },0x46303130: { "name": "Isle of Songs", "internalName": "", },0x53313030: { "name": "Farore's Silent Realm", "internalName": "FaroreSilentRealm", },0x46313032: { "name": "Lake Floria", "internalName": "", },0x44313031: { "name": "Ancient Cistern", "internalName": "ACMain", },0x42313031: { "name": "Ancient Cistern", "internalName": "ACBossRoom", },0x53333030: { "name": "Nayru's Silent Realm", "internalName": "NayruSilentRealm", },0x46333033: { "name": "Lanayru Caves", "internalName": "", },0x46333031: { "name": "Lanayru Sand Sea", "internalName": "", },0x44333031: { "name": "Sandship", "internalName": "SMain", },0x42333031: { "name": "Sandship", "internalName": "SBossRoom", },0x53323030: { "name": "Din's Silent Realm", "internalName": "DinSilentRealm", },0x46323031: { "name": "Volcano Summit", "internalName": "", },0x44323031: { "name": "Fire Sanctuary", "internalName": "", },0x42323031: { "name": "Fire Sanctuary", "internalName": "FSBossRoom", },0x46343037: { "name": "Sealed Temple", "internalName": "GoTCutscene", },0x46343034: { "name": "Temple of Hylia", "internalName": "", },0x46303131: { "name": "The Lumpy Pumpkin", "internalName": "", },0x46313033: { "name": "Faron Woods", "internalName": "FaronWoodsFlooded", }, } rpLookup = {} @@ -174,15 +174,14 @@ function JustClankedGivenNumberOfTimes(times) return tally(times, triggers) } +spinIds = [ + 0x4f, // Horizontal, counterclockwise + 0x50, // Horizontal, clockwise + 0x51, // Vertical, downward + 0x52, // Vertical, upward +] function JustUsedSpinAttack() { - spinIds = [ - 0x4f, // Horizontal, counterclockwise - 0x50, // Horizontal, clockwise - 0x51, // Vertical, downward - 0x52, // Vertical, upward - ] - trigger = always_false() for id in spinIds @@ -277,10 +276,20 @@ achievement(title = "Heartthrob", description = "Have a total of 20 hearts' wort trigger = measured(maxHp() == 80, format = "percent") && Delta(maxHp() == 76) && WasValueJustChangedInGame(maxHp(), 76, 80) ) +function DialogueIdIs(id, includeNullTerminator = true, callback = x => x) +{ + offset = 0 + + if (includeNullTerminator) + { + offset = 1 + } + + return ascii_string_equals(dialogueIdAddr(), id, length(id) + offset, callback) +} + achievement(title = "Defenestration Shopping", description = "Leave Beedle's Airshop without buying anything.", points = 1, - trigger = once(ascii_string_equals(dialogueIdAddr(), "TERY_09", 8)) - && once(ascii_string_equals(dialogueIdAddr(), "TERY_10", 8)) - && IsInAreaByName("Skyloft") + trigger = once(DialogueIdIs("TERY_09")) && once(DialogueIdIs("TERY_10")) && IsInAreaByName("Skyloft") ) function bugNet() => bit0(0x00955e4c) @@ -300,8 +309,7 @@ achievement(title = "For Every Occasion", description = "Acquire all four Advent ) achievement(title = "I.O.U.", description = "Pick up a Rupoor.", points = 1, - trigger = ascii_string_equals(dialogueIdAddr(), "ITEM_034", 9) - && IsInAreaByInternalName("EldinThrillDigger") + trigger = DialogueIdIs("ITEM_034") && IsInAreaByInternalName("EldinThrillDigger") ) function rupees() => word_be(0x00955ec2) @@ -421,10 +429,8 @@ function ImprisonedToeWasJustAttacked() return trigger } -function ImprisonedICheckpointReached() => BattleCheckpointStarted(once(ascii_string_equals(dialogueIdAddr(), "CF_05", 6)) - && once(ascii_string_equals(dialogueIdAddr(), "CF_05", 6)) - && IsInAreaByInternalName("SealedGroundsCutscene"), neverWhen = !IsInAreaByInternalName("SealedGroundsCutscene") - || ascii_string_equals(dialogueIdAddr(), "CF_47", 6)) // Nonstandard game over dialogue +function ImprisonedICheckpointReached() => BattleCheckpointStarted(once(DialogueIdIs("CF_05")) && once(DialogueIdIs("CF_05")) + && IsInAreaByInternalName("SealedGroundsCutscene"), neverWhen = !IsInAreaByInternalName("SealedGroundsCutscene") || DialogueIdIs("CF_47")) // Nonstandard game over dialogue achievement(title = "What Am I, A Podiatrist?", description = "Defeat the Imprisoned I without attacking its toes (no resurrections).", points = 5, type = "missable", trigger = ImprisonedICheckpointReached() && never(playerSealPromptI() == 1) && never(ImprisonedToeWasJustAttacked()) @@ -685,9 +691,8 @@ achievement(title = "The Predecessor", type = "progression", points = 3, function imprisonedIIHp() => byte(0x00b18f35) function groosenatorState() => byte(0x00b69db3) function playerSealPromptII() => bit2(0x00956f6b) -function ImprisonedIICheckpointReached() => BattleCheckpointStarted(once(ascii_string_equals(dialogueIdAddr(), "BOSS_07", 8)) - && IsInAreaByInternalName("SealedGroundsCutscene"), neverWhen = !IsInAreaByInternalName("SealedGroundsCutscene") - || ascii_string_equals(dialogueIdAddr(), "CF_47", 6)) // Nonstandard game over dialogue +function ImprisonedIICheckpointReached() => BattleCheckpointStarted(once(DialogueIdIs("BOSS_07")) + && IsInAreaByInternalName("SealedGroundsCutscene"), neverWhen = !IsInAreaByInternalName("SealedGroundsCutscene") || DialogueIdIs("CF_47")) // Nonstandard game over dialogue achievement(title = "Nice Paperweight, Groose", description = "Defeat the Imprisoned II without firing more than two shots from the Groosenator (no resurrections).", points = 25, type = "missable", trigger = ImprisonedIICheckpointReached() && never(playerSealPromptII() == 1) && never(repeated(3, Delta(groosenatorState()) == 1 && groosenatorState() == 2)) @@ -700,8 +705,47 @@ achievement(title = "Hylia's Chosen", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(trueMasterSword()) ) +function targetsScore() => byte(0x00af0f63) +function targetsTimeRemaining() => byte(0x00af1aeb) +achievement(title = "Certified Pilot", type = "missable", description = "Complete Instructor Owlan's Spiral Charge test within 90 seconds.", points = 10, + trigger = once(DialogueIdIs("SHINA_30")) + && trigger_when(Delta(targetsScore()) == 9 && targetsScore() == 10) && targetsTimeRemaining() >= 30 + && never(!IsInAreaByName("The Sky")) +) + +function bilocyteHp() => word_be(0x00b66c6e) +usedAttackDuringPhase3Trigger = always_false() + +for id in attackIds +{ + usedAttackDuringPhase3Trigger = usedAttackDuringPhase3Trigger || once(bilocyteHp() == 0x124) && JustUsedAttack(id) +} + +for id in spinIds +{ + usedAttackDuringPhase3Trigger = usedAttackDuringPhase3Trigger || once(bilocyteHp() == 0x124) && JustUsedAttack(id) +} + +achievement(title = "So Uncivilized", type = "missable", description = "Defeat Bilocyte without using your sword during its third phase (no resurrections).", points = 10, + trigger = BattleCheckpointStarted(once(DialogueIdIs("BOSS_08_", false) && !DialogueIdIs("BOSS_08_", false, x => Delta(x))) && IsInAreaByName("Inside the Thunderhead"), + neverWhen = !IsInAreaByName("Inside the Thunderhead")) + && trigger_when(CreateChain([ bilocyteHp() == 0x124, bilocyteHp() == 0 ], x => once(x))) + && never(usedAttackDuringPhase3Trigger) +) + +function imprisonedIIIHp() => byte(0x00b16c3d) +function groosenatorState() => byte(0x00b69db3) +function playerSealPromptIII() => bit3(0x00956f6b) +function ImprisonedIIICheckpointReached() => BattleCheckpointStarted(once(DialogueIdIs("BOSS_09") && playerSealPromptIII() == 0 && playerSealPromptII() == 1) + && IsInAreaByInternalName("SealedGroundsCutscene"), neverWhen = !IsInAreaByInternalName("SealedGroundsCutscene") || DialogueIdIs("CF_47")) // Nonstandard game over dialogue +achievement(title = "For Display Only", description = "Defeat the Imprisoned III without firing a single bomb from the Groosenator (no resurrections).", + points = 10, type = "missable", + trigger = ImprisonedIIICheckpointReached() && never(playerSealPromptIII() == 1) + && never(Delta(groosenatorState()) == 1 && groosenatorState() == 2) + && trigger_when(imprisonedIIIHp() == 0 && Delta(imprisonedIIIHp()) == 1) +) + function songOfTheHero() => bit4(0x00955e5e) achievement(title = "The Melody of Legend", description = "Learn the Song of the Hero.", type = "progression", points = 3, trigger = WasBitflagJustSetInGame(songOfTheHero()) ) -