mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
113 lines
4.2 KiB
Lua
113 lines
4.2 KiB
Lua
-- Parity test: mart inventories match pokered, and every item the route
|
|
-- driver tries to buy is actually on that mart's shelf.
|
|
--
|
|
-- Two failures in one, and the second is the one that bit.
|
|
--
|
|
-- Our extracted mart data was right all along -- VermilionMartClerkText is
|
|
-- POKE_BALL, SUPER_POTION, ICE_HEAL, AWAKENING, PARLYZ_HEAL, REPEL
|
|
-- (data/items/marts.asm:17), and that is exactly what we import. The route
|
|
-- driver's shopping list asked for plain POTION there, which Vermilion has
|
|
-- never sold. buyItem logged "shop: no POTION @ VERMILION_MART" into the
|
|
-- end-of-run summary and returned, so the bot left town with no healing at
|
|
-- all and then died nine times in Surge's gym and five more around
|
|
-- Cerulean, every fight taken at whatever HP the last nurse had left it.
|
|
--
|
|
-- A shopping list that names an unstocked item cannot work, and nothing
|
|
-- else in the run reports it loudly enough to notice. This asserts the
|
|
-- lists against the data instead.
|
|
--
|
|
-- Self-contained; run via `luajit tests/parity_mart_stock.lua`.
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
if not _G.love then _G.love = require("tests.love_stub") end
|
|
local S = require("tests.harness").suite("parity mart stock")
|
|
local check, eq = S.check, S.eq
|
|
|
|
local T = dofile("data/generated/text_pointers.lua")
|
|
|
|
-- MAP_NAME -> text-pointer group ("CELADON_MART_4F" -> "CeladonMart4F")
|
|
local function groupOf(map)
|
|
local s = ""
|
|
for part in tostring(map):gmatch("[^_]+") do
|
|
if part:match("^%d") then
|
|
s = s .. part:upper()
|
|
else
|
|
s = s .. part:sub(1, 1):upper() .. part:sub(2):lower()
|
|
end
|
|
end
|
|
return s
|
|
end
|
|
|
|
-- every item sold on a map, across all its clerks
|
|
local function stockFor(map)
|
|
local group = T[groupOf(map)]
|
|
if not group then return nil end
|
|
local set, any = {}, false
|
|
for _, v in pairs(group) do
|
|
if type(v) == "table" and v.mart then
|
|
for _, id in ipairs(v.mart) do set[id] = true; any = true end
|
|
end
|
|
end
|
|
return any and set or nil
|
|
end
|
|
|
|
-- ---- 1. our extracted stock matches pokered's marts.asm -----------------
|
|
-- Spot-checks transcribed from data/items/marts.asm; the Vermilion row is
|
|
-- the one the driver got wrong, so it is pinned exactly.
|
|
local POKERED = {
|
|
VERMILION_MART = { "POKE_BALL", "SUPER_POTION", "ICE_HEAL", "AWAKENING",
|
|
"PARLYZ_HEAL", "REPEL" },
|
|
PEWTER_MART = { "POKE_BALL", "POTION", "ESCAPE_ROPE", "ANTIDOTE",
|
|
"BURN_HEAL", "AWAKENING", "PARLYZ_HEAL" },
|
|
LAVENDER_MART = { "GREAT_BALL", "SUPER_POTION", "REVIVE", "ESCAPE_ROPE",
|
|
"SUPER_REPEL", "ANTIDOTE", "BURN_HEAL", "ICE_HEAL",
|
|
"PARLYZ_HEAL" },
|
|
}
|
|
for map, want in pairs(POKERED) do
|
|
local sold = stockFor(map)
|
|
check(sold ~= nil, map .. " has mart data")
|
|
if sold then
|
|
for _, id in ipairs(want) do
|
|
check(sold[id], ("%s stocks %s (marts.asm)"):format(map, id))
|
|
end
|
|
end
|
|
end
|
|
-- and the absence that caused the bug
|
|
check(not (stockFor("VERMILION_MART") or {}).POTION,
|
|
"VERMILION_MART sells SUPER_POTION and NOT plain POTION")
|
|
|
|
-- ---- 2. every driver shopping list is actually stocked ------------------
|
|
-- Mirrors SHOP_STOCK in tests/drivers/route.lua. Kept as a literal rather
|
|
-- than reached into the driver, which needs a live Game to load.
|
|
local SHOP_STOCK = {
|
|
viridianBalls = { "POKE_BALL", "ANTIDOTE", "PARLYZ_HEAL" },
|
|
pewter = { "ESCAPE_ROPE", "POTION" },
|
|
vermilion = { "SUPER_POTION", "POKE_BALL" },
|
|
repels = { "SUPER_POTION" },
|
|
buffs = {},
|
|
pokeDoll = { "POKE_DOLL" },
|
|
tm07 = {}, vending = {}, water = {},
|
|
}
|
|
|
|
local R = dofile("tests/drivers/bot_route.lua")
|
|
local checked = 0
|
|
for i, seg in ipairs(R) do
|
|
for _, step in ipairs(seg.steps) do
|
|
if step.op == "shop" then
|
|
local list = SHOP_STOCK[step.list]
|
|
-- an unknown list name would silently fall back to POTION at runtime
|
|
check(list ~= nil,
|
|
("segment %d: shop list %q is known to the driver")
|
|
:format(i, tostring(step.list)))
|
|
local sold = stockFor(seg.map)
|
|
for _, id in ipairs(list or {}) do
|
|
checked = checked + 1
|
|
check(sold and sold[id],
|
|
("segment %d: %s sells %s"):format(i, seg.map, id))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
check(checked > 0, "the route actually contains shop steps to check")
|
|
|
|
S.finish()
|