From 28f26d216962d3b13a152d82c9849b1508f368b3 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Thu, 23 Dec 2021 12:44:53 -0500 Subject: [PATCH 01/10] Removed the three achievements I plan to demote and added "Pharmacophobia," one of the three achievements to replace it --- RA Scripts/Legend of Dragoon, The.rascript | 59 ++++++++++++++-------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index 7f68ebc..8e6b76d 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -300,6 +300,44 @@ achievement( trigger = word(0x052C30) == 0x0032 && bit5(0x0BAD90) == 0x1 && prev(bit5(0x0BAD90)) == 0x0 ) +function urobolusHp() => word(0x1adf44) +function itemsInInventory() => byte(0x0BADAE) +function ItemCountDecreased() => Delta(itemsInInventory()) > itemsInInventory() +function characterObjectWidth() => 0x2c + +function Dart() => 0 +function Lavitz() => 1 +function Shana() => 2 + +function GetCharacterById(id) +{ + characterArrayBaseAddr = 0x0baef4 + addr = characterArrayBaseAddr + id * characterObjectWidth() + return { + "exp": dword(addr), + "statusFlags": byte(addr + 4), + "hp": word(addr + 8), + "level": byte(addr + 18), + "accessoryId": byte(addr + 24) + } +} + +function CharacterWithIdHasItemWithIdEquipped(charId, accessoryId) +{ + character = GetCharacterById(charId) + return character["accessoryId"] == accessoryId +} + +function poisonGuardId() => 0x67 +achievement(title = "Pharmacophobia", points = 5, + description = "Defeat the Urobolus without using items and without equipping any Poison Guards.", + trigger = mapId() == 0x35 && enemyId() == 0x19e && EnteredBattleOnce() && never(!IsInBattle()) + && trigger_when(once(Delta(urobolusHp()) > 0 && urobolusHp() == 0) && repeated(290, urobolusHp() == 0)) + && never(ItemCountDecreased()) && never(CharacterWithIdHasItemWithIdEquipped(Dart(), poisonGuardId())) + && never(CharacterWithIdHasItemWithIdEquipped(Lavitz(), poisonGuardId())) + && never(CharacterWithIdHasItemWithIdEquipped(Shana(), poisonGuardId())) +) + achievement( title = "No Ordinary Keepsake", description = "Awaken the Dragoon Spirit of the Red-Eyed Dragon.", points = 5, id = 94790, badge = "106752", published = "1/15/2020 11:23:24 PM", modified = "2/3/2020 10:16:19 PM", @@ -765,27 +803,6 @@ achievement( trigger = prev(word(0x052C30)) == 0x023C && word(0x052C30) == 0x0210 ) -achievement( - title = "Protectionist Parliamentarian", description = "Repeal the law permitting use of the shop next to the Law Factory in Zenebatos.", points = 1, - id = 96106, badge = "106738", published = "1/26/2020 7:52:18 PM", modified = "2/3/2020 2:50:34 AM", - trigger = word(0x052C30) == 0x0218 && prev(bit0(0x0BAD68)) == 0x1 && bit0(0x0BAD68) == 0x0 && bit0(0x0BACDA) == 0x1 && - prev(bit0(0x0BACDA)) == 0x0 -) - -achievement( - title = "Trespassers Will Be Ignored", description = "Prohibit the Zenebatos guards from arresting you by changing the law.", points = 1, - id = 96108, badge = "106738", published = "1/26/2020 8:05:07 PM", modified = "2/3/2020 2:50:37 AM", - trigger = word(0x052C30) == 0x0218 && prev(bit0(0x0BAD68)) == 0x1 && bit0(0x0BAD68) == 0x0 && bit5(0x0BACD9) == 0x1 && - prev(bit5(0x0BACD9)) == 0x0 -) - -achievement( - title = "No Lines, No Waiting", description = "Repeal the law in Zenebatos requiring the need to queue at the Legislation Center.", points = 1, - id = 96111, badge = "106738", published = "1/26/2020 8:13:46 PM", modified = "2/3/2020 2:50:30 AM", - trigger = word(0x052C30) == 0x0218 && prev(bit0(0x0BAD68)) == 0x1 && bit0(0x0BAD68) == 0x0 && bit4(0x0BACD9) == 0x1 && - prev(bit4(0x0BACD9)) == 0x0 -) - achievement( title = "Jury Nullification", description = "With Meru and Miranda in your party, defeat Kubila, Selebus, and Vector simultaneously.", points = 10, id = 98143, badge = "108080", published = "2/11/2020 1:16:21 AM", modified = "2/25/2020 10:08:04 PM", From 5e4efdd77ece2a026f091e6db1fae1fe72803b9e Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Thu, 23 Dec 2021 23:15:33 -0500 Subject: [PATCH 02/10] Added "No Revenge Like Overkill" and "Electrical Paralysis" --- RA Scripts/Legend of Dragoon, The.rascript | 134 ++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index 8e6b76d..223e2b9 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -329,7 +329,7 @@ function CharacterWithIdHasItemWithIdEquipped(charId, accessoryId) } function poisonGuardId() => 0x67 -achievement(title = "Pharmacophobia", points = 5, +achievement(title = "Pharmacophobia", points = 5, id = 189207, badge = "209992", description = "Defeat the Urobolus without using items and without equipping any Poison Guards.", trigger = mapId() == 0x35 && enemyId() == 0x19e && EnteredBattleOnce() && never(!IsInBattle()) && trigger_when(once(Delta(urobolusHp()) > 0 && urobolusHp() == 0) && repeated(290, urobolusHp() == 0)) @@ -359,6 +359,129 @@ achievement( unless(byte(0x0BAC58) == 0x03) && never(word(0x1AC50C) == 0x0000) && never(word(0x1AC184) == 0x0000))) ) +function playerSlot1Addr() => 0x0bc1d8 +function playerSlot2Addr() => 0x0bc1dc +function playerSlot3Addr() => 0x0bc1e0 +function enemySlot1Addr() => 0x0bc1ec +function enemySlot2Addr() => 0x0bc1f0 +function garbagePointer() => 0xbc0c0 + +function CombatantInSlotAddrIsLoaded(addr) => Delta(tbyte(addr)) != garbagePointer() +function GetCombatantInGivenSlotAddr(addr) +{ + return { + "hp": word(tbyte(addr) + 0x108), + "mp": word(tbyte(addr) + 0x10c) + } +} + +function CombatantInSlotAddrWasJustDefeated(addr) +{ + combatant = GetCombatantInGivenSlotAddr(addr) + return CombatantInSlotAddrIsLoaded(addr) && Delta(combatant["hp"]) > 0 && combatant["hp"] == 0 +} + +function AllCombatantsInGivenSlotAddrsWereJustDefeated(slots, useTrigger = true, deferTime = 0) +{ + allGivenCombatantsDefeated = always_true() + anyGivenCombatantWasJustDefeated = always_false() + for slot in slots + { + combatant = GetCombatantInGivenSlotAddr(slot) + allGivenCombatantsDefeated = allGivenCombatantsDefeated && combatant["hp"] == 0 && CombatantInSlotAddrIsLoaded(slot) + wasJustDefeated = CombatantInSlotAddrWasJustDefeated(slot) + + if (useTrigger == true) + { + wasJustDefeated = trigger_when(wasJustDefeated) + } + + anyGivenCombatantWasJustDefeated = anyGivenCombatantWasJustDefeated || wasJustDefeated + } + + if (useTrigger == true) + { + allGivenCombatantsDefeated = trigger_when(allGivenCombatantsDefeated) + } + + return repeated(deferTime, allGivenCombatantsDefeated) && anyGivenCombatantWasJustDefeated +} + +function slot1DragoonTurnsRemaining() => byte(0x06e62c) +function slot2DragoonTurnsRemaining() => byte(0x06e630) +function slot3DragoonTurnsRemaining() => byte(0x06e634) + +function DragoonTurnConsumedBySlot(slotId) +{ + if (slotId == 1) + { + return Delta(slot1DragoonTurnsRemaining()) > slot1DragoonTurnsRemaining() + } + else if (slotId == 2) + { + return Delta(slot2DragoonTurnsRemaining()) > slot2DragoonTurnsRemaining() + } + else + { + return Delta(slot3DragoonTurnsRemaining()) > slot3DragoonTurnsRemaining() + } +} + +function turnCounter() => dword(0x0bac80) +function TurnConsumed() => Delta(turnCounter()) < turnCounter() + +function GetPlayerAddrFromSlot(slotId) +{ + if (slotId == 1) + { + return playerSlot1Addr() + } + else if (slotId == 2) + { + return playerSlot2Addr() + } + else + { + return playerSlot3Addr() + } +} + +function PlayerUsedMagicThisTurn() +{ + trigger = always_false() + for slot in range(1, 3) + { + slotAddr = GetPlayerAddrFromSlot(slot) + combatant = GetCombatantInGivenSlotAddr(slotAddr) + // todo: use `trigger_when()` around the `once()` statement when https://github.com/Jamiras/RATools/issues/272 is addressed. + trigger = trigger || unless(!CombatantInSlotAddrIsLoaded(slotAddr)) && once(Delta(combatant["mp"]) > combatant["mp"] && never(TurnConsumed())) + } + + return trigger +} + +function PlayerJustUsedMagic() +{ + trigger = always_false() + for slot in range(1, 3) + { + slotAddr = GetPlayerAddrFromSlot(slot) + combatant = GetCombatantInGivenSlotAddr(slotAddr) + // todo: use `trigger_when()` around the `once()` statement when https://github.com/Jamiras/RATools/issues/272 is addressed. + trigger = trigger || CombatantInSlotAddrIsLoaded(slotAddr) && once(Delta(combatant["mp"]) > combatant["mp"]) + } + + return trigger +} + +function Feyrbrand() => enemySlot1Addr() +function Greham() => enemySlot2Addr() +achievement(title = "No Revenge Like Overkill", description = "Finish the battle against Greham and Feyrbrand with a Dragoon spell.", points = 10, + id = 189209, badge = "209994", + trigger = mapId() == 0x290 && enemyId() == 0x189 && EnteredBattleOnce() && never(!IsInBattle()) + && AllCombatantsInGivenSlotAddrsWereJustDefeated([ Feyrbrand(), Greham() ], true) && PlayerUsedMagicThisTurn() +) + achievement( title = "You Killed My Father. Prepare to Die.", description = "Acquire the Dragoon Spirit of the Jade Dragon.", points = 5, id = 94793, badge = "106749", published = "1/15/2020 11:26:00 PM", modified = "2/3/2020 2:19:05 AM", @@ -473,6 +596,15 @@ achievement( trigger = word(0x0BB0F8) == 0x0183 && word(0x0BC95C) == 0x07D0 ) +function Doel() => enemySlot1Addr() +function DragoonDoel() => enemySlot2Addr() +achievement(title = "Electrical Paralysis", points = 5, id = 189208, badge = "209993", + description = "Defeat Emperor Doel without using Dragoon magic.", + trigger = mapId() == 0x294 && enemyId() == 0x186 && EnteredBattleOnce() && never(!IsInBattle()) + && AllCombatantsInGivenSlotAddrsWereJustDefeated([ Doel(), DragoonDoel() ], true) + && never(PlayerJustUsedMagic()) +) + // To make sure the achievement doesn't trigger during a game over while still letting it trigger during the // transition from the cutscene to the results screen, we're checking to make sure that the map ID changes // for about a half second before triggering--because, OF COURSE, the map ID changes to the next one for From 828cdc6bf801dcaeb0d61007b67014958d620fbd Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Mon, 3 Jan 2022 20:32:41 -0500 Subject: [PATCH 03/10] Reintroduced `trigger_when()` and removed an outdated todo --- RA Scripts/Legend of Dragoon, The.rascript | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index 223e2b9..b4dbb81 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -453,8 +453,7 @@ function PlayerUsedMagicThisTurn() { slotAddr = GetPlayerAddrFromSlot(slot) combatant = GetCombatantInGivenSlotAddr(slotAddr) - // todo: use `trigger_when()` around the `once()` statement when https://github.com/Jamiras/RATools/issues/272 is addressed. - trigger = trigger || unless(!CombatantInSlotAddrIsLoaded(slotAddr)) && once(Delta(combatant["mp"]) > combatant["mp"] && never(TurnConsumed())) + trigger = trigger || unless(!CombatantInSlotAddrIsLoaded(slotAddr)) && trigger_when(once(Delta(combatant["mp"]) > combatant["mp"] && never(TurnConsumed()))) } return trigger From 0361bca0dcb4bd37d1124f7463d4950742cc33cf Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Thu, 3 Feb 2022 22:47:35 -0500 Subject: [PATCH 04/10] "Monkeyball Master" fix Fixed an issue where the memory address used to keep track of the player's score would change depending on the core being used. --- RA Scripts/Legend of Dragoon, The.rascript | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index b4dbb81..81073d8 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -366,7 +366,7 @@ function enemySlot1Addr() => 0x0bc1ec function enemySlot2Addr() => 0x0bc1f0 function garbagePointer() => 0xbc0c0 -function CombatantInSlotAddrIsLoaded(addr) => Delta(tbyte(addr)) != garbagePointer() +function PointerIsValid(addr) => Delta(tbyte(addr)) != garbagePointer() function GetCombatantInGivenSlotAddr(addr) { return { @@ -378,7 +378,7 @@ function GetCombatantInGivenSlotAddr(addr) function CombatantInSlotAddrWasJustDefeated(addr) { combatant = GetCombatantInGivenSlotAddr(addr) - return CombatantInSlotAddrIsLoaded(addr) && Delta(combatant["hp"]) > 0 && combatant["hp"] == 0 + return PointerIsValid(addr) && Delta(combatant["hp"]) > 0 && combatant["hp"] == 0 } function AllCombatantsInGivenSlotAddrsWereJustDefeated(slots, useTrigger = true, deferTime = 0) @@ -388,7 +388,7 @@ function AllCombatantsInGivenSlotAddrsWereJustDefeated(slots, useTrigger = true, for slot in slots { combatant = GetCombatantInGivenSlotAddr(slot) - allGivenCombatantsDefeated = allGivenCombatantsDefeated && combatant["hp"] == 0 && CombatantInSlotAddrIsLoaded(slot) + allGivenCombatantsDefeated = allGivenCombatantsDefeated && combatant["hp"] == 0 && PointerIsValid(slot) wasJustDefeated = CombatantInSlotAddrWasJustDefeated(slot) if (useTrigger == true) @@ -453,7 +453,7 @@ function PlayerUsedMagicThisTurn() { slotAddr = GetPlayerAddrFromSlot(slot) combatant = GetCombatantInGivenSlotAddr(slotAddr) - trigger = trigger || unless(!CombatantInSlotAddrIsLoaded(slotAddr)) && trigger_when(once(Delta(combatant["mp"]) > combatant["mp"] && never(TurnConsumed()))) + trigger = trigger || unless(!PointerIsValid(slotAddr)) && trigger_when(once(Delta(combatant["mp"]) > combatant["mp"] && never(TurnConsumed()))) } return trigger @@ -467,7 +467,7 @@ function PlayerJustUsedMagic() slotAddr = GetPlayerAddrFromSlot(slot) combatant = GetCombatantInGivenSlotAddr(slotAddr) // todo: use `trigger_when()` around the `once()` statement when https://github.com/Jamiras/RATools/issues/272 is addressed. - trigger = trigger || CombatantInSlotAddrIsLoaded(slotAddr) && once(Delta(combatant["mp"]) > combatant["mp"]) + trigger = trigger || PointerIsValid(slotAddr) && once(Delta(combatant["mp"]) > combatant["mp"]) } return trigger @@ -528,14 +528,14 @@ achievement( word(0x052C30) == 0x027E ) +function monsterConquestAddr() => tbyte(0x0bc1e8) +function monsterConquestScore() => dword(monsterConquestAddr() + 0x7c) achievement( title = "Monkeyball Master", description = "Get a score of 100 or more in the Monster Conquest Game Stand minigame.", points = 5, id = 94798, badge = "106744", published = "1/15/2020 11:26:27 PM", modified = "2/4/2020 10:54:22 PM", - trigger = word(0x052C30) == 0x0098 && never(word(0x052C30) != 0x0098) && - ((dword(0x195DD4) >= 0x00000064 && dword(0x195DD4) != 0xFFFFFFFF && once(word(0x195DD4) == 0xFFFF) && - word(0x0BAC60) == 0x0000) || - (word(0x0BAC60) > 0x0000 && dword(0x195054) >= 0x00000064 && dword(0x195054) != 0xFFFFFFFF && - once(word(0x195054) == 0xFFFF))) + trigger = mapId() == 0x98 && never(mapId() != 0x98) && + never(!PointerIsValid(monsterConquestAddr())) && monsterConquestScore() >= 100 && monsterConquestScore() != 0xffffffff + && once(monsterConquestScore() == 0xffffffff) ) achievement( From 0605c4c8a418ffbbb3d666d907009eb83ca81ad6 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Sat, 30 Sep 2023 21:35:55 -0400 Subject: [PATCH 05/10] Refactored "Ful, Losei Dovahkiin?" --- RA Scripts/Legend of Dragoon, The.rascript | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index 81073d8..476f8e4 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -385,26 +385,31 @@ function AllCombatantsInGivenSlotAddrsWereJustDefeated(slots, useTrigger = true, { allGivenCombatantsDefeated = always_true() anyGivenCombatantWasJustDefeated = always_false() + ret = always_false() for slot in slots { combatant = GetCombatantInGivenSlotAddr(slot) allGivenCombatantsDefeated = allGivenCombatantsDefeated && combatant["hp"] == 0 && PointerIsValid(slot) wasJustDefeated = CombatantInSlotAddrWasJustDefeated(slot) - if (useTrigger == true) - { - wasJustDefeated = trigger_when(wasJustDefeated) - } - anyGivenCombatantWasJustDefeated = anyGivenCombatantWasJustDefeated || wasJustDefeated } + if (deferTime > 0) + { + ret = repeated(deferTime, allGivenCombatantsDefeated) && anyGivenCombatantWasJustDefeated + } + else + { + ret = allGivenCombatantsDefeated && anyGivenCombatantWasJustDefeated + } + if (useTrigger == true) { - allGivenCombatantsDefeated = trigger_when(allGivenCombatantsDefeated) + ret = trigger_when(ret) } - return repeated(deferTime, allGivenCombatantsDefeated) && anyGivenCombatantWasJustDefeated + return ret } function slot1DragoonTurnsRemaining() => byte(0x06e62c) @@ -987,12 +992,12 @@ achievement( (word(0x0CCDEC) == 0x0000 && word(0x0BC95C) == 0x1770 && word(0x0BC920) == 0x012C)) ) +function DivineDragonSpirit() => enemySlot2Addr() achievement( title = "Ful, Losei Dovahkiin?", description = "Defeat the spirit of the Divine Dragon in Mayfil.", points = 25, id = 96124, badge = "106736", published = "1/26/2020 9:17:07 PM", modified = "2/3/2020 2:53:03 AM", - trigger = word(0x0BB0F8) == 0x01BF && word(0x052C30) == 0x0222 && word(0x0BB0F4) == 0x0044 && - ((prev(word(0x0BC95C)) == 0x1F40 && word(0x0BC95C) == 0x0000) || - (word(0x0CCDEC) == 0x0000 && word(0x0BC95C) == 0x1F40 && word(0x0BC920) == 0x0190)) + trigger = mapId() == 0x0222 && enemyId() == 0x01BF && EnteredBattleOnce() && never(!IsInBattle()) + && AllCombatantsInGivenSlotAddrsWereJustDefeated([ DivineDragonSpirit() ], false) ) achievement( From 201bda070fa63f55952b30c3f1003360bf5e0cfd Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Mon, 27 Nov 2023 18:14:54 -0500 Subject: [PATCH 06/10] Hack fix for "Confidence or Recklessness" Will still need to be revised later, per the new comment. --- RA Scripts/Legend of Dragoon, The.rascript | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index 476f8e4..f427b1e 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -29,6 +29,7 @@ function EnteredBattleOnce() => once(Delta(battleMarker()) != battleMarker() && // 0x8005 = world map(?) function battleMarker() => word(0xccdec) function IsInBattle() => battleMarker() == 0x1021 +function JustLeftBattle() => !IsInBattle() && Delta(battleMarker()) == 0x1021 // $0badae: Total items in inventory function itemsInInventory() => byte(0x0badae) @@ -886,12 +887,23 @@ achievement( (word(0x1AD824) == 0x0000 && prev(word(0x1AD824)) == 0x0003)) ) +function slot1DragoonTurnsRemaining() => byte(0x06E62C) +function slot2DragoonTurnsRemaining() => byte(0x06E630) +function slot3DragoonTurnsRemaining() => byte(0x06E634) +function slotIdOfDragoonSpecial() => byte(0x06E648) +function DragoonLloyd() => enemySlot1Addr() + +// This achievement needs a rework. We need to ensure the player actually spends at least six turns in a Dragoon Special. The player can simply wait to pop the special until the end, which +// was not intended. +// Additionally, we need to specify 0 HP instead of defeating him because Lloyd will always do an AoE attack when he's brought to 0 HP. This will have to be specified until I can revise this +// further and trigger the achievement after the cutscene like before. achievement( - title = "Confidence, or Recklessness?", description = "Defeat Lloyd after triggering at least a second-level Dragoon Special at least once.", points = 10, + title = "Confidence, or Recklessness?", description = "Bring Lloyd down to 0 HP after triggering at least a second-level Dragoon Special at least once.", points = 10, id = 98127, badge = "108055", published = "2/9/2020 9:25:08 PM", modified = "2/13/2020 10:38:38 PM", - trigger = word(0x0BC95C) == 0x2EE0 && once(byte(0x06E62C) > 0x01 && byte(0x06E630) > 0x01 && byte(0x06E634) > 0x01 - && prev(byte(0x06E648)) == 0xFF && byte(0x06E648) != 0xFF) && - never(prev(word(0x0CCDEC)) != 0x1021 && word(0x0CCDEC) == 0x1021) && word(0x0BB0F8) == 0x0188 + trigger = trigger_when(once(slot1DragoonTurnsRemaining() > 1 && slot2DragoonTurnsRemaining() > 1 && slot3DragoonTurnsRemaining() > 1 + && Delta(slotIdOfDragoonSpecial()) == 0xFF && slotIdOfDragoonSpecial() != 0xFF)) + && never(JustLeftBattle()) && enemyId() == 0x0188 + && AllCombatantsInGivenSlotAddrsWereJustDefeated([ DragoonLloyd() ], true) ) achievement( From 99d1a68e681e4eac7ceac819b9e50e192fc5888b Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Thu, 11 Sep 2025 19:49:52 -0400 Subject: [PATCH 07/10] "Muggles Do It Better" bugfix Fixed an issue where the achievement could be earned after a Dragoon Special ends with no other Dragoon on the field. --- RA Scripts/Legend of Dragoon, The.rascript | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index f427b1e..fea39e2 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -754,11 +754,12 @@ achievement( achievement( title = "Muggles Do It Better", description = "Defeat Lenus and Regole without using Dragoon transformations.", points = 5, - id = 98008, badge = "108035", published = "2/8/2020 11:03:41 PM", modified = "2/13/2020 10:38:26 PM", - trigger = once(prev(byte(0x06E648)) != 0xFF && byte(0x06E648) == 0xFF) && word(0x0CCDEC) == 0x1021 && + id = 98008, badge = "108035", published = "2/8/2020 11:03:41 PM", modified = "2/13/2020 10:38:26 PM", type = "missable", + trigger = once(EnteredBattleOnce() && prev(byte(0x06E648)) != 0xFF && byte(0x06E648) == 0xFF) && word(0x0CCDEC) == 0x1021 && ((never(byte(0x06E62C) > 0x00) && never(byte(0x06E630) > 0x00) && never(byte(0x06E634) > 0x00) && unless(byte(0x06E62C) == 0x28) && unless(byte(0x06E630) == 0x2C) && unless(byte(0x06E634) == 0x30) && always_false()) || (prev(word(0x0BC95C)) == 0x1B58 && word(0x0BC95C) == 0x0000)) + && never(!IsInBattle()) ) achievement( From 5bf57fce1f425bb8c09ab47c3a63d2465aea2ba7 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Thu, 11 Sep 2025 19:57:20 -0400 Subject: [PATCH 08/10] Addendum from previous "Muggles Do It Better" fix --- RA Scripts/Legend of Dragoon, The.rascript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index fea39e2..1c4c15b 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -755,7 +755,7 @@ achievement( achievement( title = "Muggles Do It Better", description = "Defeat Lenus and Regole without using Dragoon transformations.", points = 5, id = 98008, badge = "108035", published = "2/8/2020 11:03:41 PM", modified = "2/13/2020 10:38:26 PM", type = "missable", - trigger = once(EnteredBattleOnce() && prev(byte(0x06E648)) != 0xFF && byte(0x06E648) == 0xFF) && word(0x0CCDEC) == 0x1021 && + trigger = EnteredBattleOnce() && word(0x0CCDEC) == 0x1021 && ((never(byte(0x06E62C) > 0x00) && never(byte(0x06E630) > 0x00) && never(byte(0x06E634) > 0x00) && unless(byte(0x06E62C) == 0x28) && unless(byte(0x06E630) == 0x2C) && unless(byte(0x06E634) == 0x30) && always_false()) || (prev(word(0x0BC95C)) == 0x1B58 && word(0x0BC95C) == 0x0000)) From 69614eccdea331776390bf177561f734cd341b4c Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Thu, 11 Sep 2025 21:34:08 -0400 Subject: [PATCH 09/10] "Leave No Trace" bugfix Fixed "Leave No Trace" so that it won't trigger when Haschel and Miranda are in the party. --- RA Scripts/Legend of Dragoon, The.rascript | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index 1c4c15b..bb02ce6 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -305,10 +305,21 @@ function urobolusHp() => word(0x1adf44) function itemsInInventory() => byte(0x0BADAE) function ItemCountDecreased() => Delta(itemsInInventory()) > itemsInInventory() function characterObjectWidth() => 0x2c +function characterSlot1Id() => byte(0x0bac50) +function characterSlot2Id() => byte(0x0bac54) +function characterSlot3Id() => byte(0x0bac58) function Dart() => 0 function Lavitz() => 1 function Shana() => 2 +function Haschel() => 4 +function Kongol() => 7 +function Miranda() => 8 + +function CharacterIsInParty(id) +{ + return characterSlot1Id() == id || characterSlot2Id() == id || characterSlot3Id() == id +} function GetCharacterById(id) { @@ -382,6 +393,12 @@ function CombatantInSlotAddrWasJustDefeated(addr) return PointerIsValid(addr) && Delta(combatant["hp"]) > 0 && combatant["hp"] == 0 } +function CombatantInSlotAddrWasAlreadyDefeated(addr) +{ + combatant = GetCombatantInGivenSlotAddr(addr) + return PointerIsValid(addr) && Delta(combatant["hp"]) == 0 && combatant["hp"] == 0 +} + function AllCombatantsInGivenSlotAddrsWereJustDefeated(slots, useTrigger = true, deferTime = 0) { allGivenCombatantsDefeated = always_true() @@ -1059,9 +1076,10 @@ achievement( achievement( title = "Leave No Trace", description = "With Kongol and Haschel in your party, destroy the arm of the Super Virage on the Moon before either its head or its body.", points = 5, - id = 98230, badge = "108084", published = "2/12/2020 12:39:52 AM", modified = "2/13/2020 10:39:00 PM", + id = 98230, badge = "108084", published = "2/12/2020 12:39:52 AM", modified = "2/13/2020 10:39:00 PM", type = "missable", trigger = word(0x0BC95C) == 0x3A98 && word(0x0BB0F8) == 0x019B && never(word(0x052C30) != 0x02DD) && (always_false() || (once(prev(word(0x0BAC80)) != word(0x0BAC80)) && unless(word(0x1AB01C) > 0x0000))) + && never(!CharacterIsInParty(Haschel())) && never(!CharacterIsInParty(Kongol())) ) achievement( From e6d54fa8a3c36704401f2314118cd7a81e8446e8 Mon Sep 17 00:00:00 2001 From: MagmarFire Date: Tue, 23 Sep 2025 19:47:07 -0400 Subject: [PATCH 10/10] Refactored "Magician's Hat-Trick" --- RA Scripts/Legend of Dragoon, The.rascript | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/RA Scripts/Legend of Dragoon, The.rascript b/RA Scripts/Legend of Dragoon, The.rascript index bb02ce6..6c32276 100644 --- a/RA Scripts/Legend of Dragoon, The.rascript +++ b/RA Scripts/Legend of Dragoon, The.rascript @@ -313,6 +313,7 @@ function Dart() => 0 function Lavitz() => 1 function Shana() => 2 function Haschel() => 4 +function Albert() => 5 function Kongol() => 7 function Miranda() => 8 @@ -376,6 +377,7 @@ function playerSlot2Addr() => 0x0bc1dc function playerSlot3Addr() => 0x0bc1e0 function enemySlot1Addr() => 0x0bc1ec function enemySlot2Addr() => 0x0bc1f0 +function enemySlot3Addr() => 0x0bc1f4 function garbagePointer() => 0xbc0c0 function PointerIsValid(addr) => Delta(tbyte(addr)) != garbagePointer() @@ -749,9 +751,10 @@ achievement( achievement( title = "Magician's Hat-Trick", description = "With Albert and Kongol in your party, defeat the Magician Bogy Trio simultaneously.", points = 5, id = 97752, badge = "107878", published = "2/7/2020 5:10:49 AM", modified = "2/13/2020 10:38:15 PM", - trigger = word(0x0BB0F8) == 0x01E9 && word(0x052C30) == 0x0125 && word(0x0CCDEC) == 0x1021 && - prev(word(0x1AD694)) > 0x0000 && word(0x1AD694) == 0x0000 && prev(word(0x1AD30C)) > 0x0000 && word(0x1AD30C) == 0x0000 && - prev(word(0x1ACF84)) > 0x0000 && word(0x1ACF84) == 0x0000 + trigger = enemyId() == 0x01E9 && mapId() == 0x0125 + && EnteredBattleOnce() && never(!IsInBattle()) + && CombatantInSlotAddrWasJustDefeated(enemySlot1Addr()) && CombatantInSlotAddrWasJustDefeated(enemySlot2Addr()) && CombatantInSlotAddrWasJustDefeated(enemySlot3Addr()) + && never(!CharacterIsInParty(Albert())) && never(!CharacterIsInParty(Kongol())) ) achievement(