Author SHA1 Message Date
TaikoZhongandClaude Fable 5.1 dd036cb85e result: clear state and clear-zone art follow the engine's norma
gauge_state came from a cell count (68 of 87 for oni) while the game clears on soul >= norma (6000/7000/7000/8000); in the band just below the norma the result lit the gold cell, the clear caption and a crown for a failed run. Hard also used the oni layout although the HUD gives it normal's zone and norma. Derive the state from the soul value, pick the art tier like the HUD, and light the gold cell and caption only when cleared.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 12:18:31 +08:00
+22 -11
View File
@@ -22,19 +22,25 @@ function ResultPlayer.new(player_num, is_2p, has_2p,
self.mod_random = mod_random
self.mod_speed = mod_speed
local clear_start = { 52, 60, 69 }
local diff_clamped = math.min(difficulty, 2)
-- Clear follows the engine's gauge (Gauge::get_is_clear: soul >= norma), not a cell
-- count: the norma is easy 6000 / normal 7000 / hard 7000 / oni+ura 8000 of 10000 soul,
-- and gauge_length arrives as soul / 10000 * 87. Hard shares normal's norma and so, like
-- the in-game HUD, normal's clear-zone art (zone at cell 60), not the oni layout.
local ART = { [0] = 0, [1] = 1, [2] = 1, [3] = 2 }
local NORMA = { [0] = 6000, [1] = 7000, [2] = 7000, [3] = 8000 }
local d = math.min(math.max(difficulty, 0), 3)
self.art_index = ART[d]
if gauge_length == 87 then
self.gauge_state = 2
elseif gauge_length >= clear_start[diff_clamped + 1] - 1 then
elseif gauge_length / 87.0 * 10000.0 >= NORMA[d] - 0.5 then
self.gauge_state = 1
else
self.gauge_state = 0
end
if difficulty >= 2 then
if self.art_index >= 2 then
self.diff_str = "_hard"
elseif difficulty >= 1 then
elseif self.art_index >= 1 then
self.diff_str = "_normal"
else
self.diff_str = "_easy"
@@ -250,8 +256,8 @@ function ResultPlayer:draw_gauge()
local scale = 10.0 / 11.0
local base_fade = self.gauge_fade_in.attribute
local gl_int = math.floor(self.gauge_length)
local clear_pts = { 52, 60, 69 }
local clear_pt = clear_pts[math.min(self.difficulty, 2) + 1]
local clear_pts = { 52, 60, 69 } -- easy / normal+hard / oni norma cells (of 87)
local clear_pt = clear_pts[self.art_index + 1]
local bar_w = self.gauge_bar_width
if self.t_gauge_unfilled then
@@ -271,11 +277,15 @@ function ResultPlayer:draw_gauge()
local x2 = math.min(gl_int * bar_w, (clear_pt - 1) * bar_w) - bar_w
tex.draw_texture(self.t_gauge_bar, { scale = scale, x2 = x2, fade = base_fade, index = p_idx })
end
if gl_int >= clear_pt - 1 and self.t_gauge_bar_clear_transition then
-- The transition piece is the first gold cell (the rounded cap of the clear zone).
-- Light it only when the run is cleared, like the HUD gauge (Gauge::get_is_clear):
-- the norma falls mid-cell (oni 8000 = cell 69.6), so a cell-count test lit it for
-- a failed run at 7816..7999 soul.
if gl_int >= clear_pt - 1 and self.gauge_state >= 1 and self.t_gauge_bar_clear_transition then
tex.draw_texture(self.t_gauge_bar_clear_transition,
{ scale = scale, x = (clear_pt - 1) * bar_w, fade = base_fade, index = p_idx })
end
if gl_int > clear_pt then
if gl_int > clear_pt and self.gauge_state >= 1 then
local extra = (gl_int - clear_pt) * bar_w
if self.t_gauge_bar_clear_top then
tex.draw_texture(self.t_gauge_bar_clear_top,
@@ -296,8 +306,9 @@ function ResultPlayer:draw_gauge()
tex.draw_texture(self.t_gauge_footer, { scale = scale, fade = base_fade, index = p_idx })
end
local clear_idx = math.min(self.difficulty, 2) + p_idx * 3
if gl_int >= clear_pt - 1 then
local clear_idx = self.art_index + p_idx * 3
-- A failed run never lights the clear caption, even when the fill touches the zone.
if gl_int >= clear_pt - 1 and self.gauge_state >= 1 then
if self.t_gauge_clear then
tex.draw_texture(self.t_gauge_clear,
{ scale = scale, fade = base_fade, index = clear_idx })