mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
162 lines
5.4 KiB
Lua
162 lines
5.4 KiB
Lua
-- ../pokecrystal/engine/battle/effect_commands.asm:1546
|
|
-- ../pokecrystal/engine/battle/effect_commands.asm:5475
|
|
-- ../pokecrystal/data/moves/effects.asm:1011
|
|
local U = require("tests.drivers.util")
|
|
|
|
local Mon = require("src.battle.gen2.Mon")
|
|
|
|
return function(game)
|
|
local out = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/crystal-dig-2139"
|
|
os.execute("mkdir -p '" .. out .. "'")
|
|
local fails = 0
|
|
local function ok(cond, line)
|
|
if not cond then fails = fails + 1 end
|
|
print("[dig-2139] " .. (cond and "PASS " or "FAIL ") .. line)
|
|
end
|
|
|
|
U.wait(45)
|
|
local world = game.world
|
|
assert(world and world.map, "the crystal world did not boot")
|
|
|
|
local lead = Mon.new(game.data, "ALAKAZAM", 50)
|
|
assert(lead, "could not build an ALAKAZAM")
|
|
lead.moves = {
|
|
{ id = "REFLECT", pp = 20, maxPp = 20 },
|
|
{ id = "RECOVER", pp = 20, maxPp = 20 },
|
|
{ id = "EARTHQUAKE", pp = 10, maxPp = 10 },
|
|
{ id = "ICE_PUNCH", pp = 15, maxPp = 15 },
|
|
}
|
|
game.save.party = { lead }
|
|
game.save.inventory = { POKE_BALL = 5 }
|
|
|
|
local wild = Mon.new(game.data, "HITMONTOP", 30)
|
|
assert(wild, "could not build a wild HITMONTOP")
|
|
wild.moves = { { id = "DIG", pp = 10, maxPp = 10 } }
|
|
wild.stats.speed = 1
|
|
wild.hp = wild.maxHp or wild.hp
|
|
|
|
assert(world:startBattle({ wild = wild }), "startBattle failed")
|
|
local screen
|
|
for _ = 1, 600 do
|
|
local top = game.stack:top()
|
|
if top and top.battle then screen = top break end
|
|
U.wait(1)
|
|
end
|
|
assert(screen and screen.battle, "battle screen never came up")
|
|
|
|
local messages = {}
|
|
local realPush = screen.pushAll
|
|
screen.pushAll = function(self, events)
|
|
for _, event in ipairs(events or {}) do
|
|
if event.kind == "message" and event.text then
|
|
messages[#messages + 1] = event.text
|
|
end
|
|
end
|
|
return realPush(self, events)
|
|
end
|
|
local function sawText(needle)
|
|
for _, text in ipairs(messages) do
|
|
if text:find(needle, 1, true) then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function toMenu(tag)
|
|
for _ = 1, 900 do
|
|
if screen.phase == "menu" then break end
|
|
U.tap(game, "a")
|
|
U.wait(2)
|
|
end
|
|
ok(screen.phase == "menu", tag .. ": reached the battle menu")
|
|
end
|
|
|
|
local function pickMove(index)
|
|
U.tap(game, "a")
|
|
U.wait(4)
|
|
for _ = 1, 8 do
|
|
local at = screen.moveIndex or 1
|
|
if at == index then break end
|
|
U.tap(game, at < index and "down" or "up")
|
|
U.wait(2)
|
|
end
|
|
U.tap(game, "a")
|
|
for _ = 1, 60 do
|
|
if screen.phase ~= "menu" then break end
|
|
U.wait(1)
|
|
end
|
|
end
|
|
|
|
local enemy = screen.battle.enemy
|
|
local enemyVol = screen.battle:volatile(enemy)
|
|
|
|
toMenu("turn1")
|
|
pickMove(1)
|
|
local shotDuringPlayerMove, boxUpDuringPlayerMove = false, true
|
|
local sawCharge = false
|
|
for tick = 1, 900 do
|
|
if screen.phase == "menu" or game.stack:top() ~= screen then break end
|
|
if not sawCharge and enemyVol.vanished then
|
|
if screen.vanishSeen and screen.vanishSeen.enemy then
|
|
sawCharge = true
|
|
elseif screen.anim or (screen.message and
|
|
tostring(screen.message):find("REFLECT", 1, true)) then
|
|
if screen:picBoxCleared("enemy") or screen:isUnderground("enemy") then
|
|
boxUpDuringPlayerMove = false
|
|
end
|
|
if not shotDuringPlayerMove then
|
|
shotDuringPlayerMove = true
|
|
U.shot(game, ("%s/2139_fix_turn1_t%03d.png"):format(out, tick))
|
|
end
|
|
end
|
|
end
|
|
if (screen.messageTimer or 0) > 0 then U.tap(game, "a") end
|
|
U.wait(1)
|
|
end
|
|
ok(shotDuringPlayerMove, "turn1: the player's move was replayed with the flag up")
|
|
ok(boxUpDuringPlayerMove,
|
|
"turn1: the enemy's pic box stayed on screen during the player's move")
|
|
ok(sawCharge, "turn1: the charge event was replayed")
|
|
toMenu("turn1-end")
|
|
ok(enemyVol.vanished == true, "turn1: HITMONTOP is underground after the turn")
|
|
ok(screen:isUnderground("enemy"), "turn1: and its box is now empty")
|
|
ok(not sawText("attack missed"), "turn1: Reflect did not print 'attack missed!'")
|
|
ok((screen.battle.screens.player.reflect or 0) > 0, "turn1: Reflect is up")
|
|
U.shot(game, out .. "/2139_fix_turn1_end.png")
|
|
|
|
messages = {}
|
|
lead.hp = math.max(1, math.floor((lead.maxHp or lead.hp) / 2))
|
|
local hpBefore = lead.hp
|
|
pickMove(2)
|
|
for _ = 1, 900 do
|
|
if screen.phase == "menu" or game.stack:top() ~= screen then break end
|
|
if (screen.messageTimer or 0) > 0 then U.tap(game, "a") end
|
|
U.wait(1)
|
|
end
|
|
toMenu("turn2")
|
|
ok(not sawText("attack missed"), "turn2: Recover did not print 'attack missed!'")
|
|
ok(lead.hp > hpBefore, "turn2: Recover healed while the target was underground")
|
|
ok(enemyVol.vanished == nil or enemyVol.vanished == false,
|
|
"turn2: the stored Dig came out")
|
|
ok(not screen:isUnderground("enemy") and not screen.picHidden.enemy,
|
|
"turn2: the enemy's box is back")
|
|
U.shot(game, out .. "/2139_fix_turn2_end.png")
|
|
|
|
messages = {}
|
|
enemyVol.vanished = true
|
|
enemyVol.chargeMove = "DIG"
|
|
local enemyHp = enemy.hp
|
|
pickMove(3)
|
|
for _ = 1, 900 do
|
|
if screen.phase == "menu" or game.stack:top() ~= screen then break end
|
|
if (screen.messageTimer or 0) > 0 then U.tap(game, "a") end
|
|
U.wait(1)
|
|
end
|
|
ok(enemy.hp < enemyHp, "turn3: Earthquake damaged the dug-in HITMONTOP")
|
|
ok(not sawText("attack missed"), "turn3: and did not miss")
|
|
U.shot(game, out .. "/2139_fix_turn3_end.png")
|
|
|
|
print("[dig-2139] " .. (fails == 0 and "PASS all claims" or
|
|
(fails .. " claims failed")))
|
|
love.event.quit(fails == 0 and 0 or 1)
|
|
end
|