mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
Merge pull request #655 from spiritsnails/fix/warden-yesno-645
This commit is contained in:
+25
-11
@@ -674,16 +674,18 @@ M.SAFARI_ZONE_SECRET_HOUSE = {
|
||||
M.WARDENS_HOUSE = {
|
||||
talk = {
|
||||
TEXT_WARDENSHOUSE_WARDEN = {
|
||||
-- Labelled rather than hand-numbered: the branches here have been
|
||||
-- re-pointed twice now (#535, #645), and every insert used to mean
|
||||
-- renumbering three jumps that had no way of announcing they were stale.
|
||||
{ "face_player" }, -- 1
|
||||
{ "check_flag", "EVENT_GOT_HM04" }, -- 2
|
||||
-- #535: previously jumped to the same silent-end target as the
|
||||
-- give-then-thank fallthrough (row 13), so the warden said nothing
|
||||
-- on every visit after the trade. pokered's .got_item branch
|
||||
-- (scripts/WardensHouse.asm) instead prints HM04ExplanationText,
|
||||
-- so route here to the new row 17 that does the same.
|
||||
{ "jump_if_true", 17 }, -- 3
|
||||
-- give-then-thank fallthrough, so the warden said nothing on every
|
||||
-- visit after the trade. pokered's .got_item branch
|
||||
-- (scripts/WardensHouse.asm) instead prints HM04ExplanationText.
|
||||
{ "jump_if_true", "got_hm04" }, -- 3
|
||||
{ "check_item", "GOLD_TEETH" }, -- 4
|
||||
{ "jump_if_false", 15 }, -- 5
|
||||
{ "jump_if_false", "no_teeth" }, -- 5
|
||||
{ "show_text", "_WardensHouseWardenGaveTheGoldTeethText" }, -- 6
|
||||
{ "take_item", "GOLD_TEETH", 1 }, -- 7
|
||||
{ "set_flag", "EVENT_GAVE_GOLD_TEETH" }, -- 8
|
||||
@@ -692,15 +694,27 @@ M.WARDENS_HOUSE = {
|
||||
{ "give_item", "HM_STRENGTH", 1, false }, -- 10
|
||||
{ "show_text", "_WardensHouseWardenReceivedHM04Text" }, -- 11
|
||||
{ "set_flag", "EVENT_GOT_HM04" }, -- 12
|
||||
{ "jump", 18 }, -- 13 (already got it this convo; jp .done)
|
||||
{ "jump", 18 }, -- 14 (unused)
|
||||
{ "show_text", "_WardensHouseWardenGibberish1Text" }, -- 15
|
||||
{ "jump", 18 }, -- 16 (#535: skip the new explanation row below)
|
||||
{ "jump", "end" }, -- 13 (jp .done)
|
||||
|
||||
-- #645: WardensHouseWardenText prints Gibberish1, then YesNoChoice,
|
||||
-- and the warden answers the same gibberish either way -- Gibberish2
|
||||
-- on yes, Gibberish3 on no (scripts/WardensHouse.asm). The port
|
||||
-- printed the question and walked off before the answer.
|
||||
{ "label", "no_teeth" }, -- 14
|
||||
{ "ask", "_WardensHouseWardenGibberish1Text" }, -- 15
|
||||
{ "jump_if_true", "gibberish_yes" }, -- 16
|
||||
{ "show_text", "_WardensHouseWardenGibberish3Text" }, -- 17
|
||||
{ "jump", "end" }, -- 18
|
||||
{ "label", "gibberish_yes" }, -- 19
|
||||
{ "show_text", "_WardensHouseWardenGibberish2Text" }, -- 20
|
||||
{ "jump", "end" }, -- 21
|
||||
|
||||
-- #535: pokered .got_item branch (scripts/WardensHouse.asm) --
|
||||
-- printed on every subsequent talk once EVENT_GOT_HM04 is set.
|
||||
-- Text is _WardensHouseWardenHM04ExplanationText (text/WardensHouse.asm):
|
||||
-- HM04 teaches Strength, and hints at the Safari Zone secret house.
|
||||
{ "show_text", "_WardensHouseWardenHM04ExplanationText" }, -- 17
|
||||
{ "label", "got_hm04" }, -- 22
|
||||
{ "show_text", "_WardensHouseWardenHM04ExplanationText" }, -- 23
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
-- Driver: #645 Warden's House YES/NO.
|
||||
--
|
||||
-- WardensHouseWardenText prints Gibberish1, calls YesNoChoice, and answers
|
||||
-- with Gibberish2 on yes / Gibberish3 on no (scripts/WardensHouse.asm). The
|
||||
-- port printed the question and ended the script, so the box just closed.
|
||||
--
|
||||
-- Runs the conversation twice against the live script: once answering YES,
|
||||
-- once walking the cursor down to NO, shooting the YES/NO box and each reply.
|
||||
-- POKEPORT_DRIVER=tests/drivers/wardens_house_yesno_bug645_test.lua \
|
||||
-- POKEPORT_SPEED=2 lovec .
|
||||
return function(game)
|
||||
local U = dofile("tests/drivers/util.lua")
|
||||
local DIR = os.getenv("SHOT_DIR") or "/tmp/shots"
|
||||
|
||||
-- record what the script actually prints, so the log is checkable on its
|
||||
-- own and does not depend on reading the shots
|
||||
local Commands = require("src.script.Commands")
|
||||
local shown = {}
|
||||
local origShow = Commands.show_text
|
||||
-- forward every argument: the 4th is extraOpts, which is how Commands.ask
|
||||
-- passes its `choice` callback -- drop it and the YES/NO box never appears
|
||||
Commands.show_text = function(ctx, textId, ...)
|
||||
shown[#shown + 1] = textId
|
||||
U.log("text:", textId)
|
||||
return origShow(ctx, textId, ...)
|
||||
end
|
||||
|
||||
local ChoiceBox = require("src.ui.ChoiceBox")
|
||||
local function choiceUp()
|
||||
local top = game.stack:top()
|
||||
return top and getmetatable(top) == ChoiceBox and top or nil
|
||||
end
|
||||
|
||||
-- mash A until the YES/NO box is up, then hand it back
|
||||
local function talkUntilChoice()
|
||||
U.tap(game, "a")
|
||||
for _ = 1, 600 do
|
||||
local box = choiceUp()
|
||||
if box then return box end
|
||||
U.tap(game, "a")
|
||||
U.wait(3)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function talkDone()
|
||||
for _ = 1, 600 do
|
||||
if game.stack:top() == game.overworld then return true end
|
||||
U.tap(game, "a")
|
||||
U.wait(3)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- the warden stands at (2,3); face him from the tile below
|
||||
U.teleport(game, "WARDENS_HOUSE", 2, 4, "up")
|
||||
-- Lead-in: this is meant to be WATCHED, not just logged. At SPEED=2 the
|
||||
-- driver runs two iterations per rendered frame, so a wait of N is N/120
|
||||
-- seconds on screen -- long enough here to find the window before anything
|
||||
-- happens. Every beat below is held the same way.
|
||||
U.log("watch now: talking to the WARDEN in 5 seconds")
|
||||
U.wait(600)
|
||||
U.shot(game, DIR .. "/warden_0_before.png")
|
||||
|
||||
-- ---------------------------------------------------------------- YES
|
||||
shown = {}
|
||||
local box = talkUntilChoice()
|
||||
if not box then
|
||||
U.log("FAIL no YES/NO box appeared after the gibberish line")
|
||||
else
|
||||
U.log("YES/NO box is up, cursor on", box.index == 1 and "YES" or "NO")
|
||||
U.wait(360) -- hold the box on screen for 3s
|
||||
U.shot(game, DIR .. "/warden_1_yesno_box.png")
|
||||
U.tap(game, "a") -- take the default, YES
|
||||
U.wait(360)
|
||||
U.shot(game, DIR .. "/warden_2_yes_reply.png")
|
||||
end
|
||||
talkDone()
|
||||
U.log("YES branch printed:", table.concat(shown, ","))
|
||||
U.log("now the same conversation again, answering NO")
|
||||
U.wait(360)
|
||||
|
||||
-- ----------------------------------------------------------------- NO
|
||||
shown = {}
|
||||
box = talkUntilChoice()
|
||||
if not box then
|
||||
U.log("FAIL no YES/NO box on the second talk")
|
||||
else
|
||||
U.wait(240)
|
||||
U.tap(game, "down") -- walk the cursor onto NO, on screen
|
||||
U.wait(360)
|
||||
U.log("cursor now on", box.index == 1 and "YES" or "NO")
|
||||
U.shot(game, DIR .. "/warden_3_yesno_on_no.png")
|
||||
U.tap(game, "a")
|
||||
U.wait(360)
|
||||
U.shot(game, DIR .. "/warden_4_no_reply.png")
|
||||
end
|
||||
talkDone()
|
||||
U.log("NO branch printed:", table.concat(shown, ","))
|
||||
|
||||
U.wait(360)
|
||||
Commands.show_text = origShow
|
||||
end
|
||||
@@ -36,13 +36,22 @@ local script = story.WARDENS_HOUSE.talk.TEXT_WARDENSHOUSE_WARDEN
|
||||
-- instrument show_text the way parity_gift_atomicity.lua does, to record
|
||||
-- exactly which text ids actually printed
|
||||
local shown = {}
|
||||
-- forward EVERY argument: the 4th is extraOpts, which is how Commands.ask
|
||||
-- hands down its `choice` callback. A wrapper that stops at `subs` silently
|
||||
-- turns every ask in the script back into a plain show_text -- no YES/NO box,
|
||||
-- and ctx.lastCheck left holding whatever the previous check_* put there.
|
||||
local origShow = Commands.show_text
|
||||
Commands.show_text = function(ctx, textId, subs)
|
||||
Commands.show_text = function(ctx, textId, ...)
|
||||
shown[#shown + 1] = textId
|
||||
return origShow(ctx, textId, subs)
|
||||
return origShow(ctx, textId, ...)
|
||||
end
|
||||
|
||||
local function runScript()
|
||||
-- `button` drives the whole conversation: both A and B page a text box, and
|
||||
-- on the YES/NO box A takes the cursor's default (YES) while B snaps to NO
|
||||
-- and answers false (ChoiceBox:update, .choseSecondMenuItem). So holding A
|
||||
-- runs the yes branch and holding B runs the no branch, with no reaching
|
||||
-- into the choice box from the test.
|
||||
local function runScript(button)
|
||||
shown = {}
|
||||
StateStack:init()
|
||||
local ow = { map = { id = "WARDENS_HOUSE", def = { label = "WardensHouse" } },
|
||||
@@ -53,7 +62,7 @@ local function runScript()
|
||||
local guard = 0
|
||||
while r:isRunning() and guard < 3000 do
|
||||
guard = guard + 1
|
||||
Input.pressed = { a = true }
|
||||
Input.pressed = { [button or "a"] = true }
|
||||
StateStack:update(1 / 60)
|
||||
r:update()
|
||||
end
|
||||
@@ -85,13 +94,34 @@ check(runScript(), "a third talk completes")
|
||||
eq(table.concat(shown, ","), "_WardensHouseWardenHM04ExplanationText",
|
||||
"the explanation text repeats on every later talk, not just the first")
|
||||
|
||||
-- === 3) unrelated path is unchanged: no GOLD TEETH, no flag yet ===
|
||||
-- === 3) no GOLD TEETH yet: the gibberish question, then a YES/NO, then the
|
||||
-- warden's answer -- Gibberish2 on yes, Gibberish3 on no (#645).
|
||||
-- The port used to stop dead after the question. ===
|
||||
Game.save = SaveData.newGame()
|
||||
check(runScript(), "empty-handed talk completes")
|
||||
eq(table.concat(shown, ","), "_WardensHouseWardenGibberish1Text",
|
||||
"without the GOLD TEETH the Warden's gibberish line is unchanged")
|
||||
check(runScript("a"), "empty-handed talk completes on yes")
|
||||
eq(table.concat(shown, ","),
|
||||
"_WardensHouseWardenGibberish1Text,_WardensHouseWardenGibberish2Text",
|
||||
"answering YES gets the warden's reply, not silence (#645)")
|
||||
check(not Flags.get(Game.save, "EVENT_GOT_HM04"), "no HM04 yet")
|
||||
|
||||
Game.save = SaveData.newGame()
|
||||
check(runScript("b"), "empty-handed talk completes on no")
|
||||
eq(table.concat(shown, ","),
|
||||
"_WardensHouseWardenGibberish1Text,_WardensHouseWardenGibberish3Text",
|
||||
"and answering NO gets the other reply (#645)")
|
||||
|
||||
-- the question is asked, not just printed: `ask` is what puts the YES/NO box
|
||||
-- up, so a future edit that downgrades it back to show_text fails here
|
||||
local askRow
|
||||
for _, row in ipairs(script) do
|
||||
if row[2] == "_WardensHouseWardenGibberish1Text" then askRow = row[1] end
|
||||
end
|
||||
eq(askRow, "ask", "the gibberish line is asked with a YES/NO, not just shown")
|
||||
|
||||
-- neither answer touches the teeth trade
|
||||
check(not Flags.get(Game.save, "EVENT_GAVE_GOLD_TEETH"),
|
||||
"and neither answer hands over teeth the player does not have")
|
||||
|
||||
Commands.show_text = origShow
|
||||
|
||||
S.finish()
|
||||
|
||||
Reference in New Issue
Block a user