Files
YataiDONNijiiro/Scripts/background/bg_objects/donbg/6.lua
T
2026-09-02 14:25:04 -04:00

135 lines
5.8 KiB
Lua

-- YataiDON-HSS override of PyTaikoGreen/background/bg_objects/donbg/6.lua
-- ROUND 12: the cabinet's band is a single static 1920x276 plate (see base.lua),
-- so the parent's per-index tile/scroll/overlay rig has nothing left to do and
-- every index is the base class.
--
-- ROUND 102 (r102-bg-sweep). That is still true of index 6's two SCROLLING
-- layers -- bg_data/donbg.lua's "5_x" carries them and this round re-measured
-- them as correct (-91.92 px/s wrapping 490 px, and -91.98 px/s wrapping 980 px).
-- What ROUND 13 missed is a THIRD thing in `enso/donbg/donbg_a_06_{1,2}p`: three
-- sakura-petal drifters, `#13@0/#6@{1,2,3}/#4@0` (fever: `#27@1/#21@{1,2,3}/#19@0`),
-- sitting at root depths 1..3 -- i.e. BETWEEN the two scrolling layers (#3@0 is
-- depth 0, #12@4 is depth 4). They were never sampled because their own parent
-- `#6@k` is constant (tx 2110, ty -178, every frame); only the grandchild moves.
-- This is the same "sampled the wrong level of the display list" mistake ROUND 26,
-- ROUND 35 and ROUND 76 each hit on the dan band.
--
-- Dumped with `lumen_anim_dump --sprite <root> --all --leaves --auto-stop
-- --range 0,700` and read frame by frame, one drifter walks
-- (2308, -106) -> (1540, 382) over 160 frames, then snaps back
-- i.e. -4.830189 px/frame = -289.81 px/s and +3.069182 px/frame = +184.15 px/s at
-- the stage's own 60 fps ("fps":60 in the dump; NOT Common.FPS = 120, which is the
-- Lua tick). The three instances are in phase and 980 px apart. Both players'
-- movies measure identically.
--
-- The art is `overlay_2` (frame 0 normal, frame 1 fever): a 391x208 nine-petal
-- cluster lifted straight out of the cabinet with
-- lumen_shape_dump -m -r 6 -O 700 60 (normal)
-- lumen_shape_dump -m -r 21 -O 700 60 (fever)
-- and cropped to the exact alpha>0 bounding box, which is x 703..1093, y 28..235 --
-- verified explicitly rather than trimmed by a heuristic (ROUND 88). No colour
-- transform is involved (`alpha: 1/1 placement(s) visible, mean Amul = 256.0/256`),
-- so it is a plain source-over composite, never ImageChops.screen (ROUND 94).
-- Its registration point is (-195, -104) from the placement, so the art's top-left
-- is (world_x - 195, world_y - 104).
--
-- `overlay_2` was an 8x8 placeholder that nothing drew, so this introduces no new
-- texture name -- a child skin cannot invent one (ROUND 11) and does not need to.
--
-- The cabinet clips the drifters to its 1920x276 stage; we have no stage, so the
-- draw is cropped to the band with `src` + `y2` exactly the way ROUND 76's
-- bg_collabs/dan.lua crops its petals. Without that the bottom of a cluster would
-- fall over the play area, and on 2P (band drawn at y = 804) the top of one would
-- paint over 1P's lane.
local DonBGBase = require("background/bg_objects/donbg/base")
DonBG6 = setmetatable({}, { __index = DonBGBase })
DonBG6.__index = DonBG6
local PETAL_W, PETAL_H = 391, 208
local PETAL_REG_X = -195
local PETAL_REG_Y = -104
local PETAL_LOOP_FRAMES = 160
local PETAL_X0, PETAL_Y0 = 2308.0, -106.0
local PETAL_DX = -4.830189
local PETAL_DY = 3.069182
local PETAL_GAP = 980.0
local PETAL_COPIES = 3
local BAND_H = 276
function DonBG6.new(index, player_num, path)
local self = setmetatable({}, DonBG6)
local base = DonBGBase.new(index, player_num, path)
for k, v in pairs(base) do self[k] = v end
-- ROUND 60: id 0 is a valid texture id, so nil (not 0) means missing.
self._id_petal = tex.get_id(self.name, "overlay_2")
-- Fail soft: only the DEFAULT pack ("5_x", path "background") owns this rig.
-- A collab routed through DonBG6 keeps the plain base behaviour.
self._petals_on = self.use_layers and (self._id_petal ~= nil)
return self
end
-- One petal cluster, cropped to the band [y, y + 276).
function DonBG6:_draw_petal(frame, fade, y, cx, top)
local band_top, band_bottom = y, y + BAND_H
if top >= band_bottom or top + PETAL_H <= band_top then return end
local sy = 0
if top < band_top then sy = band_top - top end
local h = PETAL_H - sy
if top + sy + h > band_bottom then h = band_bottom - (top + sy) end
if h <= 0 then return end
tex.draw_texture(self._id_petal, {
frame = frame, fade = fade,
x = cx + PETAL_REG_X,
y = top + sy,
src = { x = 0, y = sy, width = PETAL_W, height = h },
y2 = h - PETAL_H,
})
end
function DonBG6:_draw_petals(frame, fade, y)
if not self._petals_on then return end
local f = (self.elapsed / (1000.0 / 60.0)) % PETAL_LOOP_FRAMES
local cx = PETAL_X0 + PETAL_DX * f
local top = (PETAL_Y0 + PETAL_DY * f) + PETAL_REG_Y + y
for i = 0, PETAL_COPIES - 1 do
self:_draw_petal(frame, fade, y, cx - i * PETAL_GAP, top)
end
end
-- Same shape as DonBGBase:draw(), with the drifters slotted in at their real
-- display-list depth: after the depth-0 backdrop, before the depth-4 motif row.
function DonBG6:draw(y)
y = y or 0
if not self.use_layers then return DonBGBase.draw(self, y) end
local normal = self.states.normal or {}
local fever = self.states.fever
local back, front = {}, {}
for i, l in ipairs(normal) do
table.insert(i == 1 and back or front, l)
end
self:draw_layers(back, 1.0, y)
self:_draw_petals(0, 1.0, y)
self:draw_layers(front, 1.0, y)
local fade = nil
if self.is_clear then
fade = self.clear_fade.attribute
elseif self.exit_fade then
-- ROUND 52: falling-edge reverse fade (`fever_normal`).
fade = self.exit_fade.attribute
end
if fade and fever then
local fback, ffront = {}, {}
for i, l in ipairs(fever) do
table.insert(i == 1 and fback or ffront, l)
end
self:draw_layers(fback, fade, y)
self:_draw_petals(1, fade, y)
self:draw_layers(ffront, fade, y)
end
end
return DonBG6