From f002db2929227c104e0451ef8096ecc1095f8b0b Mon Sep 17 00:00:00 2001 From: johnjohto Date: Mon, 3 Aug 2026 11:22:40 -0400 Subject: [PATCH] Show only one branch of the gated flavor talks (#719) --- .../scripts/flavor/cerulean_trashed_house.lua | 4 +- data/scripts/flavor/lavender_mart.lua | 4 +- data/scripts/flavor/mr_fujis_house.lua | 8 +- data/scripts/flavor/route_16_gate_1f.lua | 4 +- data/scripts/flavor/route_18_gate_1f.lua | 4 +- data/scripts/flavor/silph_co_10f.lua | 4 +- data/scripts/flavor/silph_co_3f.lua | 4 +- data/scripts/flavor/silph_co_4f.lua | 4 +- data/scripts/flavor/silph_co_5f.lua | 4 +- data/scripts/flavor/silph_co_6f.lua | 20 +-- data/scripts/flavor/silph_co_7f.lua | 12 +- data/scripts/flavor/silph_co_8f.lua | 4 +- tests/parity_flavor_talk_branches.lua | 130 ++++++++++++++++++ 13 files changed, 168 insertions(+), 38 deletions(-) create mode 100644 tests/parity_flavor_talk_branches.lua diff --git a/data/scripts/flavor/cerulean_trashed_house.lua b/data/scripts/flavor/cerulean_trashed_house.lua index a5c31b95..a21b2029 100644 --- a/data/scripts/flavor/cerulean_trashed_house.lua +++ b/data/scripts/flavor/cerulean_trashed_house.lua @@ -14,9 +14,9 @@ return { -- else -> .WhatsLostIsLostText (player has TM_DIG) TEXT_CERULEANTRASHEDHOUSE_FISHING_GURU = { { "check_item", "TM_DIG" }, - { "jump_if_true", 4 }, + { "jump_if_true", 5 }, { "show_text", "_CeruleanTrashedHouseFishingGuruTheyStoleATMText" }, - { "jump", 5 }, + { "jump", "end" }, { "show_text", "_CeruleanTrashedHouseFishingGuruWhatsLostIsLostText" }, }, }, diff --git a/data/scripts/flavor/lavender_mart.lua b/data/scripts/flavor/lavender_mart.lua index 54ba8c8d..c6e91137 100644 --- a/data/scripts/flavor/lavender_mart.lua +++ b/data/scripts/flavor/lavender_mart.lua @@ -8,9 +8,9 @@ return { TEXT_LAVENDERMART_COOLTRAINER_M = { { "face_player" }, { "check_flag", "EVENT_RESCUED_MR_FUJI" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_LavenderMartCooltrainerMReviveText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_LavenderMartCooltrainerMNuggetText" }, }, }, diff --git a/data/scripts/flavor/mr_fujis_house.lua b/data/scripts/flavor/mr_fujis_house.lua index 2502704e..6e1a7ae0 100644 --- a/data/scripts/flavor/mr_fujis_house.lua +++ b/data/scripts/flavor/mr_fujis_house.lua @@ -13,9 +13,9 @@ M.MR_FUJIS_HOUSE = { TEXT_MRFUJISHOUSE_SUPER_NERD = { { "face_player" }, -- 1 { "check_flag", "EVENT_RESCUED_MR_FUJI" }, -- 2 - { "jump_if_true", 5 }, -- 3 + { "jump_if_true", 6 }, -- 3 { "show_text", "_MrFujisHouseSuperNerdMrFujiIsntHereText" }, -- 4 - { "jump", 6 }, -- 5 + { "jump", "end" }, -- 5 { "show_text", "_MrFujisHouseSuperNerdMrFujiHadBeenPrayingText" }, -- 6 }, @@ -25,9 +25,9 @@ M.MR_FUJIS_HOUSE = { TEXT_MRFUJISHOUSE_LITTLE_GIRL = { { "face_player" }, -- 1 { "check_flag", "EVENT_RESCUED_MR_FUJI" }, -- 2 - { "jump_if_true", 5 }, -- 3 + { "jump_if_true", 6 }, -- 3 { "show_text", "_MrFujisHouseLittleGirlThisIsMrFujisHouseText" }, -- 4 - { "jump", 6 }, -- 5 + { "jump", "end" }, -- 5 { "show_text", "_MrFujisHouseLittleGirlPokemonAreNiceToHugText" }, -- 6 }, diff --git a/data/scripts/flavor/route_16_gate_1f.lua b/data/scripts/flavor/route_16_gate_1f.lua index c35e1b11..3ab63768 100644 --- a/data/scripts/flavor/route_16_gate_1f.lua +++ b/data/scripts/flavor/route_16_gate_1f.lua @@ -12,9 +12,9 @@ return { TEXT_ROUTE16GATE1F_GUARD = { { "face_player" }, { "check_item", "BICYCLE" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_Route16Gate1FGuardNoPedestriansAllowedText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_Route16Gate1FGuardCyclingRoadExplanationText" }, }, }, diff --git a/data/scripts/flavor/route_18_gate_1f.lua b/data/scripts/flavor/route_18_gate_1f.lua index dc147506..a167017b 100644 --- a/data/scripts/flavor/route_18_gate_1f.lua +++ b/data/scripts/flavor/route_18_gate_1f.lua @@ -14,9 +14,9 @@ return { TEXT_ROUTE18GATE1F_GUARD = { { "face_player" }, { "check_item", "BICYCLE" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_Route18Gate1FGuardYouNeedABicycleText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_Route18Gate1FGuardCyclingRoadUphillText" }, }, }, diff --git a/data/scripts/flavor/silph_co_10f.lua b/data/scripts/flavor/silph_co_10f.lua index 33c8c5ff..c2c247ea 100644 --- a/data/scripts/flavor/silph_co_10f.lua +++ b/data/scripts/flavor/silph_co_10f.lua @@ -12,9 +12,9 @@ return { TEXT_SILPHCO10F_SILPH_WORKER_F = { { "face_player" }, { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_SilphCo10FSilphWorkerFImScaredText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_SilphCo10FSilphWorkerFQuietAboutMyCryingText" }, }, }, diff --git a/data/scripts/flavor/silph_co_3f.lua b/data/scripts/flavor/silph_co_3f.lua index 4813fb71..e8f2cbcc 100644 --- a/data/scripts/flavor/silph_co_3f.lua +++ b/data/scripts/flavor/silph_co_3f.lua @@ -10,9 +10,9 @@ return { -- not set: _SilphCo3FSilphWorkerMWhatShouldIDoText TEXT_SILPHCO3F_SILPH_WORKER_M = { { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 4 }, + { "jump_if_true", 5 }, { "show_text", "_SilphCo3FSilphWorkerMWhatShouldIDoText" }, - { "jump", 5 }, + { "jump", "end" }, { "show_text", "_SilphCo3FSilphWorkerMYouSavedUsText" }, }, }, diff --git a/data/scripts/flavor/silph_co_4f.lua b/data/scripts/flavor/silph_co_4f.lua index 3ac8d112..3c650280 100644 --- a/data/scripts/flavor/silph_co_4f.lua +++ b/data/scripts/flavor/silph_co_4f.lua @@ -7,9 +7,9 @@ return { TEXT_SILPHCO4F_SILPH_WORKER_M = { {"face_player"}, {"check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI"}, - {"jump_if_true", 5}, + {"jump_if_true", 6}, {"show_text", "_SilphCo4FSilphWorkerMImHidingText"}, - {"jump", 6}, + {"jump", "end"}, {"show_text", "_SilphCo4FSilphWorkerMTeamRocketIsGoneText"}, }, }, diff --git a/data/scripts/flavor/silph_co_5f.lua b/data/scripts/flavor/silph_co_5f.lua index 79213620..8c2f46fe 100644 --- a/data/scripts/flavor/silph_co_5f.lua +++ b/data/scripts/flavor/silph_co_5f.lua @@ -7,9 +7,9 @@ return { TEXT_SILPHCO5F_SILPH_WORKER_M = { {"face_player"}, {"check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI"}, - {"jump_if_true", 5}, + {"jump_if_true", 6}, {"show_text", "_SilphCo5FSilphWorkerMThatsYouRightText"}, - {"jump", 6}, + {"jump", "end"}, {"show_text", "_SilphCo5FSilphWorkerMYoureOurHeroText"}, }, }, diff --git a/data/scripts/flavor/silph_co_6f.lua b/data/scripts/flavor/silph_co_6f.lua index daeb4d42..be2a95e8 100644 --- a/data/scripts/flavor/silph_co_6f.lua +++ b/data/scripts/flavor/silph_co_6f.lua @@ -11,9 +11,9 @@ return { TEXT_SILPHCO6F_SILPH_WORKER_M1 = { { "face_player" }, { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_SilphCo6FSilphWorkerM1TookOverTheBuildingText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_SilphCo6FSilphWorkerM1BackToWorkText" }, }, @@ -21,9 +21,9 @@ return { TEXT_SILPHCO6F_SILPH_WORKER_M2 = { { "face_player" }, { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_SilphCo6FSilphWorkerMHelpMePleaseText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_SilphCo6FSilphWorkerMWeGotEngagedText" }, }, @@ -31,9 +31,9 @@ return { TEXT_SILPHCO6F_SILPH_WORKER_F1 = { { "face_player" }, { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_SilphCo6FSilphWorkerF1SuchACowardText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_SilphCo6FSilphWorkerF1HaveToMarryHimText" }, }, @@ -41,9 +41,9 @@ return { TEXT_SILPHCO6F_SILPH_WORKER_F2 = { { "face_player" }, { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_SilphCo6FSilphWorkerF2TeamRocketConquerWorldText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_SilphCo6FSilphWorkerF2TeamRocketRanText" }, }, @@ -51,9 +51,9 @@ return { TEXT_SILPHCO6F_SILPH_WORKER_M3 = { { "face_player" }, { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 5 }, + { "jump_if_true", 6 }, { "show_text", "_SilphCo6FSilphWorkerM3TargetedSilphText" }, - { "jump", 6 }, + { "jump", "end" }, { "show_text", "_SilphCo6FSilphWorkerM3WorkForSilphText" }, }, }, diff --git a/data/scripts/flavor/silph_co_7f.lua b/data/scripts/flavor/silph_co_7f.lua index 1c56cb5a..39c496cc 100644 --- a/data/scripts/flavor/silph_co_7f.lua +++ b/data/scripts/flavor/silph_co_7f.lua @@ -10,9 +10,9 @@ return { -- set: _SilphCo7FSilphWorkerM2CancelledMasterBallText TEXT_SILPHCO7F_SILPH_WORKER_M2 = { { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 4 }, + { "jump_if_true", 5 }, { "show_text", "_SilphCo7FSilphWorkerM2AfterTheMasterBallText" }, - { "jump", 5 }, + { "jump", "end" }, { "show_text", "_SilphCo7FSilphWorkerM2CancelledMasterBallText" }, }, @@ -22,9 +22,9 @@ return { -- set: _SilphCo7FSilphWorkerM3YouChasedOffTeamRocketText TEXT_SILPHCO7F_SILPH_WORKER_M3 = { { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 4 }, + { "jump_if_true", 5 }, { "show_text", "_SilphCo7FSilphWorkerM3ItWouldBeBadText" }, - { "jump", 5 }, + { "jump", "end" }, { "show_text", "_SilphCo7FSilphWorkerM3YouChasedOffTeamRocketText" }, }, @@ -34,9 +34,9 @@ return { -- set: _SilphCo7FSilphWorkerM4SafeAtLastText TEXT_SILPHCO7F_SILPH_WORKER_M4 = { { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 4 }, + { "jump_if_true", 5 }, { "show_text", "_SilphCo7FSilphWorkerM4ItsReallyDangerousHereText" }, - { "jump", 5 }, + { "jump", "end" }, { "show_text", "_SilphCo7FSilphWorkerM4SafeAtLastText" }, }, }, diff --git a/data/scripts/flavor/silph_co_8f.lua b/data/scripts/flavor/silph_co_8f.lua index 13ca3913..1614b47a 100644 --- a/data/scripts/flavor/silph_co_8f.lua +++ b/data/scripts/flavor/silph_co_8f.lua @@ -10,9 +10,9 @@ return { -- set: _SilphCo8FSilphWorkerMThanksForSavingUsText TEXT_SILPHCO8F_SILPH_WORKER_M = { { "check_flag", "EVENT_BEAT_SILPH_CO_GIOVANNI" }, - { "jump_if_true", 4 }, + { "jump_if_true", 5 }, { "show_text", "_SilphCo8FSilphWorkerMSilphIsFinishedText" }, - { "jump", 5 }, + { "jump", "end" }, { "show_text", "_SilphCo8FSilphWorkerMThanksForSavingUsText" }, }, }, diff --git a/tests/parity_flavor_talk_branches.lua b/tests/parity_flavor_talk_branches.lua new file mode 100644 index 00000000..5f2bddea --- /dev/null +++ b/tests/parity_flavor_talk_branches.lua @@ -0,0 +1,130 @@ +-- Parity: a branched flavor talk script shows exactly ONE text per branch +-- (#719). The buggy layout was +-- +-- check_flag X / jump_if_true / show before / jump / +-- show after +-- +-- where the fall-through "jump" landed ON the after-text row instead of +-- ending the script, so talking to the Silph Co. workers (and the other +-- NPCs below) before Giovanni showed the worried line and then the +-- relieved line right after it. ScriptRunner executes the row a numeric +-- jump targets, so the fixed scripts point jump_if_true at the after-text +-- row directly and end the before-branch with jump "end". +-- +-- The walker below is a minimal read of ScriptRunner's jump semantics: +-- checks are forced to one outcome, every non-control command is a no-op, +-- and show_text/ask rows are recorded in order. +package.path = "./?.lua;./?/init.lua;" .. package.path +local S = require("tests.harness").suite("parity flavor talk branches") +local check, eq = S.check, S.eq + +local scripts = require("data.scripts.init") + +local function textsShown(script, checkResult) + local texts, pc, steps = {}, 1, 0 + local last = nil + while pc <= #script do + steps = steps + 1 + if steps > 200 then error("script did not terminate", 0) end + local row = script[pc] + local cmd = row[1] + if cmd == "show_text" or cmd == "ask" then + texts[#texts + 1] = row[2] + pc = pc + 1 + elseif cmd == "check_flag" or cmd == "check_item" then + last = checkResult + pc = pc + 1 + elseif cmd == "jump" then + if row[2] == "end" then break end + pc = row[2] + elseif cmd == "jump_if_true" or cmd == "jump_if_false" then + local take = (cmd == "jump_if_true") == (last == true) + if take then + if row[2] == "end" then break end + pc = row[2] + else + pc = pc + 1 + end + else + pc = pc + 1 + end + end + return texts +end + +-- { mapId, textConst, before-text, after-text } +local cases = { + { "SILPH_CO_3F", "TEXT_SILPHCO3F_SILPH_WORKER_M", + "_SilphCo3FSilphWorkerMWhatShouldIDoText", + "_SilphCo3FSilphWorkerMYouSavedUsText" }, + { "SILPH_CO_4F", "TEXT_SILPHCO4F_SILPH_WORKER_M", + "_SilphCo4FSilphWorkerMImHidingText", + "_SilphCo4FSilphWorkerMTeamRocketIsGoneText" }, + { "SILPH_CO_5F", "TEXT_SILPHCO5F_SILPH_WORKER_M", + "_SilphCo5FSilphWorkerMThatsYouRightText", + "_SilphCo5FSilphWorkerMYoureOurHeroText" }, + { "SILPH_CO_6F", "TEXT_SILPHCO6F_SILPH_WORKER_M1", + "_SilphCo6FSilphWorkerM1TookOverTheBuildingText", + "_SilphCo6FSilphWorkerM1BackToWorkText" }, + { "SILPH_CO_6F", "TEXT_SILPHCO6F_SILPH_WORKER_M2", + "_SilphCo6FSilphWorkerMHelpMePleaseText", + "_SilphCo6FSilphWorkerMWeGotEngagedText" }, + { "SILPH_CO_6F", "TEXT_SILPHCO6F_SILPH_WORKER_F1", + "_SilphCo6FSilphWorkerF1SuchACowardText", + "_SilphCo6FSilphWorkerF1HaveToMarryHimText" }, + { "SILPH_CO_6F", "TEXT_SILPHCO6F_SILPH_WORKER_F2", + "_SilphCo6FSilphWorkerF2TeamRocketConquerWorldText", + "_SilphCo6FSilphWorkerF2TeamRocketRanText" }, + { "SILPH_CO_6F", "TEXT_SILPHCO6F_SILPH_WORKER_M3", + "_SilphCo6FSilphWorkerM3TargetedSilphText", + "_SilphCo6FSilphWorkerM3WorkForSilphText" }, + { "SILPH_CO_7F", "TEXT_SILPHCO7F_SILPH_WORKER_M2", + "_SilphCo7FSilphWorkerM2AfterTheMasterBallText", + "_SilphCo7FSilphWorkerM2CancelledMasterBallText" }, + { "SILPH_CO_7F", "TEXT_SILPHCO7F_SILPH_WORKER_M3", + "_SilphCo7FSilphWorkerM3ItWouldBeBadText", + "_SilphCo7FSilphWorkerM3YouChasedOffTeamRocketText" }, + { "SILPH_CO_7F", "TEXT_SILPHCO7F_SILPH_WORKER_M4", + "_SilphCo7FSilphWorkerM4ItsReallyDangerousHereText", + "_SilphCo7FSilphWorkerM4SafeAtLastText" }, + { "SILPH_CO_8F", "TEXT_SILPHCO8F_SILPH_WORKER_M", + "_SilphCo8FSilphWorkerMSilphIsFinishedText", + "_SilphCo8FSilphWorkerMThanksForSavingUsText" }, + { "SILPH_CO_10F", "TEXT_SILPHCO10F_SILPH_WORKER_F", + "_SilphCo10FSilphWorkerFImScaredText", + "_SilphCo10FSilphWorkerFQuietAboutMyCryingText" }, + { "CERULEAN_TRASHED_HOUSE", "TEXT_CERULEANTRASHEDHOUSE_FISHING_GURU", + "_CeruleanTrashedHouseFishingGuruTheyStoleATMText", + "_CeruleanTrashedHouseFishingGuruWhatsLostIsLostText" }, + { "LAVENDER_MART", "TEXT_LAVENDERMART_COOLTRAINER_M", + "_LavenderMartCooltrainerMReviveText", + "_LavenderMartCooltrainerMNuggetText" }, + { "ROUTE_16_GATE_1F", "TEXT_ROUTE16GATE1F_GUARD", + "_Route16Gate1FGuardNoPedestriansAllowedText", + "_Route16Gate1FGuardCyclingRoadExplanationText" }, + { "ROUTE_18_GATE_1F", "TEXT_ROUTE18GATE1F_GUARD", + "_Route18Gate1FGuardYouNeedABicycleText", + "_Route18Gate1FGuardCyclingRoadUphillText" }, + { "MR_FUJIS_HOUSE", "TEXT_MRFUJISHOUSE_SUPER_NERD", + "_MrFujisHouseSuperNerdMrFujiIsntHereText", + "_MrFujisHouseSuperNerdMrFujiHadBeenPrayingText" }, + { "MR_FUJIS_HOUSE", "TEXT_MRFUJISHOUSE_LITTLE_GIRL", + "_MrFujisHouseLittleGirlThisIsMrFujisHouseText", + "_MrFujisHouseLittleGirlPokemonAreNiceToHugText" }, +} + +for _, case in ipairs(cases) do + local mapId, textConst, beforeText, afterText = case[1], case[2], case[3], case[4] + local script = scripts.talkScript(mapId, textConst) + check(script ~= nil, mapId .. "/" .. textConst .. " has a talk script") + if script then + local before = textsShown(script, false) + eq(#before, 1, textConst .. " shows exactly one text before the event") + eq(before[1], beforeText, textConst .. " shows the before-text") + local after = textsShown(script, true) + eq(#after, 1, textConst .. " shows exactly one text after the event") + eq(after[1], afterText, textConst .. " shows the after-text") + end +end + +S.finish()