# Conflicts:
#	data/scripts/story4.lua
#	src/ui/DexEntryMenu.lua
#	tests/drivers/fighting_dojo_bug197_test.lua
This commit is contained in:
bryanthaboi
2026-08-05 14:43:05 -04:00
7 changed files with 143 additions and 50 deletions
+6 -14
View File
@@ -3,9 +3,8 @@
-- BUG1 gate -- the master stops the player on the tile to his left
-- BUG2 no speech -- no won text + no prize dialogue after the win
-- BUG3 wrong re-talk -- shows the pre-battle challenge, not the after line
-- BUG4 (verify) -- the ball opens the prize's dex preview first
-- (FightingDojo.asm DisplayPokedex, #853) and then
-- asks with the Gen1 descriptor text
-- BUG4 (verify) -- the ball ask() is the Gen1 descriptor, shown after
-- the species' dex entry (DisplayPokedex)
-- BUG5 both balls -- the chosen ball AND the other one both vanish; the
-- other should stay and give the "greedy" refusal
-- BUG6 poster -- the north-wall posters ("Enemies on every side!") are
@@ -22,7 +21,6 @@ return function(game)
local DIR = os.getenv("SHOT_DIR") or "/tmp/shots"
local TextBox = require("src.render.TextBox")
local ChoiceBox = require("src.ui.ChoiceBox")
local DexEntryMenu = require("src.ui.DexEntryMenu")
local OW = require("src.world.OverworldController")
local Pokemon = require("src.pokemon.Pokemon")
local Commands = require("src.script.Commands")
@@ -38,7 +36,6 @@ return function(game)
local function topIsTextBox() return getmetatable(game.stack:top()) == TextBox end
local function topIsChoice() return getmetatable(game.stack:top()) == ChoiceBox end
local function topIsDex() return getmetatable(game.stack:top()) == DexEntryMenu end
local function currentPageText()
local top = game.stack:top()
@@ -167,8 +164,9 @@ return function(game)
mashUntil(function() return game.stack:top() == ow end)
------------------------------------------------------------------
-- BUG4 (verify-only): the Hitmonlee ball prompt is the Gen1 descriptor
-- ("You want the hard kicking HITMONLEE?"), not a Pokedex entry screen.
-- BUG4 (verify-only): the Hitmonlee ball shows the species' Pokedex
-- entry first (DisplayPokedex, #853), then the Gen1 descriptor prompt
-- ("You want the hard kicking HITMONLEE?").
------------------------------------------------------------------
ow = resetDojo(4, 2, "up", { EVENT_BEAT_KARATE_MASTER = true })
local leeBall = npcByName(ow, "FIGHTINGDOJO_HITMONLEE_POKE_BALL")
@@ -176,14 +174,8 @@ return function(game)
check(leeBall ~= nil and chanBall ~= nil, "BUG5: both prize balls on the mat")
if leeBall then
ow:talkTo(leeBall)
-- DisplayPokedex runs before .Text and YesNoChoice in FightingDojo.asm,
-- so the dex page is the first thing the ball opens (#853)
U.wait(3)
check(topIsDex(), "BUG4: the ball opens the HITMONLEE dex entry first")
U.shot(game, DIR .. "/dojo_4_dexentry.png")
mashUntil(function() return not topIsDex() end, 20)
check(sawText("hard kicking") or sawText("HITMONLEE"),
"BUG4: the dex page is followed by the Gen1 descriptor prompt")
"BUG4: ball asks the Gen1 descriptor prompt after the dex entry")
U.shot(game, DIR .. "/dojo_4_prompt.png")
------------------------------------------------------------------
-- BUG5: choose YES -> only the chosen ball vanishes; the other stays
+20
View File
@@ -0,0 +1,20 @@
-- CacheFs stays headless-safe: plain luajit has no love global, and the
-- modkit validate/pack driver reaches CacheFs.read through Data:load when
-- an optional generated module (audio) is missing from the checkout
-- (issue #850). With no portable root and no love there is no save
-- directory to read from, so the read is a nil miss, not a crash.
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.harness")
local check = T.check
check(_G.love == nil, "suite runs with no love global")
local CacheFs = require("src.import.CacheFs")
check(CacheFs.read("data/generated/audio.lua") == nil,
"read is a nil miss headless, not a crash")
check(CacheFs.readActive("data/generated/audio.lua") == nil,
"readActive is a nil miss headless, not a crash")
T.finish()
+89
View File
@@ -0,0 +1,89 @@
-- Parity: the Fighting Dojo prize balls open the Pokédex entry before the
-- take-it prompt (#853). FightingDojo.asm runs DisplayPokedex on the
-- ball's species (marking it seen) and only then prints the yes/no ask.
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 then Data:load() end
local S = require("tests.harness").suite("parity Fighting Dojo dex entry")
local check, eq = S.check, S.eq
local Font = require("src.render.Font")
Font.load(Data)
local TextBox = require("src.render.TextBox")
local DexEntryMenu = require("src.ui.DexEntryMenu")
local SaveData = require("src.core.SaveData")
local dojo = require("data.scripts.story4").FIGHTING_DOJO
local function fakeGame()
local states = {}
local save = SaveData.newGame()
save.pokedex = { seen = {}, owned = {} }
save.flags = { EVENT_BEAT_KARATE_MASTER = true }
local game = {
data = Data,
save = save,
pressed = false,
stack = {
states = states,
push = function(_, s) states[#states + 1] = s end,
pop = function(_) states[#states] = nil end,
top = function(_) return states[#states] end,
},
}
game.input = { wasPressed = function(_, btn)
local p = game.pressed
game.pressed = false
return p and btn == "a"
end }
return game
end
local function pageText(box)
local out = {}
for _, page in ipairs(box.pages or {}) do
out[#out + 1] = table.concat(page, "\n")
end
return table.concat(out, "\n")
end
-- each ball: dex entry first (seen, not owned), then the ask prompt
for _, c in ipairs({
{ textId = "TEXT_FIGHTINGDOJO_HITMONLEE_POKE_BALL", species = "HITMONLEE" },
{ textId = "TEXT_FIGHTINGDOJO_HITMONCHAN_POKE_BALL", species = "HITMONCHAN" },
}) do
local game = fakeGame()
dojo.talk[c.textId](game, {}, nil, function() end)
local top = game.stack:top()
check(getmetatable(top) == DexEntryMenu,
c.textId .. " opens the Pokédex entry first")
eq(top and top.def and top.def.id, c.species,
"the entry shows " .. c.species)
check(game.save.pokedex.seen[c.species] == true,
"the preview marks " .. c.species .. " seen")
check(not game.save.pokedex.owned[c.species],
"the preview does not mark " .. c.species .. " owned")
game.pressed = true
top:update(0)
local ask = game.stack:top()
check(getmetatable(ask) == TextBox,
"closing the entry shows the take-it prompt")
check(ask and pageText(ask):find(c.species, 1, true) ~= nil,
"the prompt names " .. c.species)
end
-- before the Karate Master is beaten the ball still refuses, no dex entry
do
local game = fakeGame()
game.save.flags.EVENT_BEAT_KARATE_MASTER = nil
dojo.talk.TEXT_FIGHTINGDOJO_HITMONLEE_POKE_BALL(game, {}, nil,
function() end)
check(getmetatable(game.stack:top()) == TextBox,
"an unbeaten master keeps the refusal text, not the dex entry")
check(not game.save.pokedex.seen.HITMONLEE,
"the refusal does not mark Hitmonlee seen")
end
S.finish()