Files
gen1recomp/tests/engine/prize_window_bug1867.lua
T

215 lines
7.5 KiB
Lua

-- engine/events/prize_menu.asm (#1867)
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.harness")
local check, eq = T.check, T.eq
love = love or require("tests.love_stub")
local realFont = package.loaded["src.render.Font"]
local realTextBox = package.loaded["src.render.TextBox"]
local calls = {}
local FontStub
FontStub = {
BORDER = { tl = 1, tr = 2, bl = 3, br = 4, h = 5, v = 6 },
draw = function(text, x, y) calls[#calls + 1] = { "draw", text, x, y } end,
drawCode = function(code, x, y) calls[#calls + 1] = { "code", code, x, y } end,
drawBox = function(tx, ty, tw, th) calls[#calls + 1] = { "box", tx, ty, tw, th } end,
width = function(text) return #tostring(text) * 8 end,
split = function(text)
local out = {}
for i = 1, #tostring(text) do out[i] = i end
return out
end,
}
package.loaded["src.render.Font"] = FontStub
package.loaded["src.render.TextBox"] = {
new = function(_, text, onDone, opts)
return { text = text, onDone = onDone, opts = opts, isTextBox = true }
end,
}
package.loaded["src.core.Sound"] = { play = function() end }
local version = "red"
package.loaded["src.core.GameVersion"] = {
isBlue = function() return version == "blue" end,
isYellow = function() return version == "yellow" end,
}
package.loaded["src.ui.PrizeCounter"] = nil
package.loaded["src.ui.Theme"] = nil
local PrizeCounter = require("src.ui.PrizeCounter")
local M = assert(loadfile("data/scripts/story3.lua"))()
local counters = M.GAME_CORNER_PRIZE_ROOM.talk
local function found(kind, pred)
for _, c in ipairs(calls) do
if c[1] == kind and pred(c) then return c end
end
return nil
end
local pressed, done
local function mkGame(coins)
done = false
local mons = {}
for _, n in ipairs({ "ABRA", "CLEFAIRY", "NIDORINA", "VULPIX",
"WIGGLYTUFF" }) do
mons[n] = { name = n }
end
return {
data = {
text = {},
pokemon = mons,
items = {
TM_DRAGON_RAGE = { name = "TM23" },
TM_HYPER_BEAM = { name = "TM15" },
TM_SUBSTITUTE = { name = "TM35" },
},
},
save = { coins = coins, inventory = { COIN_CASE = 1 } },
input = {
wasPressed = function(_, b) return pressed == b end,
isDown = function() return false end,
},
stack = {
states = {},
push = function(self, s) self.states[#self.states + 1] = s end,
pop = function(self) return table.remove(self.states) end,
top = function(self) return self.states[#self.states] end,
},
}
end
local function open(n, coins)
local game = mkGame(coins or 5000)
counters["TEXT_GAMECORNERPRIZEROOM_PRIZE_VENDOR_" .. n](
game, nil, nil, function() done = true end)
local exchange = game.stack:pop()
exchange.onDone()
local which = game.stack:top()
which.opts.stay.onShown()
return game, which, game.stack:top()
end
do
local game, which, window = open(1)
check(tostring(which.text):find("Which prize", 1, true) ~= nil,
"WhichPrizeText goes up before the window")
check(which.opts.stay ~= nil and which.opts.stay.prompt == nil,
"it ends in `done`: no prompt, and PrintText leaves it up")
check(getmetatable(window) == PrizeCounter,
"the prize window is the CeladonPrizeMenu overlay")
check(window.isOpaque ~= true,
"so the prize room keeps drawing around it")
local names = {}
for i, row in ipairs(window.prizes) do names[i] = row.name end
eq(#window.prizes, 3, "one window is three prizes (#623)")
eq(table.concat(names, ","), "ABRA,CLEFAIRY,NIDORINA",
"Red's first window, by GetMonName")
for _, row in ipairs(window.prizes) do
check(tostring(row.name):find("L%d") == nil,
row.name .. " carries no level: GetPrizeMonLevel is not menu chrome")
end
eq(window.prizes[1].cost, 180, "with prizes.asm's coin prices")
eq(window.prizes[3].cost, 1200, "including the third row's")
calls = {}
window:draw()
check(found("box", function(c)
return c[2] == 11 and c[3] == 0 and c[4] == 9 and c[5] == 3
end) ~= nil, "PrintPrizePrice's coin box is 9x3 at hlcoord 11,0")
check(found("draw", function(c)
return c[2] == "COIN" and c[3] == 96 and c[4] == 0
end) ~= nil, "with COIN on its top border at hlcoord 12,0")
local coins = found("draw", function(c) return c[2] == "5000" end)
if check(coins ~= nil, "and the balance on the row below") then
eq(coins[3] + FontStub.width("5000"), 136,
"right-aligned through the BCD field (hlcoord 13,1)")
eq(coins[4], 8, "on the box's middle row")
end
check(found("box", function(c)
return c[2] == 0 and c[3] == 2 and c[4] == 18 and c[5] == 10
end) ~= nil, "the prize box is 18x10 at hlcoord 0,2, clear of columns 18-19")
for i, name in ipairs({ "ABRA", "CLEFAIRY", "NIDORINA" }) do
local y = 32 + (i - 1) * 16
check(found("draw", function(c)
return c[2] == name and c[3] == 16 and c[4] == y
end) ~= nil, name .. " sits at (16, " .. y .. ")")
local cost = found("draw", function(c)
return c[2] == tostring(window.prizes[i].cost)
end)
if check(cost ~= nil, "its price is drawn") then
eq(cost[4], y + 8, "one tile row below the name (hlcoord 13, 5/7/9)")
eq(cost[3] + FontStub.width(cost[2]), 136, "right-aligned with the coins")
end
end
check(found("draw", function(c)
return c[2] == "NO THANKS" and c[3] == 16 and c[4] == 80
end) ~= nil, "NoThanksText is the fourth row at hlcoord 2,10")
check(found("draw", function(c) return c[2] == "PRIZES (COINS)" end) == nil,
"and there is no full-screen page title")
pressed = "up"
window:update(1 / 60)
eq(window.index, 1, "Up on the first prize does nothing")
pressed = "down"
for _ = 1, 6 do window:update(1 / 60) end
eq(window.index, 4, "Down stops on NO THANKS, the fourth row")
pressed = "a"
window:update(1 / 60)
pressed = nil
check(done, "A on NO THANKS ends the conversation (cp 3 -> .noChoice)")
eq(#game.stack.states, 0,
"with the window and WhichPrizeText both taken down")
end
do
local game, _, window = open(3)
calls = {}
window:draw()
eq(window.prizes[1].name, "TM23", "vendor 3 is GetItemName, not GetMonName")
eq(window.prizes[3].cost, 7700, "PrizeMenuTMsEntries prices")
check(found("draw", function(c)
return c[2] == "3300" and c[4] == 40
end) ~= nil, "TM prices sit on the row below their name too")
end
do
version = "yellow"
local game, _, window = open(1)
local names = {}
for i, row in ipairs(window.prizes) do names[i] = row.name end
eq(table.concat(names, ","), "ABRA,VULPIX,WIGGLYTUFF",
"pokeyellow/data/events/prizes.asm restocks window 1")
eq(window.prizes[3].cost, 2680, "with Yellow's prices")
version = "red"
end
do
local game, _, window = open(1, 5000)
window.index = 1
pressed = "a"
window:update(1 / 60)
pressed = nil
local ask = game.stack:top()
check(ask.isTextBox and tostring(ask.text):find("ABRA", 1, true) ~= nil,
"SoYouWantPrizeText names the prize out of wNameBuffer")
check(tostring(ask.text):find("wNameBuffer", 1, true) == nil,
"with the token filled in")
check(ask.opts.choice ~= nil, "and a YES/NO over it")
eq(game.stack.states[#game.stack.states - 1], window,
"the window is still up underneath")
eq(game.save.coins, 5000, "no coins move before the answer")
end
package.loaded["src.render.Font"] = realFont
package.loaded["src.render.TextBox"] = realTextBox
package.loaded["src.core.Sound"] = nil
package.loaded["src.core.GameVersion"] = nil
package.loaded["src.ui.PrizeCounter"] = nil
package.loaded["src.ui.Theme"] = nil
require("src.ui.Screens").invalidate()
T.finish()