CLOSES #1206, CLOSES #1189, CLOSES #1175, CLOSES #1129, CLOSES #1119, CLOSES #1089, CLOSES #1073, CLOSES #1069, CLOSES #1065, CLOSES #1010, CLOSES #990, CLOSES #989, CLOSES #988, CLOSES #978, CLOSES #944, CLOSES #936, CLOSES #1221, CLOSES #1220, CLOSES #1193, CLOSES #1101, CLOSES #1066, CLOSES #1056, CLOSES #1041, CLOSES #984, CLOSES #1225, CLOSES #1214, CLOSES #1011, CLOSES #1035, CLOSES #1219, CLOSES #1048, CLOSES #1047, CLOSES #964, CLOSES #949, CLOSES #1149, CLOSES #1007, CLOSES #914, CLOSES #1115, CLOSES #1146, CLOSES #999, CLOSES #1207, CLOSES #1029, CLOSES #1120, CLOSES #987, CLOSES #983

This commit is contained in:
bryanthaboi
2026-08-13 13:07:20 -04:00
parent 833388c235
commit 37051a26b5
43 changed files with 752 additions and 135 deletions
+82
View File
@@ -0,0 +1,82 @@
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.harness")
local ItemEffects = require("src.core.gen2.ItemEffects")
local Game2 = require("src.core.Game2")
local Screens = require("src.ui.Screens")
local EvolutionAnim = require("src.ui.gen2.EvolutionAnim")
local data = {
pokemon = {
SUNKERN = {
evolutions = {
{ method = "EVOLVE_ITEM", item = "SUN_STONE", into = "SUNFLORA" },
},
},
},
}
local mon = { species = "SUNKERN", item = nil }
T.eq(ItemEffects.partyAction("SUN_STONE"), "stone",
"SUN STONE opens the party target flow")
local result = ItemEffects.useOnMon("SUN_STONE", mon, data)
T.check(result.used, "SUN STONE succeeds on SUNKERN")
T.eq(result.evolution and result.evolution.into, "SUNFLORA",
"SUN STONE selects SUNFLORA")
mon.item = "EVERSTONE"
result = ItemEffects.useOnMon("SUN_STONE", mon, data)
T.check(not result.used, "held EVERSTONE refuses the evolution")
local function startStone()
local partyOptions, evolutionOptions
local game = setmetatable({
data = {
pokemon = data.pokemon,
screens = {
Gen2PartyMenu = function(_, options)
partyOptions = options
return {}
end,
Gen2EvolutionAnim = function(_, options)
evolutionOptions = options
return {}
end,
},
},
save = {
party = { { species = "SUNKERN", item = nil } },
inventory = { SUN_STONE = 1 },
},
stack = { pop = function() end, push = function() end },
}, Game2)
Screens.invalidate()
game:usePartyItem("SUN_STONE")
partyOptions.onChoose(nil, game.save.party[1])
return game, evolutionOptions
end
local game, evolution = startStone()
T.check(evolution.force, "SUN STONE evolution sets wForceEvolution")
T.eq(game.save.inventory.SUN_STONE, 1,
"SUN STONE remains until evolution succeeds")
local animation = EvolutionAnim.new({ data = { pokemon = data.pokemon } }, {
mon = game.save.party[1], entry = evolution and evolution.entry,
force = evolution and evolution.force,
})
T.check(not animation:cancelPressed({ wasPressed = function(_, key)
return key == "b"
end }), "B cannot cancel a forced stone evolution")
evolution.onDone({ canceled = true })
T.eq(game.save.inventory.SUN_STONE, 1,
"a canceled evolution does not consume SUN STONE")
game, evolution = startStone()
evolution.onDone({ evolved = { species = "SUNFLORA" } })
T.eq(game.save.inventory.SUN_STONE, nil,
"a completed evolution consumes SUN STONE")
Screens.invalidate()
T.finish("gen2 sun stone bug 1219")
+5 -4
View File
@@ -65,7 +65,7 @@ T.check(pushed[1].text:find(BYE, 1, true) == nil,
pushed[1].onDone()
T.eq(#pushed, 1, "the farewell waits for the bow")
T.eq(nurse.facing, "up", "image index $14: the nurse bows")
T.eq(nurse.frameOverride, 3, "image index $1: the nurse bows")
T.check(fakeSelf.emote ~= nil, "the bow is a world hold, not a text pause")
local hold = fakeSelf.emote or {}
T.eq(hold.npc, nurse, "the hold is anchored on the nurse")
@@ -79,11 +79,12 @@ if hold.onDone then hold.onDone() end
T.eq(#pushed, 2, "the farewell follows the bow")
local farewell = pushed[2] or {}
T.eq(farewell.text, BYE, "second box is the farewell text")
T.eq(nurse.facing, "up", "she is still bowed while the farewell prints")
T.eq(nurse.frameOverride, nil, "the bow ends before the farewell prints")
T.eq(nurse.facing, "down", "the nurse faces the player for the farewell")
if farewell.onDone then farewell.onDone() end
T.eq(nurse.facing, "down", "the trailing UpdateSprites faces her back")
T.eq(faced, 1, "she is turned back exactly once")
T.eq(nurse.facing, "down", "the trailing UpdateSprites keeps her facing")
T.eq(faced, 2, "she is turned back before and after the farewell")
T.eq(finished, 1, "control returns to the player once, after the farewell")
-- === no nurse sprite (the Yellow/rest-stop callers): no bow, same text
+55
View File
@@ -0,0 +1,55 @@
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.harness")
local GenSave = require("src.save_convert.GenSave")
local romText = require("src.core.RomText")
local localized = {
text = {
_MoveIsDisabledText = "The move {RAM:wNameBuffer} from {USER} is disabled!",
},
}
T.eq(romText(localized, "_MoveIsDisabledText", "%s's %s is disabled!", {
USER = "PIKACHU", ["RAM:wNameBuffer"] = "THUNDER",
}), "The move THUNDER from PIKACHU is disabled!",
"named ROM tokens survive translation reordering")
GenSave.setCharmap(loadfile("src/save_convert/data/charmap.lua")())
local data = {
pokemon = {}, moves = {}, items = {}, maps = {},
hiddenItems = loadfile("src/save_convert/data/hidden_items.lua")(),
}
local save = {
player = { name = "RED", id = 1, map = "PALLET_TOWN", x = 0, y = 0 },
rival = { name = "BLUE" }, party = {}, boxes = {}, inventory = {},
pcItems = {}, flags = {}, pokedex = { seen = {}, owned = {} },
hiddenTaken = {
VIRIDIAN_FOREST_1_18 = true,
VIRIDIAN_CITY_14_4 = true,
},
}
for i = 1, 12 do save.boxes[i] = {} end
local bytes = GenSave.encode(save, data, nil)
local decoded = GenSave.decode(bytes, data)
T.check(decoded.hiddenTaken.VIRIDIAN_FOREST_1_18,
"Viridian Forest hidden potion imports from wObtainedHiddenItemsFlags")
T.check(decoded.hiddenTaken.VIRIDIAN_CITY_14_4,
"Viridian City hidden potion imports from wObtainedHiddenItemsFlags")
T.check(not decoded.hiddenTaken.ROUTE_9_14_7,
"an uncollected hidden item remains available")
love = love or require("tests.love_stub")
local start = require("src.ui.StartMenu").new({
data = {}, save = {
flags = {}, party = {}, inventory = {}, options = {},
player = { name = "RED" }, pokedex = { owned = {} },
},
})
local pokemonRow
for _, row in ipairs(start.items) do
if row.label == "POKéMON" then pokemonRow = row break end
end
T.check(pokemonRow and pokemonRow.keepOpen,
"the empty-party POKéMON row leaves the start menu open")
T.finish("open menu bugs 949 and 1149")