PyTaikoGreen reworked the art of its collab backdrops (folders renamed, texture.json positions changed, new layers) together with its collab scripts. Nijiiro takes the art from the parent but kept its own older copies of eight collab scripts, so with the new art those collabs lost their dancers, footer or fever layers, filled the log with draw errors (funassyi, gumi) or crashed (a3, imas_sidem, oshiri). a3, animal, buttoburst, funassyi, imas (also imas_cg/imas_ml), imas_sidem and oshiri now load the parent's script and keep what Nijiiro did differently (bg_objects/collab_parent.lua): the collab dancer-count model and no drumroll burst on balloons. The parent's script is loaded from its own file, so it uses the parent's background objects that its art is laid out for. gumi only adapted the parent's script to this skin's donbg/6, so the parent's is used as it is. The dancer-count model now also drives the parent's troupes: set_count where the troupe has it (a3), and leave_dancer to shrink. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
53 lines
2.1 KiB
Lua
53 lines
2.1 KiB
Lua
-- Collab dancer-count model: troupe size = clamp(floor(4r + 1), 1, max), where
|
|
-- r = gauge / clear_point, grown/shrunk against a BaseDancerGroup-shaped object.
|
|
local CollabDancerModel = {}
|
|
CollabDancerModel.__index = CollabDancerModel
|
|
|
|
local GAUGE_MAX = 87.0
|
|
local CLEAR_STARTS = { 52, 60, 69 } -- easy / normal / hard+oni
|
|
local CLEAR_DEFAULT = 69 / GAUGE_MAX
|
|
|
|
function CollabDancerModel.new(max_dancers)
|
|
return setmetatable({ max = max_dancers, clear_progress = nil }, CollabDancerModel)
|
|
end
|
|
|
|
-- Returns the absolute troupe size for this frame.
|
|
function CollabDancerModel:target(progress, is_clear, clear_progress)
|
|
if clear_progress and clear_progress > 0 then
|
|
self.clear_progress = clear_progress
|
|
elseif is_clear and not self.clear_progress then
|
|
local p = progress or 0
|
|
for _, cs in ipairs(CLEAR_STARTS) do
|
|
if p < cs / GAUGE_MAX + 0.0005 then
|
|
self.clear_progress = cs / GAUGE_MAX
|
|
break
|
|
end
|
|
end
|
|
self.clear_progress = self.clear_progress or CLEAR_DEFAULT
|
|
end
|
|
|
|
local cp = self.clear_progress or CLEAR_DEFAULT
|
|
local r = (progress or 0) / cp
|
|
local n = math.floor(4 * r + 1)
|
|
-- honour the engine's one-gauge-unit-early is_clear flip so the full troupe
|
|
-- and the クリア state arrive on the same frame
|
|
if is_clear then n = self.max end
|
|
if n < 1 then n = 1 elseif n > self.max then n = self.max end
|
|
return n
|
|
end
|
|
|
|
-- Drives a dancer group to the target count: one with set_count (the parent's A3 troupe) is
|
|
-- told the count; a BaseDancerGroup-shaped one is grown, and shrunk with leave_dancer (the
|
|
-- dancer walks off) where it has one.
|
|
function CollabDancerModel:apply(group, progress, is_clear, clear_progress)
|
|
local n = self:target(progress, is_clear, clear_progress)
|
|
if group.set_count then group:set_count(n) return end
|
|
local cur = group.active_count or 0
|
|
if cur <= 0 then return end
|
|
for _ = 1, n - cur do group:add_dancer() end
|
|
local leave = group.leave_dancer or group.remove_dancer
|
|
for _ = 1, cur - n do leave(group) end
|
|
end
|
|
|
|
return CollabDancerModel
|