-- LumenChibi: a good-hit chibi ported from Lumen data (Miku, GUMI). Hops in growing from -- 70% size, then runs straight across the don band. Timed in beats; driven by a spec: -- hop_x0, hop_y0: start offset from the run's start (texture.json position of chibi_1/1) -- hop_x, hop_y, grow (scale in thousandths, from 700): chain_moves over the hop -- hop_frames: frame_change steps during the hop; stride: looping frames while running -- hop_beats, run: { beats, distance } of the run, which starts after the hop -- Bad hits keep the shared chibi, which ChibiController still handles. local Timing = require("background/bg_objects/timing") local chain_moves, frame_change, sum = Timing.chain_moves, Timing.frame_change, Timing.sum local LumenChibi = {} LumenChibi.__index = LumenChibi function LumenChibi.new(spec, path, bpm, is_2p) local self = setmetatable({}, LumenChibi) local beat = 60000 / bpm local scale = tex.get_screen_scale() local offset = tex.get_skin_config("game_2p_offset") self._id = tex.get_texture(path .. "/chibi_1/1") or 0 self.y0 = (is_2p and offset and offset.y or 0) + math.floor(spec.hop_y0 * scale) self.x0 = math.floor(spec.hop_x0 * scale) self.hop_x = chain_moves(spec.hop_x, beat, scale) self.hop_y = chain_moves(spec.hop_y, beat, scale) self.grow = chain_moves(spec.grow, beat, 1) self.hop = frame_change(spec.hop_frames, beat) self.hop:start() -- ChibiController drops the chibi once hori_move finishes self.hori_move = chain_moves({ { spec.hop_beats, 0 }, spec.run }, beat, scale)[1] self.stride = frame_change(spec.stride, beat, { loop = true }) return self end function LumenChibi:update(current_time_ms) for _, m in ipairs(self.hop_x) do m:update(current_time_ms) end for _, m in ipairs(self.hop_y) do m:update(current_time_ms) end for _, m in ipairs(self.grow) do m:update(current_time_ms) end self.hop:update(current_time_ms) self.hori_move:update(current_time_ms) -- starts striding once it lands; a looping texture_change would repeat a delay if not self.stride.is_started and self.hop.is_finished then self.stride:start() end self.stride:update(current_time_ms) end function LumenChibi:draw() tex.draw_texture(self._id, { frame = self.stride.is_started and self.stride.attribute or self.hop.attribute, x = self.x0 + sum(self.hop_x) + self.hori_move.attribute, y = self.y0 + sum(self.hop_y), scale = (700 + sum(self.grow)) / 1000, center = true, }) end -- Adds a good-hit chibi to a ChibiController function LumenChibi.add(controller, spec, path, player_num) table.insert(controller.chibis, LumenChibi.new(spec, path, controller.bpm, player_num == 2)) end return LumenChibi