diff --git a/Graphics/dan_select/box/clear_mark/1.png b/Graphics/dan_select/box/clear_mark/1.png index 9748fbf..3939747 100644 --- a/Graphics/dan_select/box/clear_mark/1.png +++ b/Graphics/dan_select/box/clear_mark/1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ce42b15149894471e7644a836613106a9302004211a084b6144ef66d11be07f -size 9298 +oid sha256:0f06e751125fe6c733d59dc16b7c71aba2a0463c4436d8618782367faed4fd49 +size 9222 diff --git a/Graphics/dan_select/box/clear_mark/2.png b/Graphics/dan_select/box/clear_mark/2.png new file mode 100644 index 0000000..ce63d30 --- /dev/null +++ b/Graphics/dan_select/box/clear_mark/2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8add25664596650e50acf0a5786a1ca44e3cca3a7ff1a0815f8c4b13d99f9b71 +size 9160 diff --git a/Graphics/dan_select/box/clear_mark/3.png b/Graphics/dan_select/box/clear_mark/3.png new file mode 100644 index 0000000..80b73a3 --- /dev/null +++ b/Graphics/dan_select/box/clear_mark/3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd126fb0697f9d54e73694c69f3ab54998b8176ffdd3c5dbe10e8b6029edb0d9 +size 9277 diff --git a/Graphics/dan_select/box/clear_mark/4.png b/Graphics/dan_select/box/clear_mark/4.png new file mode 100644 index 0000000..e641bf7 --- /dev/null +++ b/Graphics/dan_select/box/clear_mark/4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55b4cca4ce4874e95bc1265b53e0affcf477ccf4b63bd8f925db91c55597b171 +size 9459 diff --git a/Graphics/dan_select/box/clear_mark/5.png b/Graphics/dan_select/box/clear_mark/5.png new file mode 100644 index 0000000..9748fbf --- /dev/null +++ b/Graphics/dan_select/box/clear_mark/5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ce42b15149894471e7644a836613106a9302004211a084b6144ef66d11be07f +size 9298 diff --git a/Graphics/dan_select/yellow_box/clear_mark/1.png b/Graphics/dan_select/yellow_box/clear_mark/1.png index 2111988..5cc57a4 100644 --- a/Graphics/dan_select/yellow_box/clear_mark/1.png +++ b/Graphics/dan_select/yellow_box/clear_mark/1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15c702977afc97112aff1d435e87040ea3262ecd66fcfb9ca4dfa769311b23ff -size 59385 +oid sha256:d4b24aa80e9e804737a7dbb45e9ea1bf6e1c0e2c893fb892102cde28c721c3bb +size 61738 diff --git a/Graphics/dan_select/yellow_box/clear_mark/2.png b/Graphics/dan_select/yellow_box/clear_mark/2.png new file mode 100644 index 0000000..8d8bbac --- /dev/null +++ b/Graphics/dan_select/yellow_box/clear_mark/2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d0be9e425230fc2542f208b8494f0d007c4c23bd3a491a279d2d6ce2b7d0f62 +size 60873 diff --git a/Graphics/dan_select/yellow_box/clear_mark/3.png b/Graphics/dan_select/yellow_box/clear_mark/3.png new file mode 100644 index 0000000..a02fe1f --- /dev/null +++ b/Graphics/dan_select/yellow_box/clear_mark/3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1cdbdb980dd549cdb8a806b7d1adc1e14193772e8cd7a62785714879a83613b +size 55621 diff --git a/Graphics/dan_select/yellow_box/clear_mark/4.png b/Graphics/dan_select/yellow_box/clear_mark/4.png new file mode 100644 index 0000000..b0bbc86 --- /dev/null +++ b/Graphics/dan_select/yellow_box/clear_mark/4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0505531898b9f3e9d174464e0306517f3804304c3a9eda4a7d41897dc65b73be +size 60514 diff --git a/Graphics/dan_select/yellow_box/clear_mark/5.png b/Graphics/dan_select/yellow_box/clear_mark/5.png new file mode 100644 index 0000000..2111988 --- /dev/null +++ b/Graphics/dan_select/yellow_box/clear_mark/5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15c702977afc97112aff1d435e87040ea3262ecd66fcfb9ca4dfa769311b23ff +size 59385 diff --git a/Graphics/dan_select/yellow_box/exam_best_pill.png b/Graphics/dan_select/yellow_box/exam_best_pill.png new file mode 100644 index 0000000..093e410 --- /dev/null +++ b/Graphics/dan_select/yellow_box/exam_best_pill.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d171b073242c4448e0664533aa54e3f1c337d5e7fd32e7a1e3fa55865382c8f +size 774 diff --git a/Graphics/dan_select/yellow_box/texture.json b/Graphics/dan_select/yellow_box/texture.json index a2604f8..3f1f047 100644 --- a/Graphics/dan_select/yellow_box/texture.json +++ b/Graphics/dan_select/yellow_box/texture.json @@ -208,5 +208,6 @@ "difficulty_level": { "x": 538, "y": 287 - } + }, + "exam_best_pill": {} } diff --git a/Graphics/skin_config.json b/Graphics/skin_config.json index f1ca5c4..984e2fe 100644 --- a/Graphics/skin_config.json +++ b/Graphics/skin_config.json @@ -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, diff --git a/Scripts/dan_select/dan_select.lua b/Scripts/dan_select/dan_select.lua index 4ece6f8..4d2d01a 100644 --- a/Scripts/dan_select/dan_select.lua +++ b/Scripts/dan_select/dan_select.lua @@ -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