dan select: 自己ベスト rows and all six clear stamps #65
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -208,5 +208,6 @@
|
||||
"difficulty_level": {
|
||||
"x": 538,
|
||||
"y": 287
|
||||
}
|
||||
},
|
||||
"exam_best_pill": {}
|
||||
}
|
||||
@@ -835,6 +835,18 @@
|
||||
"height": 88,
|
||||
"font_size": 42
|
||||
},
|
||||
"dan_exam_best_label": {
|
||||
"font_size": 17,
|
||||
"text": {
|
||||
"en": "My Best",
|
||||
"ja": "自己ベスト",
|
||||
"zh": "个人最佳",
|
||||
"ko": "개인 최고"
|
||||
}
|
||||
},
|
||||
"dan_exam_best_value": {
|
||||
"font_size": 26
|
||||
},
|
||||
"dan_back_label": {
|
||||
"x": 0,
|
||||
"y": 89,
|
||||
|
||||
@@ -201,6 +201,20 @@ local function course_view(box)
|
||||
})
|
||||
end
|
||||
|
||||
-- The clear stamps are the cabinet's six (box/clear_mark and yellow_box/clear_mark, frames
|
||||
-- 0..5 = red pass, full combo, all good, gold pass, full combo, all good), picked by the
|
||||
-- saved record's rank (2..7). An engine without box.record_rank only gives clear_mark
|
||||
-- (1 passed, 2 rank 7), which maps to frames 0 and 5.
|
||||
local function stamp_frame(box)
|
||||
local ok, rank = pcall(function() return box.record_rank end)
|
||||
if ok and type(rank) == "number" then
|
||||
return rank >= 2 and math.min(rank, 7) - 2 or nil
|
||||
end
|
||||
if box.clear_mark == 1 then return 0 end
|
||||
if box.clear_mark == 2 then return 5 end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- The course's clear stamp (yellow_box/clear_mark) sits over the dan plate and Don, as the
|
||||
-- cabinet's stamp_detail does (it is above don_1p). The parent draws it with the box, under
|
||||
-- both, so it is held back there and drawn with the title, which the engine draws after
|
||||
@@ -245,9 +259,8 @@ if parent_open then
|
||||
draw_level(box:song_level(i), i * (off.x or 0), i * (off.y or 0), f)
|
||||
end
|
||||
end
|
||||
if stamp and box.clear_mark > 0 then
|
||||
held_stamp = { id = stamp, frame = box.clear_mark - 1, fade = f }
|
||||
end
|
||||
local sf = stamp and stamp_frame(box)
|
||||
if sf then held_stamp = { id = stamp, frame = sf, fade = f } end
|
||||
end
|
||||
|
||||
function DanSelect:draw_title()
|
||||
@@ -334,8 +347,9 @@ function DanSelect:draw_dan_closed(box)
|
||||
local bx, fade, y = box:box_x(), box.fade.attribute, chip_drop(box)
|
||||
local id = tex.get_texture("dan_select/box/folder")
|
||||
if id then tex.draw_texture(id, { frame = box.dan_color, x = bx, y = y, fade = fade }) end
|
||||
local mark = box.clear_mark > 0 and tex.get_texture("dan_select/box/clear_mark")
|
||||
if mark then tex.draw_texture(mark, { frame = box.clear_mark - 1, x = bx, y = y, fade = fade }) end
|
||||
local sf = stamp_frame(box)
|
||||
local mark = sf and tex.get_texture("dan_select/box/clear_mark")
|
||||
if mark then tex.draw_texture(mark, { frame = sf, x = bx, y = y, fade = fade }) end
|
||||
draw_chip_name(box, bx, y, fade)
|
||||
end
|
||||
|
||||
@@ -349,10 +363,11 @@ end
|
||||
-- The cursor's glow goes over the chip, its emblem and name (they grey under it, as on the
|
||||
-- cabinet) but not over the clear stamp, which is drawn again on top of it.
|
||||
local function draw_chip_front(box)
|
||||
if box.is_back or box.clear_mark <= 0 then return end
|
||||
local mark = tex.get_texture("dan_select/box/clear_mark")
|
||||
if box.is_back then return end
|
||||
local sf = stamp_frame(box)
|
||||
local mark = sf and tex.get_texture("dan_select/box/clear_mark")
|
||||
if mark then
|
||||
tex.draw_texture(mark, { frame = box.clear_mark - 1, x = box:box_x(), y = chip_drop(box),
|
||||
tex.draw_texture(mark, { frame = sf, x = box:box_x(), y = chip_drop(box),
|
||||
fade = box.fade.attribute })
|
||||
end
|
||||
end
|
||||
@@ -393,3 +408,81 @@ function DanSelect:draw_cursor(pos, now_ms, moved_ms)
|
||||
if selected then draw_chip_front(selected) end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Each exam's 自己ベスト row, as on the cabinet: a white pill under the value with the label
|
||||
-- on its left and the saved best on its right (box:exam_best / exam_song_best; an engine
|
||||
-- without them, or a course never played, shows the label alone). The gauge box's pill is
|
||||
-- part of exam_gauge_box; the right-hand boxes get yellow_box/exam_best_pill, one per song
|
||||
-- segment. The boxes are walked as the parent's draw_exam_grid walks them.
|
||||
local BEST_GAUGE = { x = 10, y = 116, w = 301 } -- the pill in exam_gauge_box, from the box
|
||||
local BEST_RIGHT = { x = 11, y = 86, w = 317 } -- exam_best_pill, from the box (+ seg dx)
|
||||
local BEST_H = 31
|
||||
local BEST_LABEL_X, BEST_VALUE_R = 8, 14 -- label from the pill's left, value from its right
|
||||
|
||||
local best_texts = {}
|
||||
local function best_text(key, str)
|
||||
local cfg = tex.get_skin_config(key)
|
||||
if not cfg or str == nil or str == "" then return nil end
|
||||
local k = key .. "\0" .. str
|
||||
if best_texts[k] == nil then
|
||||
best_texts[k] = raw_create(str, cfg.font_size, { 20, 20, 20, 255 }, { 0, 0, 0, 255 },
|
||||
false, 0, 1) or false
|
||||
end
|
||||
return best_texts[k] or nil
|
||||
end
|
||||
|
||||
local function call(box, name, ...)
|
||||
local ok, fn = pcall(function() return box[name] end)
|
||||
if not ok or type(fn) ~= "function" then return nil end
|
||||
local ok2, v = pcall(fn, box, ...)
|
||||
return ok2 and v or nil
|
||||
end
|
||||
|
||||
local function draw_best_row(box, value, etype, px, py, pw, f)
|
||||
local label = best_text("dan_exam_best_label", tex.skin_text("dan_exam_best_label"))
|
||||
if label then
|
||||
label:draw({ x = px + BEST_LABEL_X, y = py + (BEST_H - label.height) / 2, fade = f })
|
||||
end
|
||||
if value then
|
||||
local str = tostring(value) .. (etype == "gauge" and " %" or "")
|
||||
local t = best_text("dan_exam_best_value", str)
|
||||
if t then
|
||||
t:draw({ x = px + pw - BEST_VALUE_R - t.width, y = py + (BEST_H - t.height) / 2, fade = f })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local parent_grid = DanSelect.draw_exam_grid
|
||||
if parent_grid then
|
||||
function DanSelect:draw_exam_grid(box, f)
|
||||
parent_grid(self, box, f)
|
||||
local pill = tex.get_texture("dan_select/yellow_box/exam_best_pill")
|
||||
local gb = tex.get_skin_config("dan_exam_gauge_box") or { x = 436, y = 610 }
|
||||
local sb = tex.get_skin_config("dan_exam_score_box") or { x = 769, y = 610, height = 132 }
|
||||
local sg = tex.get_skin_config("dan_exam_seg") or { width = 327 }
|
||||
local pitch = (sb.height and sb.height > 0) and sb.height or 132
|
||||
local seg_dx = (sg.width and sg.width > 0) and sg.width or 327
|
||||
local right_row, gauge_used = 0, false
|
||||
for i = 0, box:exam_count() - 1 do
|
||||
local etype = box:exam_type(i)
|
||||
local left = (etype == "gauge" and not gauge_used)
|
||||
if left then gauge_used = true end
|
||||
if left then
|
||||
draw_best_row(box, call(box, "exam_best", i), etype,
|
||||
gb.x + BEST_GAUGE.x, gb.y + BEST_GAUGE.y, BEST_GAUGE.w, f)
|
||||
elseif right_row < 3 then
|
||||
local by = sb.y + pitch * right_row
|
||||
local gothrough = box:exam_gothrough(i)
|
||||
local segs = gothrough and 1 or math.min(box:song_count(), 3)
|
||||
for k = 0, segs - 1 do
|
||||
local px = sb.x + BEST_RIGHT.x + seg_dx * k
|
||||
local py = by + BEST_RIGHT.y
|
||||
if pill then tex.draw_texture(pill, { x = px, y = py, fade = f }) end
|
||||
local v = gothrough and call(box, "exam_best", i) or call(box, "exam_song_best", i, k)
|
||||
draw_best_row(box, v, etype, px, py, BEST_RIGHT.w, f)
|
||||
end
|
||||
right_row = right_row + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user