mirror of
https://github.com/AverageConsumer/kanto-gear.git
synced 2026-08-28 18:24:42 +02:00
fix: preserve native companion art palettes
This commit is contained in:
+48
-20
@@ -2148,7 +2148,8 @@ return function(mod)
|
||||
quads[i] = G.newQuad((i % across) * 8, math.floor(i / across) * 8,
|
||||
8, 8, iw, ih)
|
||||
end
|
||||
mapAsset = { image = image, quads = quads, maps = gfx.maps, gen2 = true }
|
||||
mapAsset = { image = image, quads = quads, maps = gfx.maps,
|
||||
palettes = gfx.palettes, palMap = gfx.palMap, gen2 = true }
|
||||
return mapAsset
|
||||
end
|
||||
local townMap = game and game.data and game.data.field
|
||||
@@ -2176,7 +2177,8 @@ return function(mod)
|
||||
end
|
||||
|
||||
local function sprite(species, side, mon)
|
||||
local path = PokemonSprites.path(game and game.data, species, side,
|
||||
local path, trueColor = PokemonSprites.path(
|
||||
game and game.data, species, side,
|
||||
{ kind = "summary", mon = mon })
|
||||
if not path then return nil end
|
||||
local key = side .. ":" .. path
|
||||
@@ -2190,12 +2192,12 @@ return function(mod)
|
||||
if ok and image then image:setFilter("nearest", "nearest") end
|
||||
spriteCache[key] = ok and image or false
|
||||
end
|
||||
return spriteCache[key] or nil
|
||||
return spriteCache[key] or nil, trueColor
|
||||
end
|
||||
|
||||
local function drawSprite(species, side, x, y, maxW, maxH, tint,
|
||||
mon, quiet)
|
||||
local image = sprite(species, side, mon)
|
||||
local image, trueColor = sprite(species, side, mon)
|
||||
if not image then
|
||||
if not quiet then box("fill", x + 4, y + 4, maxW - 8, maxH - 8, DARK) end
|
||||
return false
|
||||
@@ -2207,11 +2209,20 @@ return function(mod)
|
||||
G.draw(image, x + (maxW - iw * scale) / 2,
|
||||
y + (maxH - ih * scale) / 2, 0, scale, scale)
|
||||
end
|
||||
local gbc, palettes = compat.gen2PaletteModules()
|
||||
local colors = palettes and palettes.monColors
|
||||
and palettes.monColors(game.data.gen2Palettes, species,
|
||||
mon and mon.shiny)
|
||||
if colors and gbc and gbc.available() then gbc.with(colors, paint)
|
||||
local gbc = require("src.render.GbcPalette")
|
||||
local colors
|
||||
if not (tint or trueColor) then
|
||||
if compat.isGen2() then
|
||||
local _, palettes = compat.gen2PaletteModules()
|
||||
colors = palettes and palettes.monColors
|
||||
and palettes.monColors(game.data.gen2Palettes, species,
|
||||
mon and mon.shiny)
|
||||
else
|
||||
colors = PaletteFX.monPal(game.data, species,
|
||||
mon and mon.transformed)
|
||||
end
|
||||
end
|
||||
if colors and gbc.available() then gbc.with(colors, paint)
|
||||
else paint() end
|
||||
return true
|
||||
end
|
||||
@@ -2670,21 +2681,29 @@ return function(mod)
|
||||
local asset = loadMap()
|
||||
if asset then
|
||||
local cells = asset.map
|
||||
local gbc = require("src.render.GbcPalette")
|
||||
local mapColors = not asset.gen2
|
||||
and PaletteFX.pal(game.data, "TOWNMAP") or nil
|
||||
if asset.gen2 then
|
||||
cells = asset.maps[region]
|
||||
color(THEME.style == "modern_dark" and INK or PAPER)
|
||||
else
|
||||
color({ 1, 1, 1, 1 })
|
||||
end
|
||||
for i, tile in ipairs(cells or {}) do
|
||||
local quad = asset.quads[tile]
|
||||
if quad then
|
||||
local col, row = (i - 1) % 20, math.floor((i - 1) / 20)
|
||||
if asset.gen2 then
|
||||
G.draw(asset.image, quad, 20 + col * 6, 20 + row * 6,
|
||||
0, 0.75, 0.75)
|
||||
elseif row > 0 then
|
||||
G.draw(asset.image, quad, 20 + col * 6, 22 + (row - 1) * 6, 0, 0.75, 0.75)
|
||||
local y = asset.gen2 and 20 + row * 6 or 22 + (row - 1) * 6
|
||||
local colors = asset.gen2 and asset.palettes
|
||||
and asset.palettes[(asset.palMap and asset.palMap[tile + 1]) or 1]
|
||||
or mapColors
|
||||
local function paint()
|
||||
color(colors and { 1, 1, 1, 1 }
|
||||
or asset.gen2 and (THEME.style == "modern_dark" and INK or PAPER)
|
||||
or { 1, 1, 1, 1 })
|
||||
G.draw(asset.image, quad, 20 + col * 6, y, 0, 0.75, 0.75)
|
||||
end
|
||||
if (asset.gen2 or row > 0) then
|
||||
if colors and gbc.available() then gbc.with(colors, paint)
|
||||
else paint() end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2939,6 +2958,8 @@ return function(mod)
|
||||
spriteCache.__badges = ok and card and card.badges or false
|
||||
end
|
||||
local badgeAsset = spriteCache.__badges
|
||||
local gen1BadgeColors = not compat.isGen2()
|
||||
and PaletteFX.pal(game.data, "MEWMON") or nil
|
||||
|
||||
header("TRAINER", false, true)
|
||||
box("fill", 4, 22, 152, 50, MID)
|
||||
@@ -2960,11 +2981,18 @@ return function(mod)
|
||||
badgeOwned and PAPER or DARK)
|
||||
end
|
||||
elseif quad then
|
||||
local tint = badgeOwned and INK or DARK
|
||||
G.setColor(tint[1], tint[2], tint[3], badgeOwned and 1 or 0.25)
|
||||
local x = math.floor(5 + (i - 1) * 134
|
||||
/ math.max(1, #badges - 1))
|
||||
G.draw(badgeAsset.img, quad, x, 56)
|
||||
local colors = badgeOwned and gen1BadgeColors
|
||||
local function paint()
|
||||
local tint = badgeOwned and INK or DARK
|
||||
if colors then G.setColor(1, 1, 1, 1)
|
||||
else G.setColor(tint[1], tint[2], tint[3], badgeOwned and 1 or 0.25) end
|
||||
G.draw(badgeAsset.img, quad, x, 56)
|
||||
end
|
||||
local gbc = require("src.render.GbcPalette")
|
||||
if colors and gbc.available() then gbc.with(colors, paint)
|
||||
else paint() end
|
||||
else
|
||||
local badgeGap = 152 / math.max(1, #badges)
|
||||
local x = math.floor(4 + (i - 1) * badgeGap)
|
||||
|
||||
@@ -1015,6 +1015,16 @@ local fallbackPhase = false
|
||||
local fallbackImage
|
||||
local decodedFrames = 0
|
||||
local genericSprites, ownedSprites = 0, 0
|
||||
local PaletteFX = require("src.render.PaletteFX")
|
||||
local GbcPalette = require("src.render.GbcPalette")
|
||||
local monPal = PaletteFX.monPal
|
||||
local paletteWith = GbcPalette.with
|
||||
local paletteAvailable = GbcPalette.available
|
||||
local nativeMonColors = {
|
||||
{ 255, 255, 255 }, { 248, 184, 112 }, { 152, 80, 136 }, { 0, 0, 0 },
|
||||
}
|
||||
local nativeMonPaletteUses = 0
|
||||
local trueColorMonPalCalls = 0
|
||||
local originalIcons = game.data.icons
|
||||
game.data.icons = {
|
||||
bySpecies = { PIKACHU = "TEST_ICON" },
|
||||
@@ -1048,6 +1058,11 @@ T.love.graphics.newImage = function(path, ...)
|
||||
if path == "official-icon.png" then fallbackImage = image end
|
||||
return image
|
||||
end
|
||||
PaletteFX.monPal = function(...)
|
||||
trueColorMonPalCalls = trueColorMonPalCalls + 1
|
||||
return monPal(...)
|
||||
end
|
||||
GbcPalette.available = function() return true end
|
||||
for _ = 1, 32 do
|
||||
trigger.right = 0.8
|
||||
run.loader.hooks:call("input.step", function() end, game, 1 / 60)
|
||||
@@ -1067,6 +1082,33 @@ T.check(ownedSprites > 0,
|
||||
"owned Pokemon screens pass their live Pokemon to the sprite resolver")
|
||||
T.eq(fallbackIcons, 0,
|
||||
"decoded Party sprite frames do not use placeholder icons")
|
||||
T.eq(trueColorMonPalCalls, 0,
|
||||
"full-color mod sprites bypass native palette remapping")
|
||||
PaletteFX.monPal = function() return nativeMonColors end
|
||||
GbcPalette.with = function(colors, body)
|
||||
if colors == nativeMonColors then
|
||||
nativeMonPaletteUses = nativeMonPaletteUses + 1
|
||||
end
|
||||
return body()
|
||||
end
|
||||
Sprites.path = function(_, _, _, opts)
|
||||
if opts and opts.mon then ownedSprites = ownedSprites + 1
|
||||
else genericSprites = genericSprites + 1 end
|
||||
return "decoded-frame.png", false
|
||||
end
|
||||
for _ = 1, 32 do
|
||||
trigger.right = 0.8
|
||||
run.loader.hooks:call("input.step", function() end, game, 1 / 60)
|
||||
trigger.right = 0
|
||||
run.loader.hooks:call("input.step", function() end, game, 1 / 60)
|
||||
run.loader.hooks:call("render.compose", function() return false end, {}, {
|
||||
secondScreen = { detected = function() return displayDetected end,
|
||||
pollTouch = function() return nil end },
|
||||
})
|
||||
if nativeMonPaletteUses > 0 then break end
|
||||
end
|
||||
T.check(nativeMonPaletteUses > 0,
|
||||
"Gen 1 Pokemon sprites use their native species palette")
|
||||
Sprites.path = function() return "unavailable.gif", true end
|
||||
fallbackPhase = true
|
||||
Assets.imageData = function(path)
|
||||
@@ -1085,6 +1127,8 @@ for _ = 1, 32 do
|
||||
if fallbackIcons > 0 then break end
|
||||
end
|
||||
Sprites.path, Assets.imageData = spritePath, imageData
|
||||
PaletteFX.monPal, GbcPalette.with = monPal, paletteWith
|
||||
GbcPalette.available = paletteAvailable
|
||||
T.love.graphics.newImage = newImage
|
||||
T.love.graphics.draw = drawImage
|
||||
game.data.icons = originalIcons
|
||||
@@ -1094,6 +1138,8 @@ T.check(fallbackIsWhite, "fallback Party icons keep their original colors")
|
||||
|
||||
do
|
||||
local badgeLoads, badgeAlphas = 0, {}
|
||||
local badgePaletteUses = 0
|
||||
local palette = PaletteFX.pal
|
||||
local draw = T.love.graphics.draw
|
||||
local TrainerCard = require("src.ui.TrainerCard")
|
||||
local trainerCardNew = TrainerCard.new
|
||||
@@ -1106,6 +1152,18 @@ do
|
||||
{ id = "VOLCANOBADGE" }, { id = "EARTHBADGE" },
|
||||
}
|
||||
game.save.inventory.TEST_BADGE = true
|
||||
local badgeColors = {
|
||||
{ 255, 255, 255 }, { 248, 184, 112 }, { 152, 80, 136 }, { 0, 0, 0 },
|
||||
}
|
||||
PaletteFX.pal = function(data, name)
|
||||
if name == "MEWMON" then return badgeColors end
|
||||
return palette(data, name)
|
||||
end
|
||||
GbcPalette.available = function() return true end
|
||||
GbcPalette.with = function(colors, body)
|
||||
if colors == badgeColors then badgePaletteUses = badgePaletteUses + 1 end
|
||||
return body()
|
||||
end
|
||||
TrainerCard.new = function()
|
||||
badgeLoads = badgeLoads + 1
|
||||
local badges = { img = T.love.graphics.newImage({}), quads = {} }
|
||||
@@ -1137,6 +1195,9 @@ do
|
||||
if #badgeAlphas >= 8 then break end
|
||||
end
|
||||
TrainerCard.new, T.love.graphics.draw = trainerCardNew, draw
|
||||
PaletteFX.pal = palette
|
||||
GbcPalette.with = paletteWith
|
||||
GbcPalette.available = paletteAvailable
|
||||
game.data.constants.badges = dataBadges
|
||||
game.save.inventory.TEST_BADGE = nil
|
||||
T.eq(badgeLoads, 1, "Trainer badges reuse Recomp's Trainer Card sprites")
|
||||
@@ -1148,6 +1209,8 @@ do
|
||||
end
|
||||
T.eq(solid, 1, "owned badges draw at full strength")
|
||||
T.eq(faded, 7, "unearned badges remain visible as faded silhouettes")
|
||||
T.eq(badgePaletteUses, 1,
|
||||
"owned Gen 1 badges use the native Trainer Card palette")
|
||||
end
|
||||
|
||||
T.eq(run.loader.hooks:call("render.output_enabled",
|
||||
|
||||
@@ -52,9 +52,13 @@ run.data.gen2Encounters = { grass = { FIX_ROUTE = { slots = {
|
||||
} } }, water = {} }
|
||||
local johtoMap = {}
|
||||
for i = 1, 20 * 18 do johtoMap[i] = 0 end
|
||||
local mapColors = {
|
||||
{ 255, 255, 255 }, { 104, 208, 88 }, { 32, 120, 64 }, { 0, 0, 0 },
|
||||
}
|
||||
run.data.gen2MenuGfx = { pokegear = {
|
||||
tiles = "gold-map.png", tilesWide = 1,
|
||||
maps = { johto = johtoMap, kanto = johtoMap },
|
||||
palettes = { mapColors }, palMap = { [1] = 1 },
|
||||
} }
|
||||
run.data.gen2Sprites = { SPRITE_CHRIS = {
|
||||
image = "gold-player.png", frames = 1, trueColor = true, paletteId = 0,
|
||||
@@ -111,8 +115,12 @@ local companion = {
|
||||
push = function() return true end,
|
||||
}
|
||||
local SpriteRenderer = require("src.render.SpriteRenderer")
|
||||
local GbcPalette = require("src.render.GbcPalette")
|
||||
local rendererNew = SpriteRenderer.new
|
||||
local paletteWith = GbcPalette.with
|
||||
local paletteAvailable = GbcPalette.available
|
||||
local markerPalette
|
||||
local mapPaletteUsed = false
|
||||
SpriteRenderer.new = function(def, seed)
|
||||
local renderer = rendererNew(def, seed)
|
||||
if seed == "kanto-gear-map" then
|
||||
@@ -124,13 +132,21 @@ SpriteRenderer.new = function(def, seed)
|
||||
end
|
||||
return renderer
|
||||
end
|
||||
GbcPalette.with = function(colors, body)
|
||||
if colors == mapColors then mapPaletteUsed = true end
|
||||
return body()
|
||||
end
|
||||
GbcPalette.available = function() return true end
|
||||
local mapDraws = T.record.draw()
|
||||
run.loader.hooks:call("render.compose", function() return false end, {}, {
|
||||
secondScreen = companion,
|
||||
})
|
||||
SpriteRenderer.new = rendererNew
|
||||
GbcPalette.with, GbcPalette.available = paletteWith, paletteAvailable
|
||||
T.check(#mapDraws:fromPath("gold-map.png") > 0,
|
||||
"Gold map renders the extracted Pokegear town-map tiles")
|
||||
T.check(mapPaletteUsed,
|
||||
"Gold map applies its extracted per-tile town-map palettes")
|
||||
local playerMarker = mapDraws:fromPath("gold-player.png")[1]
|
||||
T.check(playerMarker and playerMarker.args[2] == 44
|
||||
and playerMarker.args[3] == 56 and playerMarker.args[5] == 0.75,
|
||||
|
||||
Reference in New Issue
Block a user