mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 00:10:56 +02:00
122 lines
4.7 KiB
Lua
122 lines
4.7 KiB
Lua
-- Parity: the Fan Club Chairman asks before telling his story (#1050).
|
|
-- pokered scripts/PokemonFanClub.asm PokemonFanClubChairmanText.
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
if not _G.love then _G.love = require("tests.love_stub") end
|
|
local Data = require("src.core.Data")
|
|
if not (Data.maps and Data.maps.PALLET_TOWN) then Data:load() end
|
|
|
|
local S = require("tests.harness").suite("parity Fan Club chairman")
|
|
local check, eq = S.check, S.eq
|
|
|
|
local Game = require("src.core.Game")
|
|
local Input = require("src.core.Input")
|
|
local StateStack = require("src.core.StateStack")
|
|
local SaveData = require("src.core.SaveData")
|
|
local ScriptRunner = require("src.script.ScriptRunner")
|
|
local Commands = require("src.script.Commands")
|
|
local Flags = require("src.script.Flags")
|
|
local ChoiceBox = require("src.ui.ChoiceBox")
|
|
local mapScripts = require("data.scripts.init")
|
|
|
|
Game.data = Data
|
|
Game.input = Input; Input:init()
|
|
Game.stack = StateStack; StateStack:init()
|
|
Game.save = SaveData.newGame()
|
|
require("src.render.Font").load(Data)
|
|
|
|
local MAP, TEXT = "POKEMON_FAN_CLUB", "TEXT_POKEMONFANCLUB_CHAIRMAN"
|
|
local script = mapScripts.talkScript(MAP, TEXT)
|
|
check(type(script) == "table", "the chairman is a row list")
|
|
eq(#ScriptRunner.validate(script), 0,
|
|
"the rows validate cleanly (labels resolve after the renumbering)")
|
|
|
|
-- === the intro is the question, not a plain box ===
|
|
local asks = 0
|
|
for _, row in ipairs(type(script) == "table" and script or {}) do
|
|
if row[1] == "ask" then
|
|
asks = asks + 1
|
|
eq(row[2], "_PokemonFanClubChairmanIntroText",
|
|
"the YesNoChoice rides the intro text (#1050)")
|
|
end
|
|
end
|
|
eq(asks, 1, "exactly one question, right after the intro")
|
|
|
|
-- === harness: run the talk script headless, recording show_text ids ===
|
|
local shown = {}
|
|
local origShow = Commands.show_text
|
|
-- forward extraOpts: Commands.ask rides show_text's 4th argument
|
|
Commands.show_text = function(ctx, textId, subs, ...)
|
|
table.insert(shown, textId)
|
|
return origShow(ctx, textId, subs, ...)
|
|
end
|
|
|
|
-- pressFn returns the Input.pressed table for this frame (default: A)
|
|
local function runScript(pressFn)
|
|
shown = {}
|
|
local ow = { map = { id = MAP, def = { label = MAP } },
|
|
npcs = {}, entities = {} }
|
|
local r = ScriptRunner.new(Game, ow)
|
|
r:run(script, { npc = { def = {}, facePlayer = function() end },
|
|
overworld = ow })
|
|
local guard = 0
|
|
while r:isRunning() and guard < 3000 do
|
|
guard = guard + 1
|
|
Input.pressed = pressFn and pressFn() or { a = true }
|
|
StateStack:update(1 / 60)
|
|
r:update()
|
|
end
|
|
Input.pressed = {}
|
|
return not r:isRunning()
|
|
end
|
|
|
|
local function shownIs(want, msg)
|
|
eq(table.concat(shown, ","), table.concat(want, ","), msg)
|
|
end
|
|
|
|
-- press B while the YES/NO box is up, A otherwise: the NO answer
|
|
local function declines()
|
|
if getmetatable(StateStack:top()) == ChoiceBox then return { b = true } end
|
|
return { a = true }
|
|
end
|
|
|
|
local function held(id) return Game.save.inventory[id] or 0 end
|
|
|
|
-- === 1) YES: story, voucher, received line, explanation ===
|
|
Game.save = SaveData.newGame()
|
|
check(runScript(), "chairman script completes on YES")
|
|
shownIs({ "_PokemonFanClubChairmanIntroText",
|
|
"_PokemonFanClubChairmanStoryText",
|
|
"_PokemonFanClubReceivedBikeVoucherText",
|
|
"_PokemonFanClubExplainBikeVoucherText" },
|
|
"YES hears the RAPIDASH story out and collects the voucher")
|
|
eq(held("BIKE_VOUCHER"), 1, "the BIKE VOUCHER is in the bag")
|
|
check(Flags.get(Game.save, "EVENT_RECEIVED_BIKE_VOUCHER"),
|
|
"EVENT_GOT_BIKE_VOUCHER is set")
|
|
|
|
-- === 2) NO: the brush-off, and the voucher stays with the chairman ===
|
|
Game.save = SaveData.newGame()
|
|
check(runScript(declines), "chairman script completes on NO")
|
|
shownIs({ "_PokemonFanClubChairmanIntroText", "_PokemonFanClubNoStoryText" },
|
|
"NO skips the story and the gift (#1050)")
|
|
eq(held("BIKE_VOUCHER"), 0, "declining leaves the voucher unclaimed")
|
|
check(not Flags.get(Game.save, "EVENT_RECEIVED_BIKE_VOUCHER"),
|
|
"declining leaves the event clear, so he can be asked again")
|
|
|
|
-- === 3) asking again after NO still works, and YES then pays out ===
|
|
check(runScript(), "second visit completes")
|
|
shownIs({ "_PokemonFanClubChairmanIntroText",
|
|
"_PokemonFanClubChairmanStoryText",
|
|
"_PokemonFanClubReceivedBikeVoucherText",
|
|
"_PokemonFanClubExplainBikeVoucherText" },
|
|
"a player who said NO can come back for the voucher")
|
|
eq(held("BIKE_VOUCHER"), 1, "the voucher arrives on the second visit")
|
|
|
|
-- === 4) served player: .nothingleft, no question at all ===
|
|
check(runScript(), "post-voucher script completes")
|
|
shownIs({ "_PokemonFanClubChairFinalText" },
|
|
"with the voucher collected he only reminisces")
|
|
eq(held("BIKE_VOUCHER"), 1, "no second voucher")
|
|
|
|
Commands.show_text = origShow
|
|
S.finish()
|