mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
87 lines
3.5 KiB
Lua
87 lines
3.5 KiB
Lua
-- The new-game seed has to fill wVariableSprites, not just the event flags.
|
|
--
|
|
-- luajit tests/gen2_variable_sprites_test.lua
|
|
--
|
|
-- Found by the Gold route bot (tests/drivers/gold_bot.lua): it walked to the
|
|
-- Sudowoodo on Route 36 with the SQUIRTBOTTLE in the bag, faced (35,9), pressed
|
|
-- A and nothing happened -- because there was nothing there.
|
|
--
|
|
-- SPRITE_WEIRD_TREE is $f4, and everything from $f0 up is a wVariableSprites
|
|
-- SLOT rather than a sheet (constants/sprite_constants.asm:147). An object
|
|
-- carrying one is extracted with a NUMBER in `sprite`, World:resolveSprite
|
|
-- answers nil until the slot is filled, and World:pooledNpc spawns nothing --
|
|
-- which is faithful, because on the cart the slots are filled by
|
|
-- InitializeEventsScript, whose last nine commands are `variablesprite`.
|
|
--
|
|
-- The port's seed replayed that script's `setevent` list and dropped the rest,
|
|
-- so a new game had no Sudowoodo -- and therefore no TM08 ROCK SMASH, no
|
|
-- Burned Tower, no Morty, no FOGBADGE and no SURF -- plus no Olivine rival, no
|
|
-- Azalea Rocket, no Fuchsia Gym Janines, no Copycat and no Janine
|
|
-- impersonator.
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local S = require("tests.harness").suite("gen2 variable sprites")
|
|
local check, eq = S.check, S.eq
|
|
|
|
local World = require("src.world.gen2.World")
|
|
|
|
-- The recovery path, in isolation: given the seed's flag list and a scripts
|
|
-- table containing the script those flags came from, find its variablesprite
|
|
-- rows. This is what lets a cache written before the extractor learned to
|
|
-- record them still put the tree on the map.
|
|
do
|
|
local w = setmetatable({
|
|
initialEvents = { 10, 20, 30 },
|
|
scripts = {
|
|
-- A decoy with some of the flags and a sprite row: must NOT match.
|
|
["a:1"] = {
|
|
{ op = "setevent", event = 10 },
|
|
{ op = "variablesprite", args = { 4, 99 } },
|
|
},
|
|
-- The real one: every seed flag, then the sprite assignments.
|
|
["b:1"] = {
|
|
{ op = "setevent", event = 10 },
|
|
{ op = "setevent", event = 20 },
|
|
{ op = "setevent", event = 30 },
|
|
{ op = "variablesprite", args = { 4, 55 } }, -- SPRITE_WEIRD_TREE
|
|
{ op = "variablesprite", args = { 5, 56 } },
|
|
{ op = "end" },
|
|
},
|
|
},
|
|
}, { __index = World })
|
|
|
|
local rows = w:findInitialSprites()
|
|
eq(#rows, 2, "found both variablesprite rows")
|
|
local bySlot = {}
|
|
for _, row in ipairs(rows) do bySlot[row.slot] = row.sprite end
|
|
eq(bySlot[4], 55, "slot 4 ($f4 SPRITE_WEIRD_TREE) takes its sprite")
|
|
eq(bySlot[5], 56, "slot 5 too")
|
|
check(bySlot[4] ~= 99, "the decoy script, which lacks two of the flags, lost")
|
|
end
|
|
|
|
-- No seed list means no guessing: a cache with no flags must not match some
|
|
-- arbitrary script that happens to contain a variablesprite.
|
|
do
|
|
local w = setmetatable({
|
|
initialEvents = {},
|
|
scripts = { ["a:1"] = { { op = "variablesprite", args = { 4, 99 } } } },
|
|
}, { __index = World })
|
|
eq(#w:findInitialSprites(), 0, "an empty seed list matches nothing")
|
|
end
|
|
|
|
-- resolveSprite is the half that reads it back, and the reason an unfilled
|
|
-- slot is invisible rather than merely wrong.
|
|
do
|
|
local w = setmetatable({
|
|
variableSprites = {},
|
|
constants = { spriteOrder = { [55] = "SPRITE_SUDOWOODO" } },
|
|
}, { __index = World })
|
|
eq(w:resolveSprite(0xf4), nil, "an unfilled slot resolves to nothing")
|
|
w.variableSprites[0xf4 - 0xf0] = 55
|
|
eq(w:resolveSprite(0xf4), "SPRITE_SUDOWOODO", "a filled slot names a sheet")
|
|
eq(w:resolveSprite("SPRITE_NURSE"), "SPRITE_NURSE",
|
|
"an ordinary sprite name passes straight through")
|
|
end
|
|
|
|
S.finish()
|