forked from Yonokid/PyTaikoGreen
390 lines
18 KiB
Lua
390 lines
18 KiB
Lua
ResultPlayer = {}
|
|
ResultPlayer.__index = ResultPlayer
|
|
|
|
function ResultPlayer.new(player_num, is_2p, has_2p,
|
|
gauge_length, difficulty, selected_difficulty,
|
|
crown_type, score_diff, score_method,
|
|
mod_display, mod_inverse, mod_random, mod_speed)
|
|
local self = setmetatable({}, ResultPlayer)
|
|
tex.load_animations("result")
|
|
|
|
self.player_num = player_num
|
|
self.is_2p = is_2p
|
|
self.has_2p = has_2p
|
|
self.gauge_length = gauge_length
|
|
self.difficulty = difficulty
|
|
self.selected_difficulty = selected_difficulty
|
|
self.crown_type = crown_type
|
|
self.score_diff = score_diff
|
|
self.score_method = score_method
|
|
self.mod_display = mod_display
|
|
self.mod_inverse = mod_inverse
|
|
self.mod_random = mod_random
|
|
self.mod_speed = mod_speed
|
|
|
|
local clear_start = { 52, 60, 69 }
|
|
local diff_clamped = math.min(difficulty, 2)
|
|
if gauge_length == 87 then
|
|
self.gauge_state = 2
|
|
elseif gauge_length >= clear_start[diff_clamped + 1] - 1 then
|
|
self.gauge_state = 1
|
|
else
|
|
self.gauge_state = 0
|
|
end
|
|
|
|
if difficulty >= 2 then
|
|
self.diff_str = "_hard"
|
|
elseif difficulty >= 1 then
|
|
self.diff_str = "_normal"
|
|
else
|
|
self.diff_str = "_easy"
|
|
end
|
|
|
|
local p = tostring(player_num) .. "p"
|
|
self.player_str = p
|
|
|
|
self.score = ""
|
|
self.good = ""
|
|
self.ok = ""
|
|
self.bad = ""
|
|
self.max_combo = ""
|
|
self.total_drumroll = ""
|
|
self.fade_in_finished_flag = false
|
|
|
|
self.gauge_started = false
|
|
self.score_delay = nil
|
|
self.fade_in_started = false
|
|
self.rainbow_start_ms = -1.0
|
|
self.rainbow_frac = 0.0
|
|
|
|
-- Sub-objects
|
|
self.bottom_chars = BottomCharacters.new()
|
|
self.crown_obj = nil
|
|
self.crown_msg_obj = nil
|
|
self.high_score_obj = nil
|
|
|
|
-- Animations owned by ResultPlayer
|
|
self.fade_in_bottom = tex.get_animation(1, "result")
|
|
self.gauge_fade_in = tex.get_animation(17, "result")
|
|
self.tamashii_fire = tex.get_animation(20, "result")
|
|
|
|
self.t_grad_clear = tex.load_texture("result/background/gradient_clear")
|
|
self.t_grad_fail = tex.load_texture("result/background/gradient_fail")
|
|
|
|
self.t_overlay = tex.load_texture("result/score/overlay")
|
|
self.t_difficulty = tex.load_texture("result/score/difficulty")
|
|
self.t_judge_good = tex.load_texture("result/score/judge_good")
|
|
self.t_judge_ok = tex.load_texture("result/score/judge_ok")
|
|
self.t_judge_bad = tex.load_texture("result/score/judge_bad")
|
|
self.t_judge_num = tex.load_texture("result/score/judge_num")
|
|
self.t_max_combo = tex.load_texture("result/score/max_combo")
|
|
self.t_drumroll = tex.load_texture("result/score/drumroll")
|
|
self.t_score_lbl = tex.load_texture("result/score/score")
|
|
self.t_score_shinuchi_lbl = tex.load_texture("result/score/score_shinuchi")
|
|
self.t_score_num = tex.load_texture("result/score/score_num")
|
|
|
|
self.t_mod_doron = tex.load_texture("result/score/mod_doron")
|
|
self.t_mod_abekobe = tex.load_texture("result/score/mod_abekobe")
|
|
self.t_mod_kimagure = tex.load_texture("result/score/mod_kimagure")
|
|
self.t_mod_detarame = tex.load_texture("result/score/mod_detarame")
|
|
self.t_mod_yonbai = tex.load_texture("result/score/mod_yonbai")
|
|
self.t_mod_sanbai = tex.load_texture("result/score/mod_sanbai")
|
|
self.t_mod_baisaku = tex.load_texture("result/score/mod_baisaku")
|
|
|
|
self.t_gauge_unfilled = tex.load_texture("result/gauge/" .. p .. "_unfilled" .. self.diff_str)
|
|
self.t_gauge_bar = tex.load_texture("result/gauge/" .. p .. "_bar")
|
|
self.t_gauge_rainbow = tex.load_texture("result/gauge/rainbow" .. self.diff_str)
|
|
self.t_gauge_overlay = tex.load_texture("result/gauge/overlay" .. self.diff_str)
|
|
self.t_gauge_footer = tex.load_texture("result/gauge/footer")
|
|
self.t_gauge_clear = tex.load_texture("result/gauge/clear")
|
|
self.t_gauge_clear_dark = tex.load_texture("result/gauge/clear_dark")
|
|
self.t_gauge_bar_clear_transition = tex.load_texture("result/gauge/bar_clear_transition")
|
|
self.t_gauge_bar_clear_top = tex.load_texture("result/gauge/bar_clear_top")
|
|
self.t_gauge_bar_clear_bottom = tex.load_texture("result/gauge/bar_clear_bottom")
|
|
self.t_gauge_tamashii = tex.load_texture("result/gauge/tamashii")
|
|
self.t_gauge_tamashii_dark = tex.load_texture("result/gauge/tamashii_dark")
|
|
self.t_gauge_tamashii_fire = tex.load_texture("result/gauge/tamashii_fire")
|
|
self.t_gauge_tamashii_overlay = tex.load_texture("result/gauge/tamashii_overlay")
|
|
|
|
local bar_info = tex.get_texture_info("gauge", p .. "_bar")
|
|
self.gauge_bar_width = bar_info and bar_info.width or 0
|
|
|
|
local si = tex.get_skin_config("score_info_counter_margin")
|
|
self.sc_score_info_margin = si and si.x or 0
|
|
local rs = tex.get_skin_config("result_score_margin")
|
|
self.sc_result_score_margin = rs and rs.x or 0
|
|
local r2 = tex.get_skin_config("result_2p_offset")
|
|
self.sc_result_2p_offset = r2 and r2.y or 0
|
|
|
|
return self
|
|
end
|
|
|
|
function ResultPlayer:update(current_ms, fade_in_finished,
|
|
score, good, ok, bad, max_combo, total_drumroll)
|
|
self.fade_in_finished_flag = fade_in_finished
|
|
self.score = score
|
|
self.good = good
|
|
self.ok = ok
|
|
self.bad = bad
|
|
self.max_combo = max_combo
|
|
self.total_drumroll = total_drumroll
|
|
|
|
if fade_in_finished and not self.gauge_started then
|
|
self.gauge_started = true
|
|
self.gauge_fade_in:start()
|
|
self.tamashii_fire:start()
|
|
self.bottom_chars:start()
|
|
end
|
|
|
|
if self.gauge_started then
|
|
if self.gauge_state == 2 then
|
|
if self.rainbow_start_ms < 0 then self.rainbow_start_ms = current_ms end
|
|
self.rainbow_frac = math.fmod((current_ms - self.rainbow_start_ms) / 75.0, 8.0)
|
|
end
|
|
self.tamashii_fire:update(current_ms)
|
|
self.gauge_fade_in:update(current_ms)
|
|
if self.gauge_fade_in.is_finished and self.score_delay == nil then
|
|
self.score_delay = current_ms + 1883
|
|
end
|
|
end
|
|
|
|
if self.score_delay ~= nil and current_ms > self.score_delay and not self.fade_in_started then
|
|
self.fade_in_started = true
|
|
self.fade_in_bottom:start()
|
|
end
|
|
self.fade_in_bottom:update(current_ms)
|
|
|
|
if self.fade_in_started then
|
|
self.bottom_chars:update(current_ms, self.gauge_state)
|
|
end
|
|
|
|
if self.bottom_chars:is_finished() then
|
|
if self.gauge_state >= 1 and not self.crown_obj then
|
|
self.crown_obj = ResultCrown.new(self.crown_type, self.is_2p)
|
|
if self.crown_type == 1 or self.crown_type == 2 then
|
|
audio.play_sound("full_combo_voice_" .. tostring(self.player_num) .. "p", "voice")
|
|
end
|
|
elseif self.gauge_state == 0 and not self.crown_msg_obj then
|
|
local frame = (self.gauge_length < 87.0 / 2.0) and 0 or 1
|
|
self.crown_msg_obj = ResultCrownMessage.new(frame, self.is_2p)
|
|
if frame == 0 then
|
|
audio.play_sound("max_fail_voice_" .. tostring(self.player_num) .. "p", "voice")
|
|
else
|
|
audio.play_sound("fail_voice_" .. tostring(self.player_num) .. "p", "voice")
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.crown_obj then
|
|
self.crown_obj:update(current_ms)
|
|
if self.crown_obj:is_settled() and not self.crown_msg_obj then
|
|
local frame = (self.gauge_state == 2) and 3 or 2
|
|
self.crown_msg_obj = ResultCrownMessage.new(frame, self.is_2p)
|
|
if frame == 2 then
|
|
audio.play_sound("clear_voice_" .. tostring(self.player_num) .. "p", "voice")
|
|
else
|
|
audio.play_sound("max_clear_voice_" .. tostring(self.player_num) .. "p", "voice")
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.crown_msg_obj then
|
|
self.crown_msg_obj:update(current_ms)
|
|
end
|
|
|
|
if not self.high_score_obj and self.score_diff > 0 and self.good ~= "" then
|
|
self.high_score_obj = HighScoreIndicator.new(self.score_diff, self.is_2p)
|
|
end
|
|
if self.high_score_obj then
|
|
self.high_score_obj:update(current_ms)
|
|
end
|
|
end
|
|
|
|
function ResultPlayer:draw()
|
|
local p_idx = self.is_2p and 1 or 0
|
|
|
|
if self.fade_in_started then
|
|
local fade_val = math.min(0.4, self.fade_in_bottom.attribute)
|
|
if self.is_2p then
|
|
if self.gauge_state == 0 then
|
|
if self.t_grad_fail then tex.draw_texture(self.t_grad_fail, { fade = fade_val }) end
|
|
else
|
|
if self.t_grad_clear then tex.draw_texture(self.t_grad_clear, { fade = fade_val }) end
|
|
end
|
|
else
|
|
local y = (self.sc_result_2p_offset ~= 0) and (self.has_2p and 1.0 or 0.0) or 0.0
|
|
if self.gauge_state == 0 then
|
|
if self.t_grad_fail then tex.draw_texture(self.t_grad_fail, { y = y, fade = fade_val }) end
|
|
else
|
|
if self.t_grad_clear then tex.draw_texture(self.t_grad_clear, { y = y, fade = fade_val }) end
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.t_overlay then tex.draw_texture(self.t_overlay, { color = { 255, 255, 255, 192 }, index = p_idx }) end
|
|
if self.t_difficulty then tex.draw_texture(self.t_difficulty, { frame = self.selected_difficulty, index = p_idx }) end
|
|
|
|
if not self.has_2p then self.bottom_chars:draw() end
|
|
|
|
if self.t_judge_good then tex.draw_texture(self.t_judge_good, { index = p_idx }) end
|
|
if self.t_judge_ok then tex.draw_texture(self.t_judge_ok, { index = p_idx }) end
|
|
if self.t_judge_bad then tex.draw_texture(self.t_judge_bad, { index = p_idx }) end
|
|
if self.t_max_combo then tex.draw_texture(self.t_max_combo, { index = p_idx }) end
|
|
if self.t_drumroll then tex.draw_texture(self.t_drumroll, { index = p_idx }) end
|
|
|
|
self:draw_score_info()
|
|
self:draw_total_score()
|
|
|
|
if self.crown_obj then self.crown_obj:draw() end
|
|
if self.crown_msg_obj then self.crown_msg_obj:draw() end
|
|
|
|
self:draw_modifiers()
|
|
|
|
if self.high_score_obj then self.high_score_obj:draw() end
|
|
end
|
|
|
|
function ResultPlayer:draw_gauge()
|
|
if not self.gauge_started then return end
|
|
|
|
local p_idx = self.is_2p and 1 or 0
|
|
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 bar_w = self.gauge_bar_width
|
|
|
|
if self.t_gauge_unfilled then
|
|
tex.draw_texture(self.t_gauge_unfilled, { scale = scale, fade = base_fade, index = p_idx })
|
|
end
|
|
|
|
if self.gauge_state == 2 then
|
|
local fa = math.floor(self.rainbow_frac) % 8
|
|
local fb = (fa + 1) % 8
|
|
local t = self.rainbow_frac - math.floor(self.rainbow_frac)
|
|
if self.t_gauge_rainbow then
|
|
tex.draw_texture(self.t_gauge_rainbow, { frame = fa, scale = scale, fade = base_fade, index = p_idx })
|
|
tex.draw_texture(self.t_gauge_rainbow, { frame = fb, scale = scale, fade = base_fade * t, index = p_idx })
|
|
end
|
|
else
|
|
if self.t_gauge_bar then
|
|
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
|
|
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
|
|
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,
|
|
{ scale = scale, x = clear_pt * bar_w, x2 = extra, fade = base_fade, index = p_idx })
|
|
end
|
|
if self.t_gauge_bar_clear_bottom then
|
|
tex.draw_texture(self.t_gauge_bar_clear_bottom,
|
|
{ scale = scale, x = clear_pt * bar_w, x2 = extra, fade = base_fade, index = p_idx })
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.t_gauge_overlay then
|
|
tex.draw_texture(self.t_gauge_overlay,
|
|
{ scale = scale, fade = math.min(0.15, base_fade), index = p_idx })
|
|
end
|
|
if self.t_gauge_footer then
|
|
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
|
|
if self.t_gauge_clear then
|
|
tex.draw_texture(self.t_gauge_clear,
|
|
{ scale = scale, fade = base_fade, index = clear_idx })
|
|
end
|
|
if self.gauge_state == 2 and self.t_gauge_tamashii_fire then
|
|
local fire_f = math.floor(self.tamashii_fire.attribute)
|
|
tex.draw_texture(self.t_gauge_tamashii_fire,
|
|
{ frame = fire_f, scale = 0.75 * scale, center = true, fade = base_fade, index = p_idx })
|
|
end
|
|
if self.t_gauge_tamashii then
|
|
tex.draw_texture(self.t_gauge_tamashii, { scale = scale, fade = base_fade, index = p_idx })
|
|
end
|
|
if self.gauge_state == 2 and self.t_gauge_tamashii_overlay then
|
|
local f = math.floor(self.tamashii_fire.attribute)
|
|
if f == 0 or f == 1 or f == 4 or f == 5 then
|
|
tex.draw_texture(self.t_gauge_tamashii_overlay,
|
|
{ scale = scale, fade = math.min(0.5, base_fade), index = p_idx })
|
|
end
|
|
end
|
|
else
|
|
if self.t_gauge_clear_dark then
|
|
tex.draw_texture(self.t_gauge_clear_dark,
|
|
{ scale = scale, fade = base_fade, index = clear_idx })
|
|
end
|
|
if self.t_gauge_tamashii_dark then
|
|
tex.draw_texture(self.t_gauge_tamashii_dark,
|
|
{ scale = scale, fade = base_fade, index = p_idx })
|
|
end
|
|
end
|
|
end
|
|
|
|
function ResultPlayer:draw_score_info()
|
|
local scores = { self.good, self.ok, self.bad, self.max_combo, self.total_drumroll }
|
|
local p_idx = self.is_2p and 1 or 0
|
|
for j, s in ipairs(scores) do
|
|
if s ~= "" and self.t_judge_num then
|
|
local n = math.floor(tonumber(s) or 0)
|
|
local str = tostring(n)
|
|
for i = 1, #str do
|
|
local d = tonumber(string.sub(str, #str - i + 1, #str - i + 1)) or 0
|
|
tex.draw_texture(self.t_judge_num, {
|
|
frame = d,
|
|
x = -((i - 1) * self.sc_score_info_margin),
|
|
index = (j - 1) + p_idx * 5,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function ResultPlayer:draw_total_score()
|
|
if not self.fade_in_finished_flag then return end
|
|
local p_idx = self.is_2p and 1 or 0
|
|
if self.score_method then
|
|
if self.t_score_shinuchi_lbl then tex.draw_texture(self.t_score_shinuchi_lbl, { index = p_idx }) end
|
|
else
|
|
if self.t_score_lbl then tex.draw_texture(self.t_score_lbl, { index = p_idx }) end
|
|
end
|
|
if self.score ~= "" and self.t_score_num then
|
|
local n = math.floor(tonumber(self.score) or 0)
|
|
local str = tostring(n)
|
|
for i = 1, #str do
|
|
local d = tonumber(string.sub(str, #str - i + 1, #str - i + 1)) or 0
|
|
tex.draw_texture(self.t_score_num, {
|
|
frame = d,
|
|
x = -((i - 1) * self.sc_result_score_margin),
|
|
index = p_idx,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
|
|
function ResultPlayer:draw_modifiers()
|
|
local p_idx = self.is_2p and 1 or 0
|
|
if self.mod_display and self.t_mod_doron then tex.draw_texture(self.t_mod_doron, { index = p_idx }) end
|
|
if self.mod_inverse and self.t_mod_abekobe then tex.draw_texture(self.t_mod_abekobe, { index = p_idx }) end
|
|
if self.mod_random == 1 and self.t_mod_kimagure then
|
|
tex.draw_texture(self.t_mod_kimagure, { index = p_idx })
|
|
elseif self.mod_random == 2 and self.t_mod_detarame then
|
|
tex.draw_texture(self.t_mod_detarame, { index = p_idx })
|
|
end
|
|
if self.mod_speed >= 40 and self.t_mod_yonbai then
|
|
tex.draw_texture(self.t_mod_yonbai, { index = p_idx })
|
|
elseif self.mod_speed >= 30 and self.t_mod_sanbai then
|
|
tex.draw_texture(self.t_mod_sanbai, { index = p_idx })
|
|
elseif self.mod_speed > 10 and self.t_mod_baisaku then
|
|
tex.draw_texture(self.t_mod_baisaku, { index = p_idx })
|
|
end
|
|
end
|