mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 19:24:01 +02:00
fix true color UI Pokemon sprites
The UI drew sprite paths but discarded their trueColor flag, so the SGB palette pass recolored full-color Pokemon.
This commit is contained in:
@@ -35,14 +35,15 @@ function DexEntryMenu.new(game, speciesOrOpts)
|
|||||||
local species, forceOwned = resolveArgs(speciesOrOpts)
|
local species, forceOwned = resolveArgs(speciesOrOpts)
|
||||||
local self = setmetatable({ game = game, forceOwned = forceOwned }, DexEntryMenu)
|
local self = setmetatable({ game = game, forceOwned = forceOwned }, DexEntryMenu)
|
||||||
self.def = game.data.pokemon[species]
|
self.def = game.data.pokemon[species]
|
||||||
local path = require("src.pokemon.Sprites").path(game.data, species, "front",
|
local path, trueColor = require("src.pokemon.Sprites").path(
|
||||||
{ kind = "dex" })
|
game.data, species, "front", { kind = "dex" })
|
||||||
-- `path and pcall(...)` truncates to one value, so img was always nil and
|
-- `path and pcall(...)` truncates to one value, so img was always nil and
|
||||||
-- every dex page drew without its pic (#307); the guard has to be a
|
-- every dex page drew without its pic (#307); the guard has to be a
|
||||||
-- statement for pcall's second return to survive.
|
-- statement for pcall's second return to survive.
|
||||||
local ok, img = false, nil
|
local ok, img = false, nil
|
||||||
if path then ok, img = pcall(love.graphics.newImage, path) end
|
if path then ok, img = pcall(love.graphics.newImage, path) end
|
||||||
self.sprite = ok and img or nil
|
self.sprite = ok and img or nil
|
||||||
|
self.spriteTrueColor = self.sprite and trueColor or false
|
||||||
require("src.core.Sound").playCry(game.data, species)
|
require("src.core.Sound").playCry(game.data, species)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -59,7 +60,12 @@ function DexEntryMenu:draw()
|
|||||||
love.graphics.rectangle("fill", 0, 0, 160, 144)
|
love.graphics.rectangle("fill", 0, 0, 160, 144)
|
||||||
local def = self.def
|
local def = self.def
|
||||||
if self.sprite then
|
if self.sprite then
|
||||||
love.graphics.draw(self.sprite, 8, math.max(0, 60 - self.sprite:getHeight()))
|
local y = math.max(0, 60 - self.sprite:getHeight())
|
||||||
|
love.graphics.draw(self.sprite, 8, y)
|
||||||
|
if self.spriteTrueColor then
|
||||||
|
require("src.render.PaletteFX").markTrueColor(
|
||||||
|
8, y, self.sprite:getDimensions())
|
||||||
|
end
|
||||||
end
|
end
|
||||||
love.graphics.setColor(0, 0, 0, 1)
|
love.graphics.setColor(0, 0, 0, 1)
|
||||||
Font.draw(def.name, 72, 8)
|
Font.draw(def.name, 72, 8)
|
||||||
|
|||||||
+34
-19
@@ -61,7 +61,7 @@ local function tryImage(path)
|
|||||||
return ok and img or nil
|
return ok and img or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Resolve a pic descriptor to (image, flip).
|
-- Resolve a pic descriptor to (image, flip, trueColor).
|
||||||
-- Descriptors:
|
-- Descriptors:
|
||||||
-- "oak" | "rival" | "player" shorthand
|
-- "oak" | "rival" | "player" shorthand
|
||||||
-- { type = "trainer", id = "OPP_PROF_OAK" }
|
-- { type = "trainer", id = "OPP_PROF_OAK" }
|
||||||
@@ -70,7 +70,7 @@ end
|
|||||||
-- { type = "image", path = "..." }
|
-- { type = "image", path = "..." }
|
||||||
-- { type = "sprite", id = "SPRITE_RED" }
|
-- { type = "sprite", id = "SPRITE_RED" }
|
||||||
function OakSpeech.resolvePic(game, desc, speech)
|
function OakSpeech.resolvePic(game, desc, speech)
|
||||||
if desc == nil then return nil, false end
|
if desc == nil then return nil, false, false end
|
||||||
if type(desc) == "string" then
|
if type(desc) == "string" then
|
||||||
if desc == "oak" then
|
if desc == "oak" then
|
||||||
desc = { type = "trainer", id = "OPP_PROF_OAK" }
|
desc = { type = "trainer", id = "OPP_PROF_OAK" }
|
||||||
@@ -86,35 +86,37 @@ function OakSpeech.resolvePic(game, desc, speech)
|
|||||||
local t = desc.type
|
local t = desc.type
|
||||||
if t == "trainer" then
|
if t == "trainer" then
|
||||||
if speech and desc.id == "OPP_PROF_OAK" and speech.oakPic then
|
if speech and desc.id == "OPP_PROF_OAK" and speech.oakPic then
|
||||||
return speech.oakPic, false
|
return speech.oakPic, false, false
|
||||||
end
|
end
|
||||||
if speech and desc.id == "OPP_RIVAL1" and speech.rivalPic then
|
if speech and desc.id == "OPP_RIVAL1" and speech.rivalPic then
|
||||||
return speech.rivalPic, false
|
return speech.rivalPic, false, false
|
||||||
end
|
end
|
||||||
local trainers = game.data.trainers or {}
|
local trainers = game.data.trainers or {}
|
||||||
local tr = trainers[desc.id]
|
local tr = trainers[desc.id]
|
||||||
return tryImage(tr and tr.pic), false
|
return tryImage(tr and tr.pic), false, false
|
||||||
elseif t == "pokemon" then
|
elseif t == "pokemon" then
|
||||||
if speech and desc.id == speech.demoSpecies and speech.demoPic then
|
if speech and desc.id == speech.demoSpecies and speech.demoPic then
|
||||||
return speech.demoPic, desc.flip and true or false
|
return speech.demoPic, desc.flip and true or false, speech.demoTrueColor
|
||||||
end
|
end
|
||||||
local path = require("src.pokemon.Sprites").path(
|
local path, trueColor = require("src.pokemon.Sprites").path(
|
||||||
game.data, desc.id, "front", { kind = "oak" })
|
game.data, desc.id, "front", { kind = "oak" })
|
||||||
return tryImage(path), desc.flip and true or false
|
return tryImage(path), desc.flip and true or false, trueColor
|
||||||
elseif t == "player" then
|
elseif t == "player" then
|
||||||
if speech and speech.playerPic and not desc.path then
|
if speech and speech.playerPic and not desc.path then
|
||||||
return speech.playerPic, false
|
return speech.playerPic, false, speech.playerTrueColor
|
||||||
end
|
end
|
||||||
if desc.path then return tryImage(desc.path), false end
|
if desc.path then return tryImage(desc.path), false, false end
|
||||||
return tryImage(require("src.pokemon.Sprites").playerPath(
|
local path, trueColor = require("src.pokemon.Sprites").playerPath(
|
||||||
game.data, "front", { kind = "intro" })), false
|
game.data, "front", { kind = "intro" })
|
||||||
|
return tryImage(path), false, trueColor
|
||||||
elseif t == "image" then
|
elseif t == "image" then
|
||||||
return tryImage(desc.path), desc.flip and true or false
|
return tryImage(desc.path), desc.flip and true or false, false
|
||||||
elseif t == "sprite" then
|
elseif t == "sprite" then
|
||||||
local sp = game.data.sprites and game.data.sprites[desc.id]
|
local sp = game.data.sprites and game.data.sprites[desc.id]
|
||||||
return tryImage(sp and sp.image), desc.flip and true or false
|
return tryImage(sp and sp.image), desc.flip and true or false,
|
||||||
|
sp and sp.trueColor or false
|
||||||
end
|
end
|
||||||
return nil, false
|
return nil, false, false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Vanilla step list. Ids are the stable anchors mods insert around.
|
-- Vanilla step list. Ids are the stable anchors mods insert around.
|
||||||
@@ -219,15 +221,18 @@ function OakSpeech.new(game, onDone)
|
|||||||
-- the show-off mon and the name length cap come from data; the vanilla
|
-- the show-off mon and the name length cap come from data; the vanilla
|
||||||
-- literals stay as the fallbacks
|
-- literals stay as the fallbacks
|
||||||
self.demoSpecies = oakGfx.demoSpecies or "NIDORINO"
|
self.demoSpecies = oakGfx.demoSpecies or "NIDORINO"
|
||||||
local demoPath = require("src.pokemon.Sprites").path(
|
local demoPath, demoTrueColor = require("src.pokemon.Sprites").path(
|
||||||
game.data, self.demoSpecies, "front", { kind = "oak" })
|
game.data, self.demoSpecies, "front", { kind = "oak" })
|
||||||
self.demoPic = tryImage(demoPath)
|
self.demoPic = tryImage(demoPath)
|
||||||
|
self.demoTrueColor = self.demoPic and demoTrueColor or false
|
||||||
local constants = game.data.constants or {}
|
local constants = game.data.constants or {}
|
||||||
self.nameLen = constants.playerNameLength or 7
|
self.nameLen = constants.playerNameLength or 7
|
||||||
-- RedPicFront (gfx/player/red.png, shared with the trainer card) and
|
-- RedPicFront (gfx/player/red.png, shared with the trainer card) and
|
||||||
-- the ShrinkPic1/ShrinkPic2 frames (gfx/player/shrink{1,2}.png)
|
-- the ShrinkPic1/ShrinkPic2 frames (gfx/player/shrink{1,2}.png)
|
||||||
self.playerPic = tryImage(require("src.pokemon.Sprites").playerPath(
|
local playerPath, playerTrueColor = require("src.pokemon.Sprites").playerPath(
|
||||||
game.data, "front", { kind = "intro" }))
|
game.data, "front", { kind = "intro" })
|
||||||
|
self.playerPic = tryImage(playerPath)
|
||||||
|
self.playerTrueColor = self.playerPic and playerTrueColor or false
|
||||||
self.shrinkPic1 = tryImage(oakGfx.shrink1
|
self.shrinkPic1 = tryImage(oakGfx.shrink1
|
||||||
or "assets/generated/intro/shrink1.png")
|
or "assets/generated/intro/shrink1.png")
|
||||||
self.shrinkPic2 = tryImage(oakGfx.shrink2
|
self.shrinkPic2 = tryImage(oakGfx.shrink2
|
||||||
@@ -278,14 +283,17 @@ end
|
|||||||
|
|
||||||
function OakSpeech:applyPic(step)
|
function OakSpeech:applyPic(step)
|
||||||
if step.pic == nil then return end
|
if step.pic == nil then return end
|
||||||
local img, flip = OakSpeech.resolvePic(self.game, step.pic, self)
|
local img, flip, trueColor = OakSpeech.resolvePic(self.game, step.pic, self)
|
||||||
if img then
|
if img then
|
||||||
self.pic = img
|
self.pic = img
|
||||||
self.picFlip = flip or false
|
self.picFlip = flip or false
|
||||||
|
self.picTrueColor = trueColor or false
|
||||||
elseif step.pic == "player" or (type(step.pic) == "table" and step.pic.type == "player") then
|
elseif step.pic == "player" or (type(step.pic) == "table" and step.pic.type == "player") then
|
||||||
-- mirror the old fallback: player pic missing → oak
|
-- mirror the old fallback: player pic missing → oak
|
||||||
self.pic = self.playerPic or self.oakPic
|
self.pic = self.playerPic or self.oakPic
|
||||||
self.picFlip = false
|
self.picFlip = false
|
||||||
|
self.picTrueColor = self.pic == self.playerPic and self.playerTrueColor
|
||||||
|
or false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -342,6 +350,7 @@ function OakSpeech:runStep(step)
|
|||||||
-- NIDORINO show-off: mirrored front sprite + wipe + cry + text 2A
|
-- NIDORINO show-off: mirrored front sprite + wipe + cry + text 2A
|
||||||
self.pic = self.demoPic
|
self.pic = self.demoPic
|
||||||
self.picFlip = true
|
self.picFlip = true
|
||||||
|
self.picTrueColor = self.demoTrueColor
|
||||||
self:revealPic("wipe", function()
|
self:revealPic("wipe", function()
|
||||||
Sound.playCry(self.game.data, self.demoSpecies)
|
Sound.playCry(self.game.data, self.demoSpecies)
|
||||||
self:say(Strings("_OakSpeechText2A"), function() self:advance() end)
|
self:say(Strings("_OakSpeechText2A"), function() self:advance() end)
|
||||||
@@ -536,8 +545,10 @@ function OakSpeech:update(dt)
|
|||||||
s.frame = s.frame + 1
|
s.frame = s.frame + 1
|
||||||
if s.frame == 5 then
|
if s.frame == 5 then
|
||||||
self.pic = self.shrinkPic1 or self.pic
|
self.pic = self.shrinkPic1 or self.pic
|
||||||
|
self.picTrueColor = false
|
||||||
elseif s.frame == 9 then
|
elseif s.frame == 9 then
|
||||||
self.pic = self.shrinkPic2 or self.pic
|
self.pic = self.shrinkPic2 or self.pic
|
||||||
|
self.picTrueColor = false
|
||||||
-- wAudioFadeOutControl = 10: the music ramps to silence over ~70
|
-- wAudioFadeOutControl = 10: the music ramps to silence over ~70
|
||||||
-- frames (7 levels x 10), reaching 0 just as the fade-to-white
|
-- frames (7 levels x 10), reaching 0 just as the fade-to-white
|
||||||
-- begins at frame 79, instead of a hard cut (oak_speech.asm:145-149,
|
-- begins at frame 79, instead of a hard cut (oak_speech.asm:145-149,
|
||||||
@@ -545,6 +556,7 @@ function OakSpeech:update(dt)
|
|||||||
Music.fadeOut(10)
|
Music.fadeOut(10)
|
||||||
elseif s.frame == 29 then
|
elseif s.frame == 29 then
|
||||||
self.pic = nil
|
self.pic = nil
|
||||||
|
self.picTrueColor = false
|
||||||
self.walkVisible = true
|
self.walkVisible = true
|
||||||
elseif s.frame >= 79 and s.frame <= 102 then
|
elseif s.frame >= 79 and s.frame <= 102 then
|
||||||
self.fadeLevel = math.floor((s.frame - 79) / 8) + 1
|
self.fadeLevel = math.floor((s.frame - 79) / 8) + 1
|
||||||
@@ -584,6 +596,9 @@ function OakSpeech:draw()
|
|||||||
else
|
else
|
||||||
love.graphics.draw(self.pic, x + off, y)
|
love.graphics.draw(self.pic, x + off, y)
|
||||||
end
|
end
|
||||||
|
if self.picTrueColor then
|
||||||
|
require("src.render.PaletteFX").markTrueColor(x + off, y, w, h)
|
||||||
|
end
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
end
|
end
|
||||||
if self.walkVisible and self.walkSheet then
|
if self.walkVisible and self.walkSheet then
|
||||||
|
|||||||
+41
-7
@@ -76,6 +76,30 @@ local function imagePath(entry)
|
|||||||
return entry
|
return entry
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- PaletteFX redraws a true-color rectangle after the palette pass. Red's
|
||||||
|
-- title art is drawn on top of the title mon, so leave its bounds out of the
|
||||||
|
-- rectangle rather than redrawing that art without its title palette.
|
||||||
|
local function markVisibleTrueColor(x, y, w, h, cover)
|
||||||
|
local P = require("src.render.PaletteFX")
|
||||||
|
if not cover then
|
||||||
|
P.markTrueColor(x, y, w, h)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local cx, cy, cw, ch = cover[1], cover[2], cover[3], cover[4]
|
||||||
|
local right, bottom = x + w, y + h
|
||||||
|
local cright, cbottom = cx + cw, cy + ch
|
||||||
|
local ix1, iy1 = math.max(x, cx), math.max(y, cy)
|
||||||
|
local ix2, iy2 = math.min(right, cright), math.min(bottom, cbottom)
|
||||||
|
if ix1 >= ix2 or iy1 >= iy2 then
|
||||||
|
P.markTrueColor(x, y, w, h)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if y < iy1 then P.markTrueColor(x, y, w, iy1 - y) end
|
||||||
|
if iy2 < bottom then P.markTrueColor(x, iy2, w, bottom - iy2) end
|
||||||
|
if x < ix1 then P.markTrueColor(x, iy1, ix1 - x, iy2 - iy1) end
|
||||||
|
if ix2 < right then P.markTrueColor(ix2, iy1, right - ix2, iy2 - iy1) end
|
||||||
|
end
|
||||||
|
|
||||||
function TitleState.new(game, opts)
|
function TitleState.new(game, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local self = setmetatable({}, TitleState)
|
local self = setmetatable({}, TitleState)
|
||||||
@@ -99,7 +123,7 @@ function TitleState.new(game, opts)
|
|||||||
self.cycleSpecies = (type(title.cycleSpecies) == "table"
|
self.cycleSpecies = (type(title.cycleSpecies) == "table"
|
||||||
and #title.cycleSpecies > 0)
|
and #title.cycleSpecies > 0)
|
||||||
and title.cycleSpecies or defaultCycle
|
and title.cycleSpecies or defaultCycle
|
||||||
self.sprites = {} -- species -> image or false (load failed)
|
self.sprites = {} -- species -> { image, trueColor } or false (load failed)
|
||||||
self.cycleIndex = 1
|
self.cycleIndex = 1
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
self.blink = 0
|
self.blink = 0
|
||||||
@@ -118,12 +142,13 @@ function TitleState:currentSprite()
|
|||||||
local species = self.cycleSpecies[self.cycleIndex]
|
local species = self.cycleSpecies[self.cycleIndex]
|
||||||
local cached = self.sprites[species]
|
local cached = self.sprites[species]
|
||||||
if cached == nil then
|
if cached == nil then
|
||||||
local path = require("src.pokemon.Sprites").path(
|
local path, trueColor = require("src.pokemon.Sprites").path(
|
||||||
self.game.data, species, "front", { kind = "title" })
|
self.game.data, species, "front", { kind = "title" })
|
||||||
cached = tryImage(path) or false
|
local image = tryImage(path)
|
||||||
|
cached = image and { image = image, trueColor = trueColor } or false
|
||||||
self.sprites[species] = cached
|
self.sprites[species] = cached
|
||||||
end
|
end
|
||||||
return cached or nil
|
return cached and cached.image or nil, cached and cached.trueColor or false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function hasSave()
|
local function hasSave()
|
||||||
@@ -276,13 +301,22 @@ function TitleState:draw()
|
|||||||
love.graphics.newQuad(40, 0, 40, 8, iw, ih), 80, 64)
|
love.graphics.newQuad(40, 0, 40, 8, iw, ih), 80, 64)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local sprite = self:currentSprite()
|
local sprite, spriteTrueColor = self:currentSprite()
|
||||||
if sprite then
|
if sprite then
|
||||||
local w, h = sprite:getDimensions()
|
local w, h = sprite:getDimensions()
|
||||||
local slide = (self.slideIn or 0) * 8 -- scroll in from the right
|
local slide = (self.slideIn or 0) * 8 -- scroll in from the right
|
||||||
-- bottom-aligned and centered in the (5,10)-(11,16) tile box
|
-- bottom-aligned and centered in the (5,10)-(11,16) tile box
|
||||||
love.graphics.draw(sprite, 40 + math.floor((56 - w) / 2) + slide,
|
local x = 40 + math.floor((56 - w) / 2) + slide
|
||||||
136 - h)
|
local y = 136 - h
|
||||||
|
love.graphics.draw(sprite, x, y)
|
||||||
|
if spriteTrueColor then
|
||||||
|
local cover
|
||||||
|
if self.player then
|
||||||
|
local pw, ph = self.player:getDimensions()
|
||||||
|
cover = { 82, 80, pw, ph }
|
||||||
|
end
|
||||||
|
markVisibleTrueColor(x, y, w, h, cover)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
-- Red is OAM in the original: he draws over the mon's box edge
|
-- Red is OAM in the original: he draws over the mon's box edge
|
||||||
if self.player then
|
if self.player then
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
-- True-color Pokemon art is drawn on the UI canvas in addition to battle.
|
||||||
|
-- The Pokedex, title screen, and Oak's intro need to report the exact
|
||||||
|
-- rectangle they draw so PaletteFX can put the unshaded copy over the SGB
|
||||||
|
-- palette pass. Run with `luajit tests/parity_true_color_ui.lua`.
|
||||||
|
|
||||||
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||||
|
if not _G.love then _G.love = require("tests.love_stub") end
|
||||||
|
|
||||||
|
local S = require("tests.harness").suite("parity true-color ui")
|
||||||
|
local check = S.check
|
||||||
|
|
||||||
|
local Data = require("src.core.Data")
|
||||||
|
if not Data.maps then Data:load() end
|
||||||
|
require("src.render.Font").load(Data)
|
||||||
|
|
||||||
|
local PaletteFX = require("src.render.PaletteFX")
|
||||||
|
local Sound = require("src.core.Sound")
|
||||||
|
local DexEntryMenu = require("src.ui.DexEntryMenu")
|
||||||
|
local TitleState = require("src.ui.TitleState")
|
||||||
|
local OakSpeech = require("src.ui.OakSpeech")
|
||||||
|
|
||||||
|
local savedCry = Sound.playCry
|
||||||
|
Sound.playCry = function() end
|
||||||
|
|
||||||
|
local function uiRects(draw)
|
||||||
|
PaletteFX.clearTrueColor()
|
||||||
|
PaletteFX.setPass("ui")
|
||||||
|
draw()
|
||||||
|
local rects = PaletteFX.trueColorRects("ui")
|
||||||
|
PaletteFX.setPass(nil)
|
||||||
|
return rects
|
||||||
|
end
|
||||||
|
|
||||||
|
local def = Data.pokemon.PIKACHU
|
||||||
|
local savedTrueColor = def.trueColor
|
||||||
|
def.trueColor = true
|
||||||
|
|
||||||
|
local game = {
|
||||||
|
data = Data,
|
||||||
|
save = { pokedex = { owned = { PIKACHU = true } } },
|
||||||
|
stack = { pop = function() end },
|
||||||
|
}
|
||||||
|
local dex = DexEntryMenu.new(game, "PIKACHU")
|
||||||
|
check(dex.spriteTrueColor == true,
|
||||||
|
"Pokedex keeps a Pokemon sprite's trueColor flag")
|
||||||
|
local dexRects = uiRects(function() dex:draw() end)
|
||||||
|
local dx, dy = 8, math.max(0, 60 - dex.sprite:getHeight())
|
||||||
|
check(#dexRects == 1 and dexRects[1].x == dx and dexRects[1].y == dy
|
||||||
|
and dexRects[1].w == dex.sprite:getWidth()
|
||||||
|
and dexRects[1].h == dex.sprite:getHeight(),
|
||||||
|
"Pokedex reports the true-color sprite rectangle")
|
||||||
|
|
||||||
|
local titleGame = {
|
||||||
|
data = { pokemon = Data.pokemon,
|
||||||
|
field = { title = { cycleSpecies = { "PIKACHU" } } } },
|
||||||
|
}
|
||||||
|
local title = TitleState.new(titleGame, {})
|
||||||
|
local titleSprite, titleTrueColor = title:currentSprite()
|
||||||
|
check(titleSprite and titleTrueColor,
|
||||||
|
"title cache keeps a Pokemon sprite's trueColor flag")
|
||||||
|
local titleRects = uiRects(function() title:draw() end)
|
||||||
|
local tx = 40 + math.floor((56 - titleSprite:getWidth()) / 2)
|
||||||
|
check(#titleRects == 1 and titleRects[1].x == tx
|
||||||
|
and titleRects[1].y == 136 - titleSprite:getHeight()
|
||||||
|
and titleRects[1].w == 82 - tx
|
||||||
|
and titleRects[1].h == titleSprite:getHeight(),
|
||||||
|
"title reports the visible true-color sprite rectangle")
|
||||||
|
|
||||||
|
local oak = OakSpeech.new({
|
||||||
|
data = { pokemon = Data.pokemon, trainers = {},
|
||||||
|
field = { oakSpeech = { demoSpecies = "PIKACHU" } } },
|
||||||
|
}, nil)
|
||||||
|
oak.pic, oak.picFlip = oak.demoPic, true
|
||||||
|
oak.picTrueColor = oak.demoTrueColor
|
||||||
|
check(oak.demoTrueColor == true,
|
||||||
|
"Oak intro keeps the demo Pokemon's trueColor flag")
|
||||||
|
local oakRects = uiRects(function() oak:draw() end)
|
||||||
|
local ow, oh = oak.demoPic:getDimensions()
|
||||||
|
local ox = 48 + math.floor((8 - ow / 8) / 2) * 8
|
||||||
|
local oy = 32 + (7 - oh / 8) * 8
|
||||||
|
check(#oakRects == 1 and oakRects[1].x == ox and oakRects[1].y == oy
|
||||||
|
and oakRects[1].w == ow and oakRects[1].h == oh,
|
||||||
|
"Oak intro reports the true-color sprite rectangle")
|
||||||
|
|
||||||
|
def.trueColor = savedTrueColor
|
||||||
|
Sound.playCry = savedCry
|
||||||
|
PaletteFX.clearTrueColor()
|
||||||
|
S.finish()
|
||||||
Reference in New Issue
Block a user