fix(game3): fix level-up move learn soft lock when mon has free move slots

LearnMove.begin's free-slot path called say(text, cb) expecting pushMsg
to invoke the callback once the message is dismissed. The battle UI's
hooks.pushMsg is Ui.push which only accepts (text) and silently drops
the callback, so finish(ok) was never called, LearnMove._active stayed
true forever → soft lock (reported as Charmander learning Ember).

Fix: set _pending="done" + _pendingResult before say() so pump() can
complete the sequence on the next update tick once the dialog drains,
matching how the 4-move full path already uses _pending="delete".
The say() callback is still wired so contexts whose pushMsg does honour
it (party_menu TM flow) finish inline as before.
This commit is contained in:
1jamie
2026-09-11 16:50:56 -05:00
parent 0ec555b25b
commit dc9d5c74c7
+17 -2
View File
@@ -32,6 +32,7 @@ function LearnMove.reset()
LearnMove._onDone = nil
LearnMove._waitingChoice = false
LearnMove._pending = nil
LearnMove._pendingResult = false
LearnMove._forgetSlots = nil
LearnMove._queue = nil
LearnMove._queueIdx = 0
@@ -181,7 +182,10 @@ function LearnMove.pump()
return false -- still active, waiting for finish from choice path or free teach
end
LearnMove._pending = nil
if pending == "delete" then
if pending == "done" then
local r = LearnMove._pendingResult
finish(r)
elseif pending == "delete" then
open_delete_prompt()
elseif pending == "stop" then
open_stop_prompt()
@@ -225,8 +229,19 @@ function LearnMove.begin(opts)
say(LearnMove._name .. " learned\n" .. LearnMove._moveName .. "!")
finish(ok)
else
-- pushMsg in the battle context (Ui.push) does not honour the callback,
-- so we cannot rely on say(..., cb) to call finish(). Instead we queue
-- the message then set _pending="done" so pump() finishes us once the
-- battle dialog drains. If pushMsg does honour the callback the say()
-- call fires it immediately and we finish inline; _pending is cleared
-- by finish() via reset() so the pump path is a safe no-op.
LearnMove._pendingResult = ok
LearnMove._pending = "done"
say(LearnMove._name .. " learned\n" .. LearnMove._moveName .. "!", function()
finish(ok)
if LearnMove._active and LearnMove._pending == "done" then
LearnMove._pending = nil
finish(ok)
end
end)
end
else