Files
YataiDONNijiiro/Scripts/result/result_crown.lua
2026-09-30 15:29:22 -04:00

139 lines
5.4 KiB
Lua

-- Arcade crown fly-in and crown_loop shine, sampled from result/result crown_mc.
ResultCrown = {}
ResultCrown.__index = ResultCrown
local FRAME_MS = 1000 / 60 -- one arcade frame in ms
local cr_ok, crown_anim = pcall(require, "anim/sampler")
if not cr_ok then crown_anim = { safe = function()
-- sampler.lua itself is missing: hand back the same NULL clip shape it would
local n = {}
n.at = function() return nil end; n.get = function() return nil end
n.label = function() return nil end; n.has = function() return false end
n.first = function() return 0 end; n.last = function() return 0 end
return n
end } end
local CROWN = crown_anim.safe("anim/crown_mc")
local CROWN_START_F = CROWN:label("start") or 5 -- t = 0 is this arcade frame
local CROWN_END_F = CROWN:label("end") or 120
local GL_SHINE = { 0, 1, 2 } -- gleam frames of the crown_loop sweep
local GL_BURST, GL_STARS = 3, 4
local CLOOP = crown_anim.safe("anim/crown_loop")
local CLOOP_LEN = CLOOP:last() - CLOOP:first() + 1 -- 180
local CLOOP_LEAVES = { { "#65@1", 1 }, { "#67@1", 2 }, { "#69@1", 3 } } -- -> GL_SHINE idx
-- GL_SHINE index visible at loop-frame k, or nil during the idle stretch / missing table
local function crown_loop_shine(k)
if not CLOOP.tracks then return nil, false end
local ki = math.floor(k)
for i = 1, #CLOOP_LEAVES do
local rows = CLOOP.tracks[CLOOP_LEAVES[i][1]]
if rows and #rows > 0 and ki >= rows[1][1] and ki <= rows[#rows][1] then
return CLOOP_LEAVES[i][2], true
end
end
return nil, true -- table present, idle frame
end
local function clamp01(v)
if v <= 0 then return 0 end
if v >= 1 then return 1 end
return v
end
local function lerp(a, b, p) return a + (b - a) * p end
function ResultCrown.new(crown_type, is_2p, has_2p)
local self = setmetatable({}, ResultCrown)
self.is_2p = is_2p
self.p_idx = is_2p and 1 or 0
self.t0 = tex.get_current_ms()
self.now = self.t0
self.sound_played = false
local crown_names = { [0] = "crown_clear", [1] = "crown_fc", [2] = "crown_dfc" }
self.t_crown = tex.get_texture("result/crown/" .. (crown_names[crown_type] or "crown_clear"))
self.t_crown_fade = tex.get_texture("result/crown/crown_fade")
self.t_gleam = tex.get_texture("result/crown/gleam")
local colours = { [0] = "silver", [1] = "gold", [2] = "rainbow" }
local seat = has_2p and (is_2p and "_r" or "_l") or "_c"
self.sound_name = "crown_" .. (colours[crown_type] or "silver") .. seat
return self
end
function ResultCrown:update(current_ms)
self.now = current_ms
if not self.sound_played and (current_ms - self.t0) / FRAME_MS >= 0 then
audio.play_sound(self.sound_name or "crown", "sound")
self.sound_played = true
end
end
-- result_player.lua gates the 「クリア」 bubble on this: the crown has landed at scale 1.0.
function ResultCrown:is_settled()
return (self.now - self.t0) / FRAME_MS >= 17
end
function ResultCrown:draw()
local t = (self.now - self.t0) / FRAME_MS
if t < 0 then return end
local idx = self.p_idx
local f = CROWN_START_F + t -- absolute arcade frame on sprite 73
local c_scale = CROWN:get("crown", f, "sx") or 1.0
local c_alpha = CROWN:get("crown", f, "a") or 1.0
if self.t_crown then
tex.draw_texture(self.t_crown, { scale = c_scale, center = true, index = idx, fade = c_alpha })
end
if self.t_crown_fade and t >= 13 and t <= 42 then
local s = CROWN:get("crown_effect", f, "sx") or 1.0
local a = CROWN:get("crown_effect", f, "a") or 0.0
if a > 0.001 then
tex.draw_texture(self.t_crown_fade, { scale = s, center = true, index = idx, fade = a })
end
end
if not self.t_gleam then return end
-- radial burst: two equal copies, drawn twice for the doubled coverage
if t >= 13 and t <= 49 then
local a = CROWN:get("#38@1", f, "a") or 0.0
local s1 = CROWN:get("#38@1", f, "sx") or 0.1
local s0 = CROWN:get("#38@0", f, "sx") or 0.1
if a > 0.001 then
-- the cabinet places both burst copies with the add blend mode
tex.draw_texture(self.t_gleam, { frame = GL_BURST, scale = s1, center = true, index = idx, fade = a, blend = "additive" })
tex.draw_texture(self.t_gleam, { frame = GL_BURST, scale = s0, center = true, index = idx, fade = a, blend = "additive" })
end
end
-- drifting star cluster
if t >= 17 and t <= 119 then
local s = CROWN:get("#50@4", f, "sx") or 0.5
local ox = CROWN:get("#50@4", f, "tx") or 30.2
local oy = CROWN:get("#50@4", f, "ty") or -2.2
local a = CROWN:get("#50@4", f, "a") or 1.0
tex.draw_texture(self.t_gleam,
{ frame = GL_STARS, scale = s, center = true, index = idx, x = ox, y = oy, fade = clamp01(a) })
end
-- crown_loop shine sweep (180-frame loop from "end")
if f >= CROWN_END_F - 5 then
local k = (f - (CROWN_END_F - 5)) % (CLOOP_LEN > 1 and CLOOP_LEN or 180)
local shine, have_table = crown_loop_shine(k)
if shine then
tex.draw_texture(self.t_gleam,
{ frame = GL_SHINE[shine], center = true, index = idx })
elseif not have_table and k < 9 then
tex.draw_texture(self.t_gleam,
{ frame = GL_SHINE[math.floor(k / 3) + 1], center = true, index = idx })
end
end
end