Refuse a TM/HM on a species with no tmhm list instead of crashing

ItemEffects.use walked speciesDef.tmhm with a bare ipairs() to check
whether the species could learn the machine's move. A record with no
tmhm field at all -- a mod species that never set one, or any record
missing it for whatever reason -- hit ipairs(nil) and took the whole
game down on the first TM/HM use, rather than reaching the ordinary
"can't learn that move" refusal a species whose list simply omits the
move already gets.

An absent list now reads the same as an empty one: nothing to learn,
same refusal, same sound, same text.
This commit is contained in:
sanjinpepic
2026-08-16 20:13:14 +02:00
parent f62b1268c8
commit 2da2168dac
2 changed files with 35 additions and 1 deletions
+4 -1
View File
@@ -515,7 +515,10 @@ function ItemEffects.use(data, save, itemId, target, battle, moveIndex, ow)
if not target then return "failed", { noEffect(data) } end
local speciesDef = data.pokemon[target.species]
local ok = false
for _, m in ipairs(speciesDef.tmhm) do
-- a species record with no tmhm list at all is "teaches nothing", the
-- same as one whose list just does not name this move -- not a reason
-- to crash instead of refusing normally
for _, m in ipairs(speciesDef.tmhm or {}) do
if m == itemDef.machine.move then ok = true break end
end
if not ok then
+31
View File
@@ -0,0 +1,31 @@
-- ItemEffects.use crashed instead of refusing when a species record carried
-- no tmhm list at all (ipairs(nil)), which is a different situation from a
-- species whose list simply does not name the move being taught -- that
-- case already refuses cleanly with MonCannotLearnMachineMoveText. A mod
-- species missing the field entirely took the whole game down on the very
-- first TM/HM use rather than reaching that refusal.
package.path = "./?.lua;./?/init.lua;" .. package.path
if not _G.love then _G.love = require("tests.love_stub") end
local T = require("tests.harness").suite("item effects tmhm nil")
local Fixtures = require("tests.modkit.fixtures")
local ItemEffects = require("src.inventory.ItemEffects")
local Pokemon = require("src.pokemon.Pokemon")
local Data = Fixtures.fresh()
Data.pokemon.FIXMON_A.tmhm = nil
local mon = Pokemon.new(Data, "FIXMON_A", 10)
local save = { player = { name = "RED" } }
local ok, result, payload = pcall(ItemEffects.use, Data, save, "FIX_TM", mon)
T.check(ok, "using a TM on a species with no tmhm list does not crash: "
.. tostring(result))
if ok then
T.eq(result, "failed", "the species refuses the move instead of crashing into it")
T.check(type(payload) == "table" and payload[1] ~= nil,
"a refusal message is still returned")
end
T.finish()