forked from Yonokid/PyTaikoGreen
186 lines
8.5 KiB
Lua
186 lines
8.5 KiB
Lua
Gauge = {}
|
|
Gauge.__index = Gauge
|
|
|
|
local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
|
|
|
|
-- Port of Gauge::draw / Gauge::draw_dan. C++ keeps the points logic and hands the
|
|
-- numbers over every frame; this only decides what gets drawn where.
|
|
function Gauge.new(is_2p, dan, string_diff)
|
|
local self = setmetatable({}, Gauge)
|
|
self.dan = dan
|
|
|
|
local cells = tex.get_skin_config("gauge_cells")
|
|
self.bar_units = (cells and cells.x and cells.x > 0) and math.floor(cells.x + 0.5) or 87
|
|
|
|
local p = (is_2p and "2p_" or "1p_")
|
|
local function t(name) return tex.get_texture("game/" .. name) end
|
|
|
|
if dan then
|
|
self.bar = t("gauge_dan/" .. p .. "bar")
|
|
self.bar_fade = t("gauge_dan/" .. p .. "bar_fade")
|
|
self.border = t("gauge_dan/border")
|
|
self.unfilled = t("gauge_dan/" .. p .. "unfilled")
|
|
self.rainbow = t("gauge_dan/rainbow")
|
|
self.overlay = t("gauge_dan/overlay")
|
|
self.fire = t("gauge_dan/tamashii_fire")
|
|
self.tamashii = t("gauge_dan/tamashii")
|
|
self.tamashii_overlay = t("gauge_dan/tamashii_overlay")
|
|
self.tamashii_dark = t("gauge_dan/tamashii_dark")
|
|
self.bar_width = tex.get_texture_info("gauge_dan", p .. "bar").width
|
|
else
|
|
self.border = t("gauge/border" .. string_diff)
|
|
self.unfilled = t("gauge/" .. p .. "unfilled" .. string_diff)
|
|
self.bar = t("gauge/" .. p .. "bar")
|
|
self.clear_transition = t("gauge/bar_clear_transition")
|
|
self.clear_top = t("gauge/bar_clear_top")
|
|
self.clear_bottom = t("gauge/bar_clear_bottom")
|
|
self.rainbow = t("gauge/rainbow" .. string_diff)
|
|
self.clear_transition_fade = t("gauge/bar_clear_transition_fade")
|
|
self.clear_fade = t("gauge/bar_clear_fade")
|
|
self.bar_fade = t("gauge/" .. p .. "bar_fade")
|
|
self.overlay = t("gauge/overlay" .. string_diff)
|
|
self.fire = t("gauge/tamashii_fire")
|
|
self.tamashii = t("gauge/tamashii")
|
|
self.tamashii_overlay = t("gauge/tamashii_overlay")
|
|
self.tamashii_dark = t("gauge/tamashii_dark")
|
|
-- language variants (clear_ja ...) are resolved by tex.get_texture
|
|
self.clear = t("gauge/clear")
|
|
self.clear_dark = t("gauge/clear_dark")
|
|
self.bar_width = tex.get_texture_info("gauge", p .. "bar").width
|
|
self.art_tier = (string_diff == "_easy") and 0 or (string_diff == "_normal") and 1 or 2
|
|
end
|
|
return self
|
|
end
|
|
|
|
-- cell bookkeeping shared by both gauges: how many cells are solid, and the alpha of the
|
|
-- sprite on the cell that was just filled (nil when there is none to show).
|
|
function Gauge:cells(points, previous_points, max_points, anim_active, anim_alpha)
|
|
local units = self.bar_units
|
|
local length = math.floor(points * units / max_points)
|
|
local previous = math.floor(previous_points * units / max_points)
|
|
local fade_in = tex.get_option("gauge_cell_fade_in")
|
|
local pending = length <= units and length > previous and anim_active
|
|
local solid = (fade_in and pending) and length - 1 or length
|
|
local alpha = fade_in and 1.0 - anim_alpha or anim_alpha
|
|
local show_up
|
|
if fade_in then show_up = pending else show_up = length <= units and length > previous end
|
|
return length, solid, alpha, show_up, pending, fade_in
|
|
end
|
|
|
|
function Gauge:draw(y, points, previous_points, max_points, clear_points,
|
|
is_clear, is_rainbow, anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
|
if self.dan then
|
|
return self:draw_dan(points, previous_points, max_points, is_rainbow,
|
|
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
|
end
|
|
local mirrored = y > tex.get_screen_height() / 2
|
|
local mirror = mirrored and "vertical" or nil
|
|
local idx = mirrored and 1 or 0
|
|
|
|
tex.draw_texture(self.border, { mirror = mirror, y = y, index = idx })
|
|
tex.draw_texture(self.unfilled, { mirror = mirror, y = y, index = idx })
|
|
|
|
local units, bw = self.bar_units, self.bar_width
|
|
local length, solid, alpha, show_up, pending, fade_in =
|
|
self:cells(points, previous_points, max_points, anim_active, anim_alpha)
|
|
local clear_point = clamp(clear_points * units // max_points, 1, units)
|
|
|
|
if solid > 0 then
|
|
tex.draw_texture(self.bar, { y = y, index = idx,
|
|
x2 = math.min(solid * bw, (clear_point - 1) * bw) - bw })
|
|
end
|
|
|
|
-- first gold cell lights exactly when the gauge is cleared (not by a cell-count test:
|
|
-- on 87 cells 8000 -> 69.6 would light it a cell early/late vs. the clear state)
|
|
if is_clear and not (fade_in and pending and length == clear_point) then
|
|
tex.draw_texture(self.clear_transition,
|
|
{ mirror = mirror, x = (clear_point - 1) * bw, y = y, index = idx })
|
|
end
|
|
|
|
-- gold zone: cells clear_point .. solid-1, one cell wide piece so stretch is (n-1)*bw
|
|
if solid > clear_point then
|
|
local gold_x2 = (solid - clear_point) * bw - bw
|
|
tex.draw_texture(self.clear_top,
|
|
{ mirror = mirror, x = clear_point * bw, y = y, x2 = gold_x2, index = idx })
|
|
tex.draw_texture(self.clear_bottom,
|
|
{ x = clear_point * bw, y = y, x2 = gold_x2, index = idx })
|
|
end
|
|
|
|
if is_rainbow and rainbow_fade >= 0 then
|
|
local frame_a = math.floor(rainbow_frac) % 8
|
|
local frame_b = (frame_a + 1) % 8
|
|
local f = rainbow_frac - math.floor(rainbow_frac)
|
|
tex.draw_texture(self.rainbow,
|
|
{ frame = frame_a, mirror = mirror, y = y, fade = rainbow_fade, index = idx })
|
|
tex.draw_texture(self.rainbow,
|
|
{ frame = frame_b, mirror = mirror, y = y, fade = rainbow_fade * f, index = idx })
|
|
end
|
|
|
|
if show_up then
|
|
-- sprite sits on the cell that was just filled (length-1)
|
|
local fx = (length - 1) * bw
|
|
if length == clear_point then
|
|
tex.draw_texture(self.clear_transition_fade,
|
|
{ mirror = mirror, x = fx, y = y, fade = alpha, index = idx })
|
|
elseif length > clear_point then
|
|
tex.draw_texture(self.clear_fade, { x = fx, y = y, fade = alpha, index = idx })
|
|
else
|
|
tex.draw_texture(self.bar_fade, { x = fx, y = y, fade = alpha, index = idx })
|
|
end
|
|
end
|
|
|
|
tex.draw_texture(self.overlay, { mirror = mirror, y = y, fade = 0.15, index = idx })
|
|
|
|
local label = self.art_tier + (mirrored and 3 or 0)
|
|
if is_clear then
|
|
tex.draw_texture(self.clear, { y = y, index = label })
|
|
if is_rainbow then
|
|
tex.draw_texture(self.fire,
|
|
{ frame = fire_frame, scale = 0.75, center = true, y = y, index = idx })
|
|
end
|
|
tex.draw_texture(self.tamashii, { y = y, index = idx })
|
|
if is_rainbow and (fire_frame == 0 or fire_frame == 1 or fire_frame == 4 or fire_frame == 5) then
|
|
tex.draw_texture(self.tamashii_overlay, { y = y, fade = 0.5, index = idx })
|
|
end
|
|
else
|
|
tex.draw_texture(self.clear_dark, { y = y, index = label })
|
|
tex.draw_texture(self.tamashii_dark, { y = y, index = idx })
|
|
end
|
|
end
|
|
|
|
-- dan gauge sits at absolute positions from its texture.json: no lane offset, no mirroring
|
|
function Gauge:draw_dan(points, previous_points, max_points, is_rainbow,
|
|
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
|
tex.draw_texture(self.border, {})
|
|
tex.draw_texture(self.unfilled, {})
|
|
|
|
local bw = self.bar_width
|
|
local length, solid, alpha, show_up = self:cells(points, previous_points, max_points, anim_active, anim_alpha)
|
|
|
|
if solid > 0 then tex.draw_texture(self.bar, { x2 = solid * bw - bw }) end
|
|
|
|
if is_rainbow and rainbow_fade >= 0 then
|
|
local frame_a = math.floor(rainbow_frac) % 8
|
|
local frame_b = (frame_a + 1) % 8
|
|
local f = rainbow_frac - math.floor(rainbow_frac)
|
|
tex.draw_texture(self.rainbow, { frame = frame_a, fade = rainbow_fade })
|
|
tex.draw_texture(self.rainbow, { frame = frame_b, fade = rainbow_fade * f })
|
|
end
|
|
|
|
if show_up and length > 0 then
|
|
tex.draw_texture(self.bar_fade, { x = (length - 1) * bw, fade = alpha })
|
|
end
|
|
|
|
tex.draw_texture(self.overlay, { fade = 0.15 })
|
|
|
|
if is_rainbow then
|
|
tex.draw_texture(self.fire, { frame = fire_frame, scale = 0.75, center = true })
|
|
tex.draw_texture(self.tamashii, {})
|
|
if fire_frame == 0 or fire_frame == 1 or fire_frame == 4 or fire_frame == 5 then
|
|
tex.draw_texture(self.tamashii_overlay, { fade = 0.5 })
|
|
end
|
|
else
|
|
tex.draw_texture(self.tamashii_dark, {})
|
|
end
|
|
end
|