From a48fcd3498aa44b9a284e594da3a1d334bbcaf70 Mon Sep 17 00:00:00 2001 From: TaikoZhong <108016253+GanYiZhong@users.noreply.github.com> Date: Mon, 12 Oct 2026 14:18:37 +0800 Subject: [PATCH] collabs: use the parent's collab scripts with its reworked art 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 --- Scripts/background/bg_collabs/a3.lua | 220 +--------------- Scripts/background/bg_collabs/animal.lua | 124 +-------- Scripts/background/bg_collabs/buttoburst.lua | 124 +-------- Scripts/background/bg_collabs/funassyi.lua | 159 +----------- Scripts/background/bg_collabs/gumi.lua | 200 -------------- Scripts/background/bg_collabs/imas.lua | 245 +----------------- Scripts/background/bg_collabs/imas_sidem.lua | 224 +--------------- Scripts/background/bg_collabs/oshiri.lua | 206 +-------------- .../bg_objects/collab_dancer_model.lua | 10 +- .../background/bg_objects/collab_parent.lua | 53 ++++ 10 files changed, 81 insertions(+), 1484 deletions(-) delete mode 100644 Scripts/background/bg_collabs/gumi.lua create mode 100644 Scripts/background/bg_objects/collab_parent.lua diff --git a/Scripts/background/bg_collabs/a3.lua b/Scripts/background/bg_collabs/a3.lua index 3333508..f5ee2d0 100644 --- a/Scripts/background/bg_collabs/a3.lua +++ b/Scripts/background/bg_collabs/a3.lua @@ -1,217 +1,3 @@ --- YataiDON-HSS override of PyTaikoGreen/background/bg_collabs/a3.lua: petal period/tile step use petal_info.x2[1] -local DonBGBase = require("background/bg_objects/donbg/base") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") -local DancerModel = require("background/bg_objects/collab_dancer_model") - -local COLLAB_PATH = "background/collab/a3" -local MAX_DANCERS = 4 - --- Custom DonBG: looping screen-width tile scroll -local A3DonBG = setmetatable({}, { __index = DonBGBase }) -A3DonBG.__index = A3DonBG - -function A3DonBG.new(player_num) - local self = setmetatable({}, A3DonBG) - local base = DonBGBase.new(1, player_num, COLLAB_PATH) - for k, v in pairs(base) do self[k] = v end - self.move = anim.move(10000, { total_distance = -tex.get_screen_width(), loop = true }) - return self -end - -function A3DonBG:draw_textures(fade, y, frame) - local sw = tex.get_screen_width() - local sc = tex.get_screen_scale() - for i = 0, math.floor(2 * sc) - 1 do - tex.draw_texture(self._id_bg, { - frame = frame, - fade = fade, - x = (i * sw) + self.move.attribute - }) - end -end - --- BGNormal: flicker overlay (anim 9) + curtain -local A3BGNormal = {} -A3BGNormal.__index = A3BGNormal - -function A3BGNormal.new() - local self = setmetatable({}, A3BGNormal) - self.name = "bg_0" - tex.load_folder(COLLAB_PATH, "bg_normal/" .. self.name) - self.flicker = tex.get_animation(9, "background") - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/background") or 0 - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - self._id_curtain = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/curtain") or 0 - return self -end - -function A3BGNormal:update(current_time_ms) - self.flicker:update(current_time_ms) -end - -function A3BGNormal:draw() - tex.draw_texture(self._id_bg) - tex.draw_texture(self._id_overlay, { fade = self.flicker.attribute }) - tex.draw_texture(self._id_curtain) -end - -function A3BGNormal:destroy() - tex.unload_folder(COLLAB_PATH, "bg_normal/" .. self.name) -end - --- BGFever: extends BGFever4 pattern with petals tiling -local A3BGFever = {} -A3BGFever.__index = A3BGFever - -function A3BGFever.new() - local self = setmetatable({}, A3BGFever) - self.name = "bg_fever_0" - tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name) - self.transitioned = false - self.horizontal_move = tex.get_animation(16, "background") - self.bg_texture_move = tex.get_animation(17, "background") - local petal_info = tex.get_texture_info(self.name, "petals") - self.petal_width = petal_info and petal_info.x2[1] or 0 - self.vertical_move = anim.move(1300, { total_distance = self.petal_width, loop = true }) - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - self._id_petals = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/petals") or 0 - return self -end - -function A3BGFever:start() - self.bg_texture_move:start() -end - -function A3BGFever:reset() - self.transitioned = false -end - -function A3BGFever:update(current_time_ms) - self.bg_texture_move:update(current_time_ms) - if self.bg_texture_move.is_finished and not self.transitioned then - self.transitioned = true - self.horizontal_move:restart() - end - if self.transitioned then - self.horizontal_move:update(current_time_ms) - end - self.vertical_move:update(current_time_ms) -end - -function A3BGFever:draw() - local sc = tex.get_screen_scale() - local w = self.petal_width - tex.draw_texture(self._id_overlay) - for i = 0, math.floor(10 * sc) - 1 do - for j = 0, 1 do - tex.draw_texture(self._id_petals, { - x = (i * w) - self.horizontal_move.attribute, - y = (j * w) + self.vertical_move.attribute - }) - end - end -end - -function A3BGFever:destroy() - tex.unload_folder(COLLAB_PATH, "bg_fever/" .. self.name) -end - --- Custom Dancer: BaseDancer + shadow overlay -local BaseDancer = Dancer.Base - -local A3Dancer = setmetatable({}, { __index = BaseDancer }) -A3Dancer.__index = A3Dancer - -function A3Dancer.new(name, index, bpm, path) - local self = setmetatable({}, A3Dancer) - local base = BaseDancer.new(name, index, bpm, path) - for k, v in pairs(base) do self[k] = v end - self._id_shadow = tex.get_texture(self.path .. "/" .. self.name .. "/shadow") or 0 - return self -end - -function A3Dancer:draw(x) - BaseDancer.draw(self, x) - tex.draw_texture(self._id_shadow, { x = x, fade = 0.50 }) -end - --- Background - -local A3Background = {} -A3Background.__index = A3Background - -function A3Background.new(player_num, bpm) - local self = setmetatable({}, A3Background) - self.donbg = A3DonBG.new(player_num) - self.bg_normal = A3BGNormal.new() - self.bg_fever = A3BGFever.new() - self.dancer = Dancer.BaseDancerGroup.new(0, bpm, MAX_DANCERS, COLLAB_PATH, A3Dancer) - self.renda = RendaController.new(COLLAB_PATH, 0) - self.chibi = ChibiController.new(bpm, COLLAB_PATH, 0) - self.is_clear = false - self.is_rainbow = false - -- reference dance_b_* count model - self.dancer_model = DancerModel.new(MAX_DANCERS) - return self -end - -function A3Background:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_normal:update(current_ms) - self.bg_fever:update(current_ms) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function A3Background:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function A3Background:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function A3Background:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function A3Background:handle_drumroll(player_num) self.renda:add_renda() end - -function A3Background:handle_balloon(player_num) end - -function A3Background:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) - self.donbg:set_clear(is_clear) - if is_clear and not self.is_clear then self.bg_fever:start() end - if not is_clear and self.is_clear and self.bg_fever.reset then self.bg_fever:reset() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - self.dancer_model:apply(self.dancer, progress, is_clear, clear_progress) -end - -function A3Background:draw_back() - if self.is_clear then - if not self.bg_fever.transitioned then - self.bg_normal:draw() - self.bg_fever:draw() - else - self.bg_fever:draw() - end - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - self.chibi:draw() -end - -function A3Background:draw_fore() end - -function A3Background:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.dancer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - -return A3Background +-- PyTaikoGreen's a3 collab backdrop (its art and script) with this skin's collab dancer count +-- and balloon handling; see background/bg_objects/collab_parent.lua. +return require("background/bg_objects/collab_parent").extend("background/bg_collabs/a3", 4) diff --git a/Scripts/background/bg_collabs/animal.lua b/Scripts/background/bg_collabs/animal.lua index af38dbb..072e5be 100644 --- a/Scripts/background/bg_collabs/animal.lua +++ b/Scripts/background/bg_collabs/animal.lua @@ -1,121 +1,3 @@ --- YataiDON-HSS override of PyTaikoGreen/background/bg_collabs/animal.lua. -local DonBG4 = require("background/bg_objects/donbg/4") -local BGNormal = require("background/bg_objects/bg_normal") -local Fever = require("background/bg_objects/fever") -local Footer = require("background/bg_objects/footer") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") -local DancerModel = require("background/bg_objects/collab_dancer_model") - -local COLLAB_PATH = "background/collab/animal" -local MAX_DANCERS = 5 - --- BGFever: simple instant-transition, draws only background -local AnimalBGFever = {} -AnimalBGFever.__index = AnimalBGFever - -function AnimalBGFever.new() - local self = setmetatable({}, AnimalBGFever) - self.name = "bg_fever_0" - tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name) - self.transitioned = false - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/background") or 0 - return self -end - -function AnimalBGFever:start() self.transitioned = true end - -function AnimalBGFever:update(current_time_ms) end - -function AnimalBGFever:draw() tex.draw_texture(self._id_bg) end - -function AnimalBGFever:destroy() tex.unload_folder(COLLAB_PATH, "bg_fever/" .. self.name) end - --- Background - -local AnimalBackground = {} -AnimalBackground.__index = AnimalBackground - -function AnimalBackground.new(player_num, bpm) - local self = setmetatable({}, AnimalBackground) - self.donbg = DonBG4.new(5, player_num, "background") - self.bg_normal = BGNormal.Base.new(0, COLLAB_PATH) - self.bg_fever = AnimalBGFever.new() - self.footer = Footer.new(COLLAB_PATH, 0) - -- class Fever3, folder fever_0 - self.fever = Fever.Fever3.new(0, bpm, COLLAB_PATH) - self.dancer = Dancer.BaseDancerGroup.new(0, bpm, MAX_DANCERS, COLLAB_PATH) - self.renda = RendaController.new(COLLAB_PATH, 0) - self.chibi = ChibiController.new(bpm, COLLAB_PATH, 0) - self.is_clear = false - self.is_rainbow = false - -- reference dance_b_* count model - self.dancer_model = DancerModel.new(MAX_DANCERS) - return self -end - -function AnimalBackground:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_fever:update(current_ms) - self.fever:update(current_ms, bpm) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function AnimalBackground:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function AnimalBackground:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function AnimalBackground:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function AnimalBackground:handle_drumroll(player_num) self.renda:add_renda() end - -function AnimalBackground:handle_balloon(player_num) end - -function AnimalBackground:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) - self.donbg:set_clear(is_clear) - if is_clear and not self.is_clear then self.bg_fever:start() end - if not is_clear and self.is_clear and self.bg_fever.reset then self.bg_fever:reset() end - if is_rainbow and not self.is_rainbow then self.fever:start() end - if not is_rainbow and self.is_rainbow and self.fever.stop then self.fever:stop() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - self.dancer_model:apply(self.dancer, progress, is_clear, clear_progress) -end - -function AnimalBackground:draw_back() - if self.is_clear then - if not self.bg_fever.transitioned then - self.bg_normal:draw() - self.bg_fever:draw() - else - self.bg_fever:draw() - end - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - self.footer:draw() - if self.fever.is_visible and self.fever:is_visible() then self.fever:draw() end - self.chibi:draw() -end - -function AnimalBackground:draw_fore() end - -function AnimalBackground:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.fever:destroy() - self.dancer:destroy() - self.footer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - -return AnimalBackground +-- PyTaikoGreen's animal collab backdrop (its art and script) with this skin's collab dancer count +-- and balloon handling; see background/bg_objects/collab_parent.lua. +return require("background/bg_objects/collab_parent").extend("background/bg_collabs/animal", 5) diff --git a/Scripts/background/bg_collabs/buttoburst.lua b/Scripts/background/bg_collabs/buttoburst.lua index 3ee8aa6..5105133 100644 --- a/Scripts/background/bg_collabs/buttoburst.lua +++ b/Scripts/background/bg_collabs/buttoburst.lua @@ -1,121 +1,3 @@ --- YataiDON-HSS override of PyTaikoGreen/background/bg_collabs/buttoburst.lua. -local DonBG4 = require("background/bg_objects/donbg/4") -local BGNormal = require("background/bg_objects/bg_normal") -local Fever = require("background/bg_objects/fever") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") -local DancerModel = require("background/bg_objects/collab_dancer_model") - -local COLLAB_PATH = "background/collab/buttoburst" -local MAX_DANCERS = 4 - --- BGFever: instant-transition, draws background + overlay -local ButtoBGFever = {} -ButtoBGFever.__index = ButtoBGFever - -function ButtoBGFever.new() - local self = setmetatable({}, ButtoBGFever) - self.name = "bg_fever_0" - tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name) - self.transitioned = false - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/background") or 0 - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - return self -end - -function ButtoBGFever:start() self.transitioned = true end - -function ButtoBGFever:update(current_time_ms) end - -function ButtoBGFever:draw() - tex.draw_texture(self._id_bg) - tex.draw_texture(self._id_overlay) -end - -function ButtoBGFever:destroy() tex.unload_folder(COLLAB_PATH, "bg_fever/" .. self.name) end - --- Background - -local ButtoBackground = {} -ButtoBackground.__index = ButtoBackground - -function ButtoBackground.new(player_num, bpm) - local self = setmetatable({}, ButtoBackground) - self.donbg = DonBG4.new(5, player_num, "background") - self.bg_normal = BGNormal.Base.new(0, COLLAB_PATH) - self.bg_fever = ButtoBGFever.new() - -- class Fever3, folder fever_0 - self.fever = Fever.Fever3.new(0, bpm, COLLAB_PATH) - self.dancer = Dancer.BaseDancerGroup.new(0, bpm, MAX_DANCERS, COLLAB_PATH) - self.renda = RendaController.new(COLLAB_PATH, 0) - self.chibi = ChibiController.new(bpm, COLLAB_PATH, 0) - self.is_clear = false - self.is_rainbow = false - -- reference dance_b_* count model - self.dancer_model = DancerModel.new(MAX_DANCERS) - return self -end - -function ButtoBackground:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_fever:update(current_ms) - self.fever:update(current_ms, bpm) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function ButtoBackground:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function ButtoBackground:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function ButtoBackground:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function ButtoBackground:handle_drumroll(player_num) self.renda:add_renda() end - -function ButtoBackground:handle_balloon(player_num) end - -function ButtoBackground:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) - self.donbg:set_clear(is_clear) - if is_clear and not self.is_clear then self.bg_fever:start() end - if not is_clear and self.is_clear and self.bg_fever.reset then self.bg_fever:reset() end - if is_rainbow and not self.is_rainbow then self.fever:start() end - if not is_rainbow and self.is_rainbow and self.fever.stop then self.fever:stop() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - self.dancer_model:apply(self.dancer, progress, is_clear, clear_progress) -end - -function ButtoBackground:draw_back() - if self.is_clear then - if not self.bg_fever.transitioned then - self.bg_normal:draw() - self.bg_fever:draw() - else - self.bg_fever:draw() - end - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - if self.fever.is_visible and self.fever:is_visible() then self.fever:draw() end - self.chibi:draw() -end - -function ButtoBackground:draw_fore() end - -function ButtoBackground:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.fever:destroy() - self.dancer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - -return ButtoBackground +-- PyTaikoGreen's buttoburst collab backdrop (its art and script) with this skin's collab dancer count +-- and balloon handling; see background/bg_objects/collab_parent.lua. +return require("background/bg_objects/collab_parent").extend("background/bg_collabs/buttoburst", 4) diff --git a/Scripts/background/bg_collabs/funassyi.lua b/Scripts/background/bg_collabs/funassyi.lua index 43b66d5..b2cfa1b 100644 --- a/Scripts/background/bg_collabs/funassyi.lua +++ b/Scripts/background/bg_collabs/funassyi.lua @@ -1,156 +1,3 @@ --- YataiDON-HSS override of PyTaikoGreen/background/bg_collabs/funassyi.lua: overlay second-copy offset uses overlay_info.x2[1] -local DonBG4 = require("background/bg_objects/donbg/4") -local BGNormal = require("background/bg_objects/bg_normal") -local Fever = require("background/bg_objects/fever") -local Footer = require("background/bg_objects/footer") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") -local DancerModel = require("background/bg_objects/collab_dancer_model") - -local COLLAB_PATH = "background/collab/funassyi" -local MAX_DANCERS = 5 - --- BGFever: animated slide-in using anims 16-17, then horizontal tile scroll -local FunassyiBGFever = {} -FunassyiBGFever.__index = FunassyiBGFever - -function FunassyiBGFever.new() - local self = setmetatable({}, FunassyiBGFever) - self.name = "bg_fever_0" - tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name) - self.transitioned = false - self.horizontal_move = tex.get_animation(16, "background") - self.bg_texture_move = tex.get_animation(17, "background") - local overlay_info = tex.get_texture_info(self.name, "overlay") - self.overlay_width = overlay_info and overlay_info.x2[1] or 0 - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/background") or 0 - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - return self -end - -function FunassyiBGFever:start() - self.bg_texture_move:start() -end - -function FunassyiBGFever:reset() - self.transitioned = false -end - -function FunassyiBGFever:update(current_time_ms) - self.bg_texture_move:update(current_time_ms) - if self.bg_texture_move.is_finished and not self.transitioned then - self.transitioned = true - self.horizontal_move:restart() - end - if self.transitioned then - self.horizontal_move:update(current_time_ms) - end -end - -function FunassyiBGFever:draw() - local y = self.bg_texture_move.attribute - tex.draw_texture(self._id_bg, { y = y }) - tex.draw_texture(self._id_overlay, { x = -self.horizontal_move.attribute, y = y }) - tex.draw_texture(self._id_overlay, { x = self.overlay_width - self.horizontal_move.attribute, y = y }) -end - -function FunassyiBGFever:destroy() - tex.unload_folder(COLLAB_PATH, "bg_fever/" .. self.name) -end - --- Background - -local FunassyiBackground = {} -FunassyiBackground.__index = FunassyiBackground - -function FunassyiBackground.new(player_num, bpm) - local self = setmetatable({}, FunassyiBackground) - self.donbg = DonBG4.new(1, player_num, COLLAB_PATH) - self.bg_normal = BGNormal.Base.new(0, COLLAB_PATH) - self.bg_fever = FunassyiBGFever.new() - -- funassyi ships no footer/fever/renda art; use inert stubs. - self.footer = Footer.new(COLLAB_PATH, -1) - self.fever = { - start = function() end, stop = function() end, - update = function() end, draw = function() end, - is_visible = function() return false end, - alpha = function() return 0 end, destroy = function() end, - } - self.dancer = Dancer.BaseDancerGroup.new(0, bpm, MAX_DANCERS, COLLAB_PATH) - self.renda = { - add_renda = function() end, update = function() end, - draw = function() end, destroy = function() end, - } - self.chibi = ChibiController.new(bpm, COLLAB_PATH, 0) - self.is_clear = false - self.is_rainbow = false - -- reference dance_b_* count model - self.dancer_model = DancerModel.new(MAX_DANCERS) - return self -end - -function FunassyiBackground:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_fever:update(current_ms) - self.fever:update(current_ms, bpm) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function FunassyiBackground:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function FunassyiBackground:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function FunassyiBackground:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function FunassyiBackground:handle_drumroll(player_num) self.renda:add_renda() end - -function FunassyiBackground:handle_balloon(player_num) end - -function FunassyiBackground:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) - self.donbg:set_clear(is_clear) - if is_clear and not self.is_clear then self.bg_fever:start() end - if not is_clear and self.is_clear and self.bg_fever.reset then self.bg_fever:reset() end - if is_rainbow and not self.is_rainbow then self.fever:start() end - if not is_rainbow and self.is_rainbow and self.fever.stop then self.fever:stop() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - self.dancer_model:apply(self.dancer, progress, is_clear, clear_progress) -end - -function FunassyiBackground:draw_back() - if self.is_clear then - if not self.bg_fever.transitioned then - self.bg_normal:draw() - self.bg_fever:draw() - else - self.bg_fever:draw() - end - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - self.footer:draw() - if self.fever.is_visible and self.fever:is_visible() then self.fever:draw() end - self.chibi:draw() -end - -function FunassyiBackground:draw_fore() end - -function FunassyiBackground:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.fever:destroy() - self.dancer:destroy() - self.footer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - -return FunassyiBackground +-- PyTaikoGreen's funassyi collab backdrop (its art and script) with this skin's collab dancer count +-- and balloon handling; see background/bg_objects/collab_parent.lua. +return require("background/bg_objects/collab_parent").extend("background/bg_collabs/funassyi", 5) diff --git a/Scripts/background/bg_collabs/gumi.lua b/Scripts/background/bg_collabs/gumi.lua deleted file mode 100644 index 6f14797..0000000 --- a/Scripts/background/bg_collabs/gumi.lua +++ /dev/null @@ -1,200 +0,0 @@ --- YataiDONNijiiro: PyTaikoGreen's bg_collabs/gumi.lua, with GumiDonBG filling in PyTaikoGreen's --- DonBG6 fields (this skin overrides donbg/6). -local DonBG6 = require("background/bg_objects/donbg/6") -local Fever = require("background/bg_objects/fever") -local Footer = require("background/bg_objects/footer") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") - -local COLLAB_PATH = "background/collab/gumi" -local MAX_DANCERS = 5 - -local GumiDonBG = setmetatable({}, { __index = DonBG6 }) -GumiDonBG.__index = GumiDonBG - -function GumiDonBG.new(index, player_num, path) - local self = setmetatable({}, GumiDonBG) - local base = DonBG6.new(index, player_num, path) - for k, v in pairs(base) do self[k] = v end - -- this skin's donbg/6 is its own (a static band) and leaves out what PyTaikoGreen's DonBG6 - -- sets for the scrolling overlays that draw_textures below uses - self.overlay_move = self.overlay_move or tex.get_animation(2, "background") - self.overlay_1_texture = self.overlay_1_texture or tex.get_texture_info(self.name, "overlay_1") - self.overlay_2_texture = self.overlay_2_texture or tex.get_texture_info(self.name, "overlay_2") - self._id_overlay_1 = self._id_overlay_1 or tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay_1") or 0 - self._id_overlay_2 = self._id_overlay_2 or tex.get_texture(self.path .. "/" .. self.name .. "/" .. "overlay_2") or 0 - return self -end - -function GumiDonBG:update(current_time_ms) - DonBG6.update(self, current_time_ms) - if self.overlay_move then self.overlay_move:update(current_time_ms) end -end - -function GumiDonBG:draw_textures(fade, y, frame) - for i = 0, 4 do - tex.draw_texture(self._id_bg, { - frame = frame, - fade = fade, - x = (i * self.bg_texture.width) + self.move.attribute, - y = y - }) - end - for i = 0, 5, 2 do - tex.draw_texture(self._id_overlay_1, { - frame = frame, - fade = fade, - x = (i * self.overlay_1_texture.width) + self.move.attribute * 3, - y = y - }) - end - for i = 0, 4 do - tex.draw_texture(self._id_overlay_2, { - frame = frame, - fade = fade, - x = (i * self.overlay_2_texture.width) + self.move.attribute, - y = self.overlay_move.attribute + y - }) - end -end - -local GumiBGNormal = {} -GumiBGNormal.__index = GumiBGNormal - -function GumiBGNormal.new() - local self = setmetatable({}, GumiBGNormal) - self.name = "bg_0" - tex.load_folder(COLLAB_PATH, "bg_normal/" .. self.name) - local bg_info = tex.get_texture_info(self.name, "background") - local frames = (bg_info and bg_info.frame_count) or 1 - local textures = {} - for i = 0, frames - 1 do - table.insert(textures, { i * 500, (i + 1) * 500, i }) - end - self.letter_cycle = anim.texture_change(frames * 500, textures, { loop = true }) - self.letter_cycle:start() - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/" .. "background") or 0 - return self -end - -function GumiBGNormal:update(current_time_ms) self.letter_cycle:update(current_time_ms) end - -function GumiBGNormal:draw() - tex.draw_texture(self._id_bg, { frame = self.letter_cycle.attribute }) -end - -function GumiBGNormal:destroy() tex.unload_folder(COLLAB_PATH, "bg_normal/" .. self.name) end - -local GumiBGFever = {} -GumiBGFever.__index = GumiBGFever - -function GumiBGFever.new() - local self = setmetatable({}, GumiBGFever) - self.name = "bg_fever_0" - tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name) - self.transitioned = false - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/" .. "background") or 0 - return self -end - -function GumiBGFever:start() end -function GumiBGFever:update(current_time_ms) end -function GumiBGFever:draw() tex.draw_texture(self._id_bg) end -function GumiBGFever:destroy() tex.unload_folder(COLLAB_PATH, "bg_fever/" .. self.name) end - --- Background - -local GumiBackground = {} -GumiBackground.__index = GumiBackground - -function GumiBackground.new(player_num, bpm) - local self = setmetatable({}, GumiBackground) - self.donbg = GumiDonBG.new(1, player_num, COLLAB_PATH) - self.bg_normal = GumiBGNormal.new() - self.bg_fever = GumiBGFever.new() - self.footer = Footer.new(COLLAB_PATH, -1) - self.fever = Fever.create(0, bpm, COLLAB_PATH) - self.dancer = Dancer.BaseDancerGroup.new(0, bpm, MAX_DANCERS, COLLAB_PATH) - for i, d in ipairs(self.dancer.dancers) do - if d.index == 4 then - self.dancer.dancers[i], self.dancer.dancers[1] = self.dancer.dancers[1], self.dancer.dancers[i] - break - end - end - self.renda = RendaController.new(COLLAB_PATH, 0) - self.chibi = ChibiController.new(bpm, COLLAB_PATH, 1) - self.is_clear = false - self.is_rainbow = false - self.last_milestone = 1 - return self -end - -function GumiBackground:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_normal:update(current_ms) - self.fever:update(current_ms, bpm) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function GumiBackground:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function GumiBackground:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function GumiBackground:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function GumiBackground:handle_drumroll(player_num) self.renda:add_renda() end - -function GumiBackground:handle_balloon(player_num) self.renda:add_renda() end - -function GumiBackground:handle_gauge(player_num, progress, is_clear, is_rainbow) - self.donbg:set_clear(is_clear) - if is_rainbow and not self.is_rainbow then self.fever:start() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - local current_milestone - if is_clear then - current_milestone = MAX_DANCERS - else - current_milestone = math.min(MAX_DANCERS - 1, math.floor(progress * MAX_DANCERS)) - end - if current_milestone > self.last_milestone then - for _ = 1, current_milestone - self.last_milestone do self.dancer:add_dancer() end - self.last_milestone = current_milestone - elseif current_milestone < self.last_milestone then - for _ = 1, self.last_milestone - current_milestone do self.dancer:remove_dancer() end - self.last_milestone = current_milestone - end -end - -function GumiBackground:draw_back() - if self.is_clear then - self.bg_fever:draw() - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - self.footer:draw() - if self.is_rainbow then self.fever:draw() end - self.chibi:draw() -end - -function GumiBackground:draw_fore() end - -function GumiBackground:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.fever:destroy() - self.dancer:destroy() - self.footer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - -return GumiBackground diff --git a/Scripts/background/bg_collabs/imas.lua b/Scripts/background/bg_collabs/imas.lua index ff778a5..16f74e7 100644 --- a/Scripts/background/bg_collabs/imas.lua +++ b/Scripts/background/bg_collabs/imas.lua @@ -1,242 +1,3 @@ --- YataiDON-HSS override of PyTaikoGreen/background/bg_collabs/imas.lua. -local DonBGBase = require("background/bg_objects/donbg/base") -local Fever = require("background/bg_objects/fever") -local Footer = require("background/bg_objects/footer") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") -local DancerModel = require("background/bg_objects/collab_dancer_model") - -local COLLAB_PATH -- set per-variant in create() -local MAX_DANCERS -- set per-variant in create() - --- Spotlight colors: {r,g,b,a} -local SPOTLIGHT_COLORS = { - { 0, 255, 255, 255 }, -- cyan - { 255, 255, 0, 255 }, -- yellow - { 255, 0, 255, 255 }, -- magenta - { 0, 255, 255, 255 }, -- cyan - { 255, 255, 0, 255 }, -- yellow -} - --- BGNormal: flicker fade + 5 alternating spotlights -local ImasBGNormal = {} -ImasBGNormal.__index = ImasBGNormal - -function ImasBGNormal.new(path) - local self = setmetatable({}, ImasBGNormal) - self.name = "bg_0" - self.path = path - tex.load_folder(path, "bg_normal/" .. self.name) - self.overlay_fade = anim.fade(1000, { - initial_opacity = 0.0, - final_opacity = 1.0, - reverse_delay = 500, - delay = 500, - loop = true - }) - self._id_bg = tex.get_texture(self.path .. "/" .. self.name .. "/background") or 0 - self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/overlay") or 0 - self._id_spotlight = tex.get_texture(self.path .. "/" .. self.name .. "/spotlight") or 0 - return self -end - -function ImasBGNormal:update(current_time_ms) - self.overlay_fade:update(current_time_ms) -end - -function ImasBGNormal:draw() - local ov = self.overlay_fade.attribute - tex.draw_texture(self._id_bg) - tex.draw_texture(self._id_overlay, { fade = ov }) - for i = 0, 4 do - local fade = (i % 2 == 0) and math.min(0.5, ov) or math.min(0.5, 1 - ov) - tex.draw_texture(self._id_spotlight, { - index = i, color = SPOTLIGHT_COLORS[i + 1], fade = fade - }) - end -end - -function ImasBGNormal:destroy() - tex.unload_folder(self.path, "bg_normal/" .. self.name) -end - --- BGFever: same flicker fade + spotlights + orange/green lights -local ImasBGFever = {} -ImasBGFever.__index = ImasBGFever - -function ImasBGFever.new(path) - local self = setmetatable({}, ImasBGFever) - self.name = "bg_fever_0" - self.path = path - tex.load_folder(path, "bg_fever/" .. self.name) - self.transitioned = false - self.overlay_fade = anim.fade(1000, { - initial_opacity = 0.0, - final_opacity = 1.0, - reverse_delay = 500, - delay = 500, - loop = true - }) - self._id_bg = tex.get_texture(self.path .. "/" .. self.name .. "/background") or 0 - self._id_overlay = tex.get_texture(self.path .. "/" .. self.name .. "/overlay") or 0 - self._id_light_orange = tex.get_texture(self.path .. "/" .. self.name .. "/light_orange") or 0 - self._id_light_green = tex.get_texture(self.path .. "/" .. self.name .. "/light_green") or 0 - self._id_spotlight = tex.get_texture(self.path .. "/" .. self.name .. "/spotlight") or 0 - return self -end - -function ImasBGFever:start() - self.transitioned = true -end - -function ImasBGFever:update(current_time_ms) - self.overlay_fade:update(current_time_ms) -end - -function ImasBGFever:draw() - local ov = self.overlay_fade.attribute - tex.draw_texture(self._id_bg) - tex.draw_texture(self._id_overlay, { fade = ov }) - tex.draw_texture(self._id_light_orange, { fade = ov }) - tex.draw_texture(self._id_light_green, { fade = 1 - ov }) - for i = 0, 4 do - local fade = (i % 2 == 0) and math.min(0.5, ov) or math.min(0.5, 1 - ov) - tex.draw_texture(self._id_spotlight, { - index = i, color = SPOTLIGHT_COLORS[i + 1], fade = fade - }) - end -end - -function ImasBGFever:destroy() - tex.unload_folder(self.path, "bg_fever/" .. self.name) -end - --- Fever: BaseFever + 2-frame texture_change overlay (2-beat cycle) -local ImasFever = setmetatable({}, { __index = Fever.Base }) -ImasFever.__index = ImasFever - -function ImasFever.new(bpm, path) - local self = setmetatable({}, ImasFever) - local base = Fever.Base.new(0, bpm, path) - for k, v in pairs(base) do self[k] = v end - local total = 120000 / bpm - self.texture_change = anim.texture_change(total, { - { 0, total / 2, 0 }, - { total / 2, total, 1 } - }, { loop = true }) - return self -end - -function ImasFever:update(current_time_ms, bpm) - Fever.Base.update(self, current_time_ms, bpm) - self.texture_change:update(current_time_ms) -end - -function ImasFever:draw() - local a = self:alpha() - if a <= 0.001 then return end - local y = self.bounce_down.attribute - self.bounce_up.attribute - tex.draw_texture(self._id_overlay, { y = y, frame = self.texture_change.attribute, fade = a }) -end - --- Background factory (used for IMAS, IMAS_CG, IMAS_ML) - -local ImasBackground = {} -ImasBackground.__index = ImasBackground - -function ImasBackground.new(player_num, bpm, path, max_dancers) - local self = setmetatable({}, ImasBackground) - self.donbg = DonBGBase.new(1, player_num, path) - self.bg_normal = ImasBGNormal.new(path) - self.bg_fever = ImasBGFever.new(path) - self.footer = Footer.new(path, 0) - self.fever = ImasFever.new(bpm, path) - self.dancer = Dancer.BaseDancerGroup.new(0, bpm, max_dancers, path) - self.renda = RendaController.new(path, 0) - self.chibi = ChibiController.new(bpm, path, 0) - self.max_dancers = max_dancers - self.is_clear = false - self.is_rainbow = false - -- reference dance_b_* count model - self.dancer_model = DancerModel.new(max_dancers) - return self -end - -function ImasBackground:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_normal:update(current_ms) - self.bg_fever:update(current_ms) - self.fever:update(current_ms, bpm) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function ImasBackground:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function ImasBackground:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function ImasBackground:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function ImasBackground:handle_drumroll(player_num) self.renda:add_renda() end - -function ImasBackground:handle_balloon(player_num) end - -function ImasBackground:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) - self.donbg:set_clear(is_clear) - if is_clear and not self.is_clear then self.bg_fever:start() end - if not is_clear and self.is_clear and self.bg_fever.reset then self.bg_fever:reset() end - if is_rainbow and not self.is_rainbow then self.fever:start() end - if not is_rainbow and self.is_rainbow and self.fever.stop then self.fever:stop() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - self.dancer_model:apply(self.dancer, progress, is_clear, clear_progress) -end - -function ImasBackground:draw_back() - if self.is_clear then - if not self.bg_fever.transitioned then - self.bg_normal:draw() - self.bg_fever:draw() - else - self.bg_fever:draw() - end - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - self.footer:draw() - if self.fever.is_visible and self.fever:is_visible() then self.fever:draw() end - self.chibi:draw() -end - -function ImasBackground:draw_fore() end - -function ImasBackground:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.fever:destroy() - self.dancer:destroy() - self.footer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - --- Export the factory and the ImasFever class (reused by imas_sidem) -local Imas = {} -Imas.new = ImasBackground.new -Imas.ImasFever = ImasFever - --- Callable as a collab constructor: Imas.new(player_num, bpm, path, max_dancers) -setmetatable(Imas, { - __call = function(_, player_num, bpm, path, max_dancers) - return ImasBackground.new(player_num, bpm, path, max_dancers) - end -}) - -return Imas +-- PyTaikoGreen's imas collab backdrop (its art and script) with this skin's collab dancer count +-- and balloon handling; see background/bg_objects/collab_parent.lua. +return require("background/bg_objects/collab_parent").extend("background/bg_collabs/imas", 5) diff --git a/Scripts/background/bg_collabs/imas_sidem.lua b/Scripts/background/bg_collabs/imas_sidem.lua index 3290bf7..5265125 100644 --- a/Scripts/background/bg_collabs/imas_sidem.lua +++ b/Scripts/background/bg_collabs/imas_sidem.lua @@ -1,221 +1,3 @@ --- YataiDON-HSS override of PyTaikoGreen/background/bg_collabs/imas_sidem.lua: bg tile step/scroll period use bg_texture.x2[1] (no extra *sc) -local DonBGBase = require("background/bg_objects/donbg/base") -local Fever = require("background/bg_objects/fever") -local Footer = require("background/bg_objects/footer") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") -local DancerModel = require("background/bg_objects/collab_dancer_model") - -local COLLAB_PATH = "background/collab/imas_sidem" -local MAX_DANCERS = 3 - --- Custom DonBG: 16*scale tiled background with 8x scale scroll -local ImasSidemDonBG = setmetatable({}, { __index = DonBGBase }) -ImasSidemDonBG.__index = ImasSidemDonBG - -function ImasSidemDonBG.new(player_num) - local self = setmetatable({}, ImasSidemDonBG) - local base = DonBGBase.new(1, player_num, COLLAB_PATH) - for k, v in pairs(base) do self[k] = v end - local bg_width = self.bg_texture and self.bg_texture.x2[1] or 0 - local sc = tex.get_screen_scale() - self.move = anim.move(3000, { total_distance = -bg_width * 8, loop = true }) - return self -end - -function ImasSidemDonBG:draw_textures(fade, y, frame) - local sc = tex.get_screen_scale() - local bg_width = self.bg_texture and self.bg_texture.x2[1] or 0 - for i = 0, math.floor(16 * sc) - 1 do - tex.draw_texture(self._id_bg, { - frame = frame, - fade = fade, - x = (i * bg_width) + self.move.attribute, - y = y - }) - end -end - --- BGNormal: looping 4-frame screen texture change -local ImasSidemBGNormal = {} -ImasSidemBGNormal.__index = ImasSidemBGNormal - -function ImasSidemBGNormal.new() - local self = setmetatable({}, ImasSidemBGNormal) - self.name = "bg_0" - tex.load_folder(COLLAB_PATH, "bg_normal/" .. self.name) - self.screen_change = anim.texture_change(8000, { - { 0, 2000, 0 }, { 2000, 4000, 1 }, { 4000, 6000, 2 }, { 6000, 8000, 3 } - }, { loop = true }) - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/background") or 0 - self._id_screen = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/screen") or 0 - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - return self -end - -function ImasSidemBGNormal:update(current_time_ms) - self.screen_change:update(current_time_ms) -end - -function ImasSidemBGNormal:draw() - tex.draw_texture(self._id_bg) - tex.draw_texture(self._id_screen, { frame = self.screen_change.attribute }) - tex.draw_texture(self._id_overlay) -end - -function ImasSidemBGNormal:destroy() - tex.unload_folder(COLLAB_PATH, "bg_normal/" .. self.name) -end - --- BGFever: same screen texture change + overlay_2; immediately transitioned -local ImasSidemBGFever = {} -ImasSidemBGFever.__index = ImasSidemBGFever - -function ImasSidemBGFever.new() - local self = setmetatable({}, ImasSidemBGFever) - self.name = "bg_fever_0" - tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name) - self.transitioned = true - self.screen_change = anim.texture_change(8000, { - { 0, 2000, 0 }, { 2000, 4000, 1 }, { 4000, 6000, 2 }, { 6000, 8000, 3 } - }, { loop = true }) - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/background") or 0 - self._id_screen = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/screen") or 0 - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - self._id_overlay2 = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay_2") or 0 - return self -end - -function ImasSidemBGFever:start() end -- already transitioned - -function ImasSidemBGFever:update(current_time_ms) - self.screen_change:update(current_time_ms) -end - -function ImasSidemBGFever:draw() - tex.draw_texture(self._id_bg) - tex.draw_texture(self._id_screen, { frame = self.screen_change.attribute }) - tex.draw_texture(self._id_overlay) - tex.draw_texture(self._id_overlay2) -end - -function ImasSidemBGFever:destroy() - tex.unload_folder(COLLAB_PATH, "bg_fever/" .. self.name) -end - --- Fever: same 2-frame overlay as imas collab (2-beat cycle) -local ImasSidemFever = setmetatable({}, { __index = Fever.Base }) -ImasSidemFever.__index = ImasSidemFever - -function ImasSidemFever.new(bpm) - local self = setmetatable({}, ImasSidemFever) - local base = Fever.Base.new(0, bpm, COLLAB_PATH) - for k, v in pairs(base) do self[k] = v end - local total = 120000 / bpm - self.texture_change = anim.texture_change(total, { - { 0, total / 2, 0 }, - { total / 2, total, 1 } - }, { loop = true }) - return self -end - -function ImasSidemFever:update(current_time_ms, bpm) - Fever.Base.update(self, current_time_ms, bpm) - self.texture_change:update(current_time_ms) -end - -function ImasSidemFever:draw() - local a = self:alpha() - if a <= 0.001 then return end - local y = self.bounce_down.attribute - self.bounce_up.attribute - tex.draw_texture(self._id_overlay, { y = y, frame = self.texture_change.attribute, fade = a }) -end - --- Background - -local ImasSidemBackground = {} -ImasSidemBackground.__index = ImasSidemBackground - -function ImasSidemBackground.new(player_num, bpm) - local self = setmetatable({}, ImasSidemBackground) - self.donbg = ImasSidemDonBG.new(player_num) - self.bg_normal = ImasSidemBGNormal.new() - self.bg_fever = ImasSidemBGFever.new() - self.footer = Footer.new(COLLAB_PATH, 0) - self.fever = ImasSidemFever.new(bpm) - self.dancer = Dancer.BaseDancerGroup.new(0, bpm, MAX_DANCERS, COLLAB_PATH) - self.renda = RendaController.new(COLLAB_PATH, 0) - self.chibi = ChibiController.new(bpm, COLLAB_PATH, 0) - self.is_clear = false - self.is_rainbow = false - -- reference dance_b_* count model - self.dancer_model = DancerModel.new(MAX_DANCERS) - return self -end - -function ImasSidemBackground:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_normal:update(current_ms) - self.bg_fever:update(current_ms) - self.fever:update(current_ms, bpm) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function ImasSidemBackground:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function ImasSidemBackground:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function ImasSidemBackground:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function ImasSidemBackground:handle_drumroll(player_num) self.renda:add_renda() end - -function ImasSidemBackground:handle_balloon(player_num) end - -function ImasSidemBackground:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) - self.donbg:set_clear(is_clear) - if is_clear and not self.is_clear then self.bg_fever:start() end - if not is_clear and self.is_clear and self.bg_fever.reset then self.bg_fever:reset() end - if is_rainbow and not self.is_rainbow then self.fever:start() end - if not is_rainbow and self.is_rainbow and self.fever.stop then self.fever:stop() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - self.dancer_model:apply(self.dancer, progress, is_clear, clear_progress) -end - -function ImasSidemBackground:draw_back() - if self.is_clear then - if not self.bg_fever.transitioned then - self.bg_normal:draw() - self.bg_fever:draw() - else - self.bg_fever:draw() - end - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - self.footer:draw() - if self.fever.is_visible and self.fever:is_visible() then self.fever:draw() end - self.chibi:draw() -end - -function ImasSidemBackground:draw_fore() end - -function ImasSidemBackground:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.fever:destroy() - self.dancer:destroy() - self.footer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - -return ImasSidemBackground +-- PyTaikoGreen's imas_sidem collab backdrop (its art and script) with this skin's collab dancer count +-- and balloon handling; see background/bg_objects/collab_parent.lua. +return require("background/bg_objects/collab_parent").extend("background/bg_collabs/imas_sidem", 3) diff --git a/Scripts/background/bg_collabs/oshiri.lua b/Scripts/background/bg_collabs/oshiri.lua index a3d721c..5d414d0 100644 --- a/Scripts/background/bg_collabs/oshiri.lua +++ b/Scripts/background/bg_collabs/oshiri.lua @@ -1,203 +1,3 @@ --- YataiDON-HSS override of PyTaikoGreen/background/bg_collabs/oshiri.lua: bg tile step/scroll period use bg_texture.x2[1] (no extra *sc) -local DonBGBase = require("background/bg_objects/donbg/base") -local BGNormal = require("background/bg_objects/bg_normal") -local Fever = require("background/bg_objects/fever") -local Footer = require("background/bg_objects/footer") -local Dancer = require("background/bg_objects/dancer") -local RendaController = require("background/bg_objects/renda") -local ChibiController = require("background/bg_objects/chibi") -local DancerModel = require("background/bg_objects/collab_dancer_model") - -local COLLAB_PATH = "background/collab/oshiri" -local MAX_DANCERS = 5 - --- Custom DonBG: 16*scale wide tiled background + 3 overlay rows per tile -local OshiriDonBG = setmetatable({}, { __index = DonBGBase }) -OshiriDonBG.__index = OshiriDonBG - -function OshiriDonBG.new(player_num) - local self = setmetatable({}, OshiriDonBG) - local base = DonBGBase.new(1, player_num, COLLAB_PATH) - for k, v in pairs(base) do self[k] = v end - local bg_width = self.bg_texture and self.bg_texture.x2[1] or 0 - local sc = tex.get_screen_scale() - self.move = anim.move(20000, { total_distance = -bg_width * 8, loop = true }) - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - return self -end - -function OshiriDonBG:draw_textures(fade, y, frame) - local sc = tex.get_screen_scale() - local bg_width = self.bg_texture and self.bg_texture.x2[1] or 0 - for i = 0, math.floor(16 * sc) - 1 do - tex.draw_texture(self._id_bg, { - frame = frame, - fade = fade, - x = (i * bg_width) + self.move.attribute, - y = y - }) - for j = 0, 2 do - tex.draw_texture(self._id_overlay, { - frame = frame, - fade = fade, - x = (i * bg_width) + self.move.attribute, - y = y + (j * 70 * sc) - }) - end - end -end - --- BGFever: looping 3-frame overlay; immediately transitioned on start -local OshiriBGFever = {} -OshiriBGFever.__index = OshiriBGFever - -function OshiriBGFever.new() - local self = setmetatable({}, OshiriBGFever) - self.name = "bg_fever_0" - tex.load_folder(COLLAB_PATH, "bg_fever/" .. self.name) - self.transitioned = false - self.overlay_texture_change = anim.texture_change(2049, { - { 0, 683, 0 }, { 683, 1366, 1 }, { 1366, 2049, 2 } - }, { loop = true }) - self._id_bg = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/background") or 0 - self._id_overlay = tex.get_texture(COLLAB_PATH .. "/" .. self.name .. "/overlay") or 0 - return self -end - -function OshiriBGFever:start() - self.transitioned = true -end - -function OshiriBGFever:update(current_time_ms) - self.overlay_texture_change:update(current_time_ms) -end - -function OshiriBGFever:draw() - tex.draw_texture(self._id_bg) - tex.draw_texture(self._id_overlay, { frame = self.overlay_texture_change.attribute }) -end - -function OshiriBGFever:destroy() - tex.unload_folder(COLLAB_PATH, "bg_fever/" .. self.name) -end - --- Custom DancerGroup: fixed variant assignment (0, 1, 1, 1, 1), no shuffle -local OshiriDancerGroup = setmetatable({}, { __index = Dancer.BaseDancerGroup }) -OshiriDancerGroup.__index = OshiriDancerGroup - -function OshiriDancerGroup.new(bpm) - local self = setmetatable({}, OshiriDancerGroup) - self.name = "dancer_0" - self.active_count = 0 - self.path = COLLAB_PATH - tex.load_folder(COLLAB_PATH, "dancer/" .. self.name) - self.spawn_positions = { 2, 1, 3, 0, 4 } - self.active_dancers = {} - self.max_dancers = MAX_DANCERS - local BaseDancer = Dancer.Base - self.dancers = { - BaseDancer.new(self.name, 0, bpm, self.path), - BaseDancer.new(self.name, 1, bpm, self.path), - BaseDancer.new(self.name, 1, bpm, self.path), - BaseDancer.new(self.name, 1, bpm, self.path), - BaseDancer.new(self.name, 1, bpm, self.path), - } - self.needs_initial_dancer = true - return self -end - -function OshiriDancerGroup:update(current_time_ms, bpm) - if self.needs_initial_dancer then - self.needs_initial_dancer = false - self:add_dancer() - end - Dancer.BaseDancerGroup.update(self, current_time_ms, bpm) -end - --- Background - -local OshiriBackground = {} -OshiriBackground.__index = OshiriBackground - -function OshiriBackground.new(player_num, bpm) - local self = setmetatable({}, OshiriBackground) - self.donbg = OshiriDonBG.new(player_num) - self.bg_normal = BGNormal.Base.new(0, COLLAB_PATH) - self.bg_fever = OshiriBGFever.new() - self.footer = Footer.new(COLLAB_PATH, 0) - -- class Fever3, folder fever_0 - self.fever = Fever.Fever3.new(0, bpm, COLLAB_PATH) - self.dancer = OshiriDancerGroup.new(bpm) - self.renda = RendaController.new(COLLAB_PATH, 0) - self.chibi = ChibiController.new(bpm, COLLAB_PATH, 0) - self.is_clear = false - self.is_rainbow = false - -- reference dance_b_* count model - self.dancer_model = DancerModel.new(MAX_DANCERS) - return self -end - -function OshiriBackground:update(current_ms, bpm) - self.donbg:update(current_ms) - self.bg_fever:update(current_ms) - self.fever:update(current_ms, bpm) - self.dancer:update(current_ms, bpm) - self.renda:update(current_ms) - self.chibi:update(current_ms, bpm) -end - -function OshiriBackground:handle_good(player_num) self.chibi:add_chibi(player_num, false) end - -function OshiriBackground:handle_ok(player_num) self.chibi:add_chibi(player_num, false) end - -function OshiriBackground:handle_bad(player_num) self.chibi:add_chibi(player_num, true) end - -function OshiriBackground:handle_drumroll(player_num) self.renda:add_renda() end - -function OshiriBackground:handle_balloon(player_num) end - -function OshiriBackground:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) - self.donbg:set_clear(is_clear) - if is_clear and not self.is_clear then self.bg_fever:start() end - if not is_clear and self.is_clear and self.bg_fever.reset then self.bg_fever:reset() end - if is_rainbow and not self.is_rainbow then self.fever:start() end - if not is_rainbow and self.is_rainbow and self.fever.stop then self.fever:stop() end - self.is_clear = is_clear - self.is_rainbow = is_rainbow - - self.dancer_model:apply(self.dancer, progress, is_clear, clear_progress) -end - -function OshiriBackground:draw_back() - if self.is_clear then - if not self.bg_fever.transitioned then - self.bg_normal:draw() - self.bg_fever:draw() - else - self.bg_fever:draw() - end - else - self.bg_normal:draw() - end - self.donbg:draw() - self.renda:draw() - self.dancer:draw() - self.footer:draw() - if self.fever.is_visible and self.fever:is_visible() then self.fever:draw() end - self.chibi:draw() -end - -function OshiriBackground:draw_fore() end - -function OshiriBackground:destroy() - self.donbg:destroy() - self.bg_normal:destroy() - self.bg_fever:destroy() - self.fever:destroy() - self.dancer:destroy() - self.footer:destroy() - self.renda:destroy() - self.chibi:destroy() -end - -return OshiriBackground +-- PyTaikoGreen's oshiri collab backdrop (its art and script) with this skin's collab dancer count +-- and balloon handling; see background/bg_objects/collab_parent.lua. +return require("background/bg_objects/collab_parent").extend("background/bg_collabs/oshiri", 5) diff --git a/Scripts/background/bg_objects/collab_dancer_model.lua b/Scripts/background/bg_objects/collab_dancer_model.lua index 928e5f0..3ae047a 100644 --- a/Scripts/background/bg_objects/collab_dancer_model.lua +++ b/Scripts/background/bg_objects/collab_dancer_model.lua @@ -36,13 +36,17 @@ function CollabDancerModel:target(progress, is_clear, clear_progress) return n end --- Drives a BaseDancerGroup-shaped object to the target count. +-- 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 - local n = self:target(progress, is_clear, clear_progress) for _ = 1, n - cur do group:add_dancer() end - for _ = 1, cur - n do group:remove_dancer() end + local leave = group.leave_dancer or group.remove_dancer + for _ = 1, cur - n do leave(group) end end return CollabDancerModel diff --git a/Scripts/background/bg_objects/collab_parent.lua b/Scripts/background/bg_objects/collab_parent.lua new file mode 100644 index 0000000..1cf2955 --- /dev/null +++ b/Scripts/background/bg_objects/collab_parent.lua @@ -0,0 +1,53 @@ +-- A collab backdrop taken from the parent skin (its art and its script), with this skin's +-- collab behaviour on top: the dance_b_* dancer-count model and no drumroll burst on balloons. +-- The parent's script is loaded from its own file, so its requires resolve to the parent's +-- background objects, which its art is laid out for. +local DancerModel = require("background/bg_objects/collab_dancer_model") + +-- the parent skin's copy of a script: the second match on package.path (the first is this skin's) +local function load_parent(name) + local seen = false + for tmpl in package.path:gmatch("[^;]+") do + local chunk = loadfile((tmpl:gsub("%?", name))) + if chunk then + if seen then return chunk end + seen = true + end + end +end + +-- stands in for the dancers while the parent's handle_gauge runs, so its own count is inert +local NO_DANCERS = { + add_dancer = function() end, remove_dancer = function() end, + leave_dancer = function() end, set_count = function() end, +} + +local CollabParent = {} + +-- name: module name ("background/bg_collabs/animal"); max_dancers: the troupe size when the +-- engine's collab table gives none +function CollabParent.extend(name, max_dancers) + local chunk = assert(load_parent(name), name .. ": the parent skin has no such script") + local Class = chunk(name) + local base_new, base_gauge = Class.new, Class.handle_gauge + + function Class.new(player_num, bpm, path, max) + local self = base_new(player_num, bpm, path, max) + self.dancer_model = DancerModel.new(max or max_dancers) + return self + end + + function Class:handle_gauge(player_num, progress, is_clear, is_rainbow, clear_progress) + local dancers = self.dancer + self.dancer = NO_DANCERS + base_gauge(self, player_num, progress, is_clear, is_rainbow, clear_progress) + self.dancer = dancers + if dancers then self.dancer_model:apply(dancers, progress, is_clear, clear_progress) end + end + + function Class:handle_balloon(player_num) end + + return Class +end + +return CollabParent -- 2.54.0