mirror of
https://github.com/DramaticShape/DramaticShapeVoxelMod.git
synced 2026-08-12 10:00:50 +02:00
update 2d shiny sprites and shiny animation
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user