update 2d shiny sprites and shiny animation

This commit is contained in:
DramaticShape
2026-08-08 18:51:01 -04:00
parent c05c2cebd9
commit 9ddb940bc8
14 changed files with 1448 additions and 98 deletions
+119
View File
@@ -0,0 +1,119 @@
-- Driver: is a shiny visible on the FLAT paths -- the engine's own battle
-- screen (3D-BTL OFF) and the cards rung (2D-3D A)?
--
-- DS_SHOTS=mods/DramaticShapeVoxelMod/.claude/shiny_update/flat \
-- POKEPORT_DRIVER=mods/DramaticShapeVoxelMod/tests/shiny_flat.lua \
-- "/c/Program Files/LOVE/lovec.exe" .
--
-- The other shot driver covers the cards rung and the STADIUM rungs and NOT
-- 3D-BTL OFF -- which is the rung a player who has never touched the mod's
-- battle row is on, and so the one place a regression can sit unseen. It sat
-- there: the pic tint was a multiply that could only darken, and the arrival
-- sparkle was armed from Stadium.update and therefore never played here.
--
-- Each rung is shot TWICE, shiny and ordinary, from the same species at the
-- same spot, as a STRIP -- the intro flashes the pic through palette variants
-- on its way in, so a single frame lands wherever the pacing put it.
--
-- Reports, per rung: whether the roll landed, the PALETTE the pic was baked
-- under (which is where the recolour now lives), and whether the flat-path
-- sparkle armed and drew.
return function(game)
local U = dofile("tests/drivers/util.lua")
local BattleState = require("src.battle.BattleState")
local PaletteFX = require("src.render.PaletteFX")
local Pokemon = require("src.pokemon.Pokemon")
local SPECIES = os.getenv("DS_SPECIES") or "GYARADOS"
local LEVEL = tonumber(os.getenv("DS_LEVEL") or "") or 40
local DIR = os.getenv("DS_SHOTS") or ".claude/shiny_update/flat"
local exports = game.mods and game.mods.exports
local lib = exports and exports.DRAMATIC_SHAPE and exports.DRAMATIC_SHAPE.lib
if not lib then U.log("DRAMATIC_SHAPE is not loaded") return end
local Shiny = lib.require("Shiny")
local ShinyPics = lib.require("ShinyPics")
local ShinyFlash = lib.require("ShinyFlash")
local OverworldBattle = lib.require("OverworldBattle")
U.log(("wraps: pics=%s flash=%s"):format(
tostring(PaletteFX.dramaticShapeShiny == true),
tostring(ShinyFlash.installed == true)))
-- ------- what the palette wrap hands the image cache
--
-- The recolour is baked ONCE, at build time, so counting draws says nothing
-- about it. What matters is the cache key and the colours behind it: ask
-- PaletteFX the same two questions monPalette asks, with the note the
-- sprite hook would have left a moment earlier.
local function palReport(mon)
ShinyPics.note({ kind = "battle", species = SPECIES, mon = mon,
data = game.data })
local cols = PaletteFX.monPal(game.data, SPECIES)
local name = PaletteFX.monPalName(game.data, SPECIES)
local out = { "pal=" .. tostring(name) }
for i = 1, math.min(3, cols and #cols or 0) do
local c = cols[i]
if type(c) == "table" and c[1] then
out[#out + 1] = ("c%d=%d,%d,%d"):format(i, c[1], c[2], c[3])
end
end
return table.concat(out, " ")
end
-- The party is built at ORDINARY odds and pinned afterwards, so the
-- player's own Pikachu stays common: this run is about the foe.
game.save.player.name = "RED"
game.save.party = { Pokemon.new(game.data, "PIKACHU", 50) }
local function leave()
while game.stack:top() and game.stack:top() ~= game.overworld do
game.stack:pop()
end
U.wait(10)
end
local function shoot(rung, label, shiny)
OverworldBattle.setting:setValue(rung, game)
Shiny.setOdds(shiny and 1 or 100000000)
for k in pairs(ShinyFlash.debug) do ShinyFlash.debug[k] = 0 end
U.teleport(game, "ROUTE_1", 5, 8, "down")
U.wait(60)
local battle = BattleState.newWild(game, SPECIES, LEVEL)
battle.onFinish = function() end
game.overworld:pushBattle(battle)
local mon = battle.enemy and battle.enemy.mon
U.log(("%s %s: 3D-BTL=%s isShiny=%s %s"):format(
label, shiny and "shiny" or "normal",
tostring(OverworldBattle.setting:get()), tostring(Shiny.isShiny(mon)),
palReport(mon)))
-- The WIPE has to be walked through first. A driver run with no input at
-- all sits on BattleTransition forever -- the battle is never pushed, so
-- nothing about it draws and every counter below reads zero, which is
-- exactly the false negative this probe produced before the taps went in.
for _ = 1, 8 do U.tap(game, "a") U.wait(10) end
-- the sparkle is three quarters of a second long and starts on the frame
-- the pic appears, so the strip is TIGHT
for k = 1, 10 do
U.shot(game, ("%s/%s_%s_%02d.png"):format(DIR, label,
shiny and "shiny" or "normal",
k))
U.wait(9)
end
local d = ShinyFlash.debug
U.log((" flash: renders=%s armed=%d draws=%d sparks=%d follows=%d occ=%d %s")
:format(tostring(d.renders), d.armed, d.draws, d.sparks,
d.follows, d.occupied, tostring(d.err)))
leave()
end
shoot(false, "off", false)
shoot(false, "off", true)
shoot(true, "cards", false)
shoot(true, "cards", true)
end