i did it for greg

This commit is contained in:
bryanthaboi
2026-08-14 17:07:06 -04:00
parent 4395792226
commit c8f6c7241b
9 changed files with 205 additions and 12 deletions
+92
View File
@@ -0,0 +1,92 @@
-- trainers.trueColor: the same 4-shade opt-out pokemon and sprites already
-- carry, now on the trainers registry. ROM-free.
-- luajit tests/engine/trainer_true_color.lua
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.modkit")
local BattleState = require("src.battle.BattleState")
local Gen2Battle = require("src.ui.gen2.BattleState")
local Schemas = require("src.mods.Schemas")
local OakSpeech = require("src.ui.OakSpeech")
local spec = Schemas.REGISTRIES.trainers
T.check(spec.fields.trueColor ~= nil,
"Gen 1 trainers schema lists trueColor")
T.check(Schemas.check(spec, "trainers", "OPP_BROCK",
{ trueColor = true }, "patch"),
"a trueColor patch validates")
T.check(not Schemas.check(spec, "trainers", "OPP_BROCK",
{ trueColor = "yes" }, "patch"),
"trueColor rejects a non-boolean")
local gen2 = Schemas.shapeFor("trainers", spec, 2)
T.check(gen2.fields.trueColor ~= nil and gen2.fields.pic ~= nil,
"Gold trainers schema lists pic and trueColor")
T.check(Schemas.check(spec, "trainers", "BEAUTY",
{ pic = "mods/x/beauty.png", trueColor = true },
"patch", 2),
"a Gold pic+trueColor patch validates")
T.eq(BattleState.trainerTrueColor(nil, nil), false,
"no trainer is not trueColor")
T.eq(BattleState.trainerTrueColor(nil, { pic = "a.png" }), false,
"a vanilla portrait is not trueColor")
T.eq(BattleState.trainerTrueColor(nil, { trueColor = true }), true,
"the record's own flag wins")
T.eq(BattleState.trainerTrueColor(nil, { trueColor = false }), false,
"explicit false stays false")
local data = {
trainers = {
BASE = { pic = "base.png", trueColor = true },
VANILLA = { pic = "vanilla.png" },
},
}
T.eq(BattleState.trainerTrueColor(data, { basePic = "BASE" }), true,
"a basePic reuse inherits the base flag")
T.eq(BattleState.trainerTrueColor(data,
{ basePic = "BASE", trueColor = false }), false,
"an explicit false on the subclass beats the base")
T.eq(BattleState.trainerTrueColor(data, { basePic = "VANILLA" }), false,
"reusing a vanilla base stays unshaded-off")
local goldData = {
gen2Trainers = {
classes = {
BEAUTY = { pic = "mods/x/beauty.png", trueColor = true },
BUG_CATCHER = {},
},
},
gen2MenuGfx = {
battleHud = {
trainerPics = {
BEAUTY = "assets/generated/trainers/beauty.png",
BUG_CATCHER = "assets/generated/trainers/bug_catcher.png",
},
},
},
}
local beautyPath, beautyTc = Gen2Battle.trainerArt(goldData, "BEAUTY")
T.eq(beautyPath, "mods/x/beauty.png",
"a class pic wins over the extracted sheet")
T.eq(beautyTc, true, "and keeps trueColor")
local bugPath, bugTc = Gen2Battle.trainerArt(goldData, "BUG_CATCHER")
T.eq(bugPath, "assets/generated/trainers/bug_catcher.png",
"a class without pic keeps the extracted sheet")
T.eq(bugTc, false, "and is not trueColor")
T.eq(select(1, Gen2Battle.trainerArt(goldData, nil)), nil,
"no class is no pic")
local game = {
data = {
trainers = {
OPP_BROCK = { pic = "brock.png", trueColor = true },
OPP_PROF_OAK = { pic = "oak.png", trueColor = true },
},
},
}
local _, _, oakTc = OakSpeech.resolvePic(game,
{ type = "trainer", id = "OPP_BROCK" })
T.eq(oakTc, true, "OakSpeech reports a trainer record's trueColor")
T.finish("trainer true color")
+15
View File
@@ -23,6 +23,7 @@ local MoveEffects = require("src.battle.MoveEffects")
local Pokemon = require("src.pokemon.Pokemon")
local Runtime = require("src.mods.Runtime")
local SaveData = require("src.core.SaveData")
local Schemas = require("src.mods.Schemas")
local Status = require("src.battle.Status")
local TrainerAI = require("src.battle.TrainerAI")
local TurnOrder = require("src.battle.TurnOrder")
@@ -346,6 +347,20 @@ do
check(BattleState.trainerPicPath(Data, { basePic = "OPP_ENGINEER" })
== Data.trainers.OPP_ENGINEER.pic,
"a custom trainer can reuse a base trainer portrait by id")
check(BattleState.trainerTrueColor(Data, { trueColor = true }) == true,
"a trainer record's trueColor flag is readable")
check(BattleState.trainerTrueColor(Data, { trueColor = false }) == false,
"explicit false stays false")
check(BattleState.trainerTrueColor(Data, { basePic = "OPP_ENGINEER" })
== false,
"a vanilla base portrait is not trueColor")
check(Schemas.check(Schemas.REGISTRIES.trainers, "trainers", "OPP_BROCK",
{ trueColor = true }, "patch"),
"a trueColor trainers patch validates against the catalog schema")
check(Schemas.check(Schemas.REGISTRIES.trainers, "trainers", "BEAUTY",
{ pic = "mods/x/beauty.png", trueColor = true },
"patch", 2),
"a Gold trainers patch can carry pic and trueColor")
end
do
+26
View File
@@ -370,6 +370,32 @@ check(math.abs(r - 0.4) < 1e-6 and math.abs(g - 0.7) < 1e-6
and math.abs(b - 0.9) < 1e-6,
"a trueColor pic keeps a pixel no 4-shade palette contains")
-- trainers.trueColor is the same opt-out on a class portrait
BattleState.invalidate()
local trainerPicData = {
trainers = {
SHADED = { pic = "assets/generated/battle/front/shaded.png" },
FULLCOLOR = { pic = "assets/generated/battle/front/full.png",
trueColor = true },
REUSED = { basePic = "FULLCOLOR" },
},
palettes = { palettes = { MEWMON = monPalette }, pokemon = {} },
}
local shadedTrainer = BattleState.trainerSprite(trainerPicData,
trainerPicData.trainers.SHADED)
r, g, b = shadedTrainer.data:getPixel(0, 0)
check(r == 0 and g == 0 and b == 1,
"a 4-shade trainer pic is palette-quantized onto its shade bucket")
local fullTrainer = BattleState.trainerSprite(trainerPicData,
trainerPicData.trainers.FULLCOLOR)
r, g, b = fullTrainer.data:getPixel(0, 0)
check(math.abs(r - 0.4) < 1e-6 and math.abs(g - 0.7) < 1e-6
and math.abs(b - 0.9) < 1e-6,
"a trueColor trainer pic keeps a pixel no 4-shade palette contains")
check(BattleState.trainerTrueColor(trainerPicData,
trainerPicData.trainers.REUSED) == true,
"a basePic reuse inherits the base portrait's trueColor flag")
-- ------- trueColor: the colors == false zone sentinel
check(PaletteFX.zone(nil, 0, 0, 1, 1) == nil, "nil colors is still no zone")