Compare commits

...
Author SHA1 Message Date
TaikoZhongandClaude Opus 5.5 13eaf11c48 Big notes: the cabinet's flight and sparkle trail
Scripts/game/note_arc.lua overrides the parent's note arc: notes fly the cabinet's path (a cubic Bezier fitted to it, P1 and P2 each their own) in 30 frames, and big notes leave the cabinet's 9 sparks (hit_effect/firework, additive, centred on the note). The balloon keeps the parent's flight.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:16:40 +08:00
Yonokid 139184e39d move note arc to lua 2026-10-14 14:37:57 -04:00
Yonokid 484c474387 remove some skin options 2026-10-14 12:51:04 -04:00
Yonokid 98d2b0adef add secondary font 2026-10-14 10:45:50 -04:00
Yonokid 8c705458dd Update checksums.sha256 2026-10-14 10:27:37 -04:00
TaikoZhongandClaude Opus 5.5 b1c1f3d10a Update checksums.sha256 for #68
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:53:56 +08:00
GanYiZhong e11a09b1be Merge pull request 'Timer digits in the cabinet grey' (#68) from GanYiZhong/YataiDONNijiiro:fix/timer-digit-grey into main 2026-10-14 15:53:39 +02:00
TaikoZhongandClaude Opus 5.5 acb945062a Timer digits in the cabinet's grey (#505050) instead of black
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:52:41 +08:00
TaikoZhongandClaude Opus 5.5 aecee76477 Update checksums.sha256 for #67
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:50:09 +08:00
GanYiZhong 4a12169a59 Merge pull request 'dan select: no 自己ベスト row when there is no best' (#67) from GanYiZhong/YataiDONNijiiro:fix/dan-select-best-empty into main 2026-10-14 15:49:50 +02:00
TaikoZhongandClaude Opus 5.5 e8798eff85 dan select: no 自己ベスト row at all when there is no best
The gauge box's best pill was part of exam_gauge_box, so it showed even on a course never played, with the label in it. It is now its own texture (exam_gauge_best_pill), and with no best neither pill nor label is drawn, as on the cabinet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:48:21 +08:00
TaikoZhongandClaude Opus 5.5 2a82b000a2 Update checksums.sha256 for #64, #65, #66
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:38:51 +08:00
GanYiZhong 8397c6b98e Merge pull request 'dan game: soul gauge drawn as on the cabinet' (#66) from GanYiZhong/YataiDONNijiiro:fix/dan-game-gauge into main 2026-10-14 15:38:17 +02:00
GanYiZhong b5f9ee628e Merge pull request 'dan select: 自己ベスト rows and all six clear stamps' (#65) from GanYiZhong/YataiDONNijiiro:feat/dan-select-best-stamps into main 2026-10-14 15:38:02 +02:00
GanYiZhong 6025f7c02f Merge pull request 'dan select: course panel closer to the cabinet' (#64) from GanYiZhong/YataiDONNijiiro:fix/dan-select-exam-panel into main 2026-10-14 15:37:50 +02:00
TaikoZhongandClaude Opus 5.5 97fa82924f Dan gauge plate: uncropped art, value at the cabinet's size
The plate art had its top and left rows cut off, flattening the top of the
魂ゲージ pill. It is now the cabinet's whole plate (with its 9 px margin),
drawn 9 px up and left so the layout constants stay put. The threshold
caption is the cabinet's size 36, its centre moved up to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:12:38 +08:00
TaikoZhongandClaude Opus 5.5 48660a8b87 dan game: the soul gauge over the lane's top edge, as on the cabinet
The engine draws the lane after the gauge, and the lane's black top edge (y 276) hid the
cells' last six rows; the cabinet's gauge sits over it (cells down to y 281). The gauge
leaves a redraw (g_dan_gauge_redraw) that the dan background's draw_fore repeats, clipped
to that strip (y 276-288).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:01:01 +08:00
TaikoZhongandClaude Opus 5.5 287f8ffd67 dan game: the soul gauge drawn as the cabinet's tamashii_gauge
Gauge:draw_dan is this skin's own now, built from the cabinet's tamashii_gauge pieces:
- the gold track (border) with the red track (gauge_dan/track_red, gauge_bg) only up to the
  threshold, so the cells past it are dark gold;
- the lit cells as the cabinet's lamp stretched 21 px per cell (gauge_dan/1p_lamp, 2p_lamp),
  all yellow (lamp_clear) once the gauge reaches the threshold, with the matching glow on a
  newly lit cell (bar_fade_clear);
- the cell separators at the cabinet's 103/255 (they were drawn at 0.15, plus a second copy
  from the dan background);
- 魂 grey, white once cleared, in flames at full.
The threshold comes from the dan exam: background/dan_info hands it over as
g_dan_gauge_border. Without it, or on a screen without these pieces, the parent draws.
This replaces the gold-zone repaint in dan_info, and 1p_bar / 2p_bar / 1p_bar_fade go back
to what they were.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:22:30 +08:00
TaikoZhongandClaude Opus 5.5 e8ce3b3a7d dan game: the soul gauge's gold zone past the threshold
The cabinet shows the cells past the threshold in gold: dark gold while unfilled, its
lamp_clear (white band over yellow) once filled. The gauge script does not know the
threshold, so dan_info, which does, paints them over the engine's cells in the gauge layer
(game/dan_info/gauge_gold_cell, gauge_gold_unfilled).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:33:42 +08:00
TaikoZhongandClaude Opus 5.5 a9bce590c5 dan game: soul gauge threshold marker, cell art and threshold caption
- The white threshold marker (game/dan_info/gauge_border_cell) is drawn on the threshold
  cell, as the cabinet's border_N, from Background:draw_fore so it sits over the lane frame.
- The gauge cells (gauge_dan/1p_bar, 2p_bar, 1p_bar_fade) get the cabinet lamp's light
  band along the top.
- The 「100 %以上」 caption on the threshold plate sits lower and one size smaller, as on
  the cabinet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:23:04 +08:00
TaikoZhongandClaude Opus 5.5 601fed93d6 dan select: 自己ベスト rows and all six clear stamps
- Each exam shows its 自己ベスト row as on the cabinet: a white pill (part of
  exam_gauge_box, and yellow_box/exam_best_pill for the right-hand boxes, one per song
  segment) with the label on the left and the recorded best on the right. Needs the
  engine's box:exam_best / exam_song_best; without them, or before a course is played,
  the label is shown alone.
- box/clear_mark and yellow_box/clear_mark have the cabinet's six stamps (red/gold x
  pass/full combo/all good), picked by the record's rank (box.record_rank); an engine
  without it falls back to clear_mark (frames 0 and 5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:58:16 +08:00
TaikoZhongandClaude Opus 5.5 c14075b8fa dan select: course panel closer to the cabinet
- Course rows show the song title alone (no subtitle). In CJK languages the title is set
  in runs (ASCII / everything else) so kanji and kana keep their width; it needs the
  engine's OutlinedText.text and falls back to the engine's title without it.
- Exam values: in CJK languages the digits are narrowed beside full-width 以上/未満, with
  a little room between them; smaller size and a thicker edge, centred on the row's
  coin and right-aligned with the cabinet's.
- Exam labels (yellow_box/exam_*.png) are smaller and edged in dark ochre, centred in
  their pills.
- The 合格条件 tab, frame and exam boxes sit 5 px higher, the tab joining the frame.
- The back chip's label set across (non-CJK languages) takes a smaller size instead of
  being squeezed to the chip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:59:34 +08:00
TaikoZhongandClaude Opus 5.5 2e00d1a0f5 Keep checksums.sha256 in its previous line order
Same entries as the last commit; only the order is restored, with the new
paths appended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 15:15:14 +08:00
TaikoZhongandClaude Opus 5.5 ec5731e3bd Update checksums.sha256 for #63
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 15:14:23 +08:00
GanYiZhong c78383fdc1 Merge pull request 'dan select: back chip, chip names, cursor and course rows' (#63) from GanYiZhong/YataiDONNijiiro:feat/dan-select-back-chip into main 2026-10-14 09:13:47 +02:00
TaikoZhongandClaude Opus 5.5 a029b25b22 dan select: back chip, chip names, cursor and course rows (#53)
- Back entry: a chip in the top strip (back/folder, a light blue in the parent's back
  colour) with its label from skin_config dan_back_label, so it follows the language
  (ja 戻る, en Back, zh 返回, ko 뒤로).
- Chip names are black with no outline: dan_chip_name_black moves into screen.options,
  where the engine reads it.
- The selected chip drops below the strip and eases back; the cursor glow covers the
  chip and its name but not the clear stamp.
- Course rows: the 1st/2nd/3rd labels are centred on their row, and the level is one
  "star + number" image per level (yellow_box/difficulty_level, 1..10 and 10+) in place of
  the separate star and digits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 15:12:37 +08:00
TaikoZhongandClaude Opus 5.5 6b5ae8b5b5 Update checksums.sha256 for #62
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:56:25 +08:00
GanYiZhong afe0bab807 Merge pull request 'dan select: cabinet clear stamps, no parent ura badge' (#62) from GanYiZhong/YataiDONNijiiro:fix/dan-select-marks into main 2026-10-14 06:56:00 +02:00
70 changed files with 1008 additions and 306 deletions

No files matched your search

Binary file not shown.
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
{
"folder": {
"x": -44,
"y": 16
}
}
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.
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.
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.
+11 -5
View File
@@ -83,12 +83,12 @@
"y": 186
},
"exam_header": {
"x": 420,
"y": 568
"x": 421,
"y": 563
},
"exam_frame": {
"x": 418,
"y": 601
"y": 596
},
"exam_box_top_left": {
"x": 420,
@@ -190,7 +190,7 @@
},
"song_label": {
"x": 430,
"y": 230
"y": 246
},
"exam_seg_label": {
"x": 0,
@@ -204,5 +204,11 @@
"x": 100,
"y": 505
},
"difficulty_ura": {}
"difficulty_ura": {},
"difficulty_level": {
"x": 538,
"y": 287
},
"exam_best_pill": {},
"exam_gauge_best_pill": {}
}
Binary file not shown.
-4
View File
@@ -132,9 +132,5 @@
"rainbow": {
"x": 449,
"y": -407
},
"rainbow_mask": {
"x": 449,
"y": -407
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+20
View File
@@ -100,5 +100,25 @@
"tamashii_fire": {
"x": 1698,
"y": 34
},
"track_red": {
"x": 738,
"y": 242
},
"1p_lamp": {
"x": 738,
"y": 242
},
"2p_lamp": {
"x": 738,
"y": 242
},
"lamp_clear": {
"x": 738,
"y": 242
},
"bar_fade_clear": {
"x": 733,
"y": 241
}
}
Binary file not shown.
Binary file not shown.
+82
View File
@@ -146,5 +146,87 @@
336
]
]
},
"firework": {
"crop": [
[
0,
0,
256,
256
],
[
256,
0,
256,
256
],
[
512,
0,
256,
256
],
[
768,
0,
256,
256
],
[
0,
256,
256,
256
],
[
256,
256,
256,
256
],
[
512,
256,
256,
256
],
[
768,
256,
256,
256
],
[
0,
512,
256,
256
],
[
256,
512,
256,
256
],
[
512,
512,
256,
256
],
[
768,
512,
256,
256
],
[
0,
768,
256,
256
]
]
}
}
Binary file not shown.
+51 -149
View File
@@ -45,6 +45,7 @@
"combo_color_tiers": true,
"gauge_cell_fade_in": true,
"dan_exam_grid": true,
"dan_chip_name_black": true,
"disable_chara_3d": false
}
},
@@ -60,10 +61,7 @@
"y": -130,
"width": 1200,
"height": 93
},
"clear_animation_x_spacing": {
"x": 100
},
},␍
"song_info": {
"x": 1872,
"y": 68,
@@ -81,10 +79,7 @@
},
"drumroll_counter_margin": {
"x": 80
},
"kusudama_counter_margin": {
"x": 240
},
},␍
"combo_announce_add_x": {
"x": 610
},
@@ -108,10 +103,7 @@
},
"nameplate_name_offset": {
"y": 1
},
"nameplate_title_offset": {
"y": 3
},
},␍
"song_box_name": {
"x": 0,
"y": 0,
@@ -589,14 +581,7 @@
},
"song_select_row_curve": {
"x": 40
},
"folder_box_name": {
"font_size": 54
},
"combo_tier": {
"x": 30,
"y": 50
},
},␍␍
"song_num_game": {
"x": 1674,
"y": 122,
@@ -607,10 +592,7 @@
},
"gauge_cells": {
"x": 50
},
"gauge_clear_mark_offset": {
"x": 1
},
},␍
"mod_badge_grid": {
"x": 170,
"y": 77,
@@ -627,7 +609,8 @@
"x": 632,
"y": 262,
"height": 60,
"font_size": 36
"font_size": 36,
"outline": 2.6
},
"dan_subtitle": {
"x": 632,
@@ -671,10 +654,7 @@
},
"dan_total_notes_margin": {
"x": 44
},
"dan_score_box_margin": {
"x": 46
},
},␍
"dan_result_info_height": {
"y": 276
},
@@ -686,10 +666,7 @@
},
"dan_result_diff_num_margin": {
"x": 16
},
"dan_result_diff_num_lead": {
"x": 9
},
},␍
"dan_result_hori_name": {
"x": 204,
"y": 317,
@@ -782,10 +759,7 @@
"balloon_counter_2p_offset": {
"x": 0,
"y": 180
},
"combo_min": {
"x": 10
},
},␍
"gogo_fire_fade": {
"x": 0.699
},
@@ -820,10 +794,7 @@
},
"loading_fade_ms": {
"x": 417
},
"copyright_page_ms": {
"x": 2000
},
},␍
"screen_fade_ms": {
"x": 500
},
@@ -833,6 +804,28 @@
"height": 88,
"font_size": 42
},
"dan_exam_best_label": {
"font_size": 17,
"text": {
"en": "My Best",
"ja": "自己ベスト",
"zh": "个人最佳",
"ko": "개인 최고"
}
},␍
"dan_back_label": {
"x": 0,
"y": 89,
"width": 52,
"height": 88,
"font_size": 42,
"text": {
"en": "Back",
"ja": "戻る",
"zh": "返回",
"ko": "뒤로"
}
},
"dan_result_chara": {
"x": 187,
"y": 934
@@ -858,50 +851,7 @@
},
"note_arc_curve_height": {
"height": 608
},
"note_arc_duration": {
"x": 30
},
"note_arc_balloon_pivot": {
"x": 1269.5,
"y": 416.94
},
"note_arc_balloon_angles": {
"x": -151.47,
"y": -38.37,
"width": -37.06
},
"note_arc_balloon_art": {
"x": 820,
"y": 824,
"width": 636,
"height": 804
},
"note_arc_balloon_frames": {
"x": 30,
"y": 39,
"width": 60,
"height": 65
},
"dan_exam_bar_all": {
"width": 972
},
"dan_exam_border_margin": {
"x": 26
},
"dan_value_counter_margin": {
"x": 56
},
"dan_exam_gauge_shift": {
"x": 48
},
"dan_exam_sub_row": {
"x": 20,
"y": 50
},
"dan_exam_sub_bar": {
"width": 234
},
},␍␍␍␍␍␍␍␍␍␍␍
"dan_between_title": {
"x": 1209,
"y": 93,
@@ -913,23 +863,7 @@
"y": 172,
"font_size": 30,
"outline": 3.0
},
"dan_exam_info_result": {
"x": 52,
"y": 154,
"width": 972
},
"dan_result_exam_sub_row": {
"x": 0,
"y": 465
},
"dan_result_exam_sub_bar": {
"x": 27,
"width": 324
},
"dan_chip_name_black": {
"x": 1
},
},␍␍␍␍
"dan_exam_grid": {
"x": 1
},
@@ -938,11 +872,11 @@
},
"dan_exam_gauge_box": {
"x": 436,
"y": 615
"y": 610
},
"dan_exam_score_box": {
"x": 769,
"y": 615,
"y": 610,
"height": 132
},
"dan_exam_seg": {
@@ -951,16 +885,16 @@
"width": 327
},
"dan_select_exam_border_text": {
"x": 319,
"y": 54,
"font_size": 28,
"outline": 2.0
"x": 309,
"y": 55,
"font_size": 25,
"outline": 2.6
},
"dan_select_gauge_border_text": {
"x": 300,
"y": 55,
"font_size": 36,
"outline": 2.6666666666666665
"x": 291,
"y": 67,
"font_size": 32,
"outline": 3.1
},
"dan_exam_value": {
"x": 185,
@@ -968,35 +902,14 @@
},
"dan_exam_label_pill": {
"x": 28,
"y": 2
},
"dan_exam_value_left": {
"x": 528
},
"y": -1
},␍
"dan_game_exam_border_text": {
"x": 500,
"y": 621,
"font_size": 36,
"outline": 2.6666666666666665
},
"dan_result_exam_border_text": {
"x": 772,
"y": 420,
"font_size": 36,
"outline": 2.6666666666666665
},
"dan_result_exam_border_song": {
"x": 850,
"y": 468,
"font_size": 20,
"outline": 2.3333333333333335
},
"dan_result_gauge_border_text": {
"x": 498,
"y": 460,
"font_size": 25,
"outline": 2.3333333333333335
},
},␍␍␍
"dan_exam_text_more": {
"text": {
"ja": "%s 以上",
@@ -1020,10 +933,7 @@
"zh": "本次挑戰不會被記錄",
"ko": "이번 도전은 기록되지 않습니다"
}
},
"dan_result_nosave_text": {
"font_size": 24
},
},␍
"dan_exam_text_gauge": {
"text": {
"ja": "%s %以上",
@@ -1039,15 +949,7 @@
"zh": "%s%未满",
"ko": "%s% 미만"
}
},
"note_arc_pivot": {
"x": 1269.22,
"y": 415.14
},
"note_arc_pivot_2p": {
"x": 1282.19,
"y": -167.83
},
},␍␍
"entry_game_comment_1": {
"text": {
"ja": "すきな曲や、むずかしさを",
+1 -2
View File
@@ -191,8 +191,7 @@ function Background.new(player_num, bpm, scene_preset)
self.donbg_1 = DonBG.create(1, "background", donbg_index)
self.donbg_2 = DonBG.create(2, "background", donbg_index)
end
local skin_cfg = tex.get_skin_config("game_2p_offset")
self.p2_y_offset = skin_cfg and skin_cfg.y or 0
self.p2_y_offset = 804
self.is_clear_1 = false
self.is_clear_2 = false
elseif pack then
+10 -6
View File
@@ -155,14 +155,18 @@ function DanBackground:draw_back()
self.chibi:draw()
end
-- dan soul gauge separator overlay (static, drawn at a hardcoded fade).
-- the soul gauge's strip the lane covers (the cabinet draws the gauge over the lane), then
-- its threshold marker, on top of everything
local LANE_TOP, GAUGE_BOTTOM = 276, 288
function DanBackground:draw_fore()
if not self._gauge_overlay then
self._gauge_overlay = tex.get_texture("game/gauge_dan/overlay") or 0
end
if self._gauge_overlay ~= 0 then
tex.draw_texture(self._gauge_overlay, { fade = 0.15 })
local redraw = _G.g_dan_gauge_redraw
if redraw then
tex.begin_scissor(0, LANE_TOP, tex.get_screen_width(), GAUGE_BOTTOM - LANE_TOP)
local ok, err = pcall(redraw)
tex.end_scissor()
if not ok then error(err, 0) end
end
self.dan_info:draw_marker()
end
-- dan condition plate, drawn in the gauge's own layer.
+1 -2
View File
@@ -13,8 +13,7 @@ function Chibi0.new(index, bpm, is_2p, path)
end
function Chibi0:draw()
local game_2p_offset = tex.get_skin_config("game_2p_offset") or { y = 0 }
local y_offset = self.is_2p and game_2p_offset.y or 0
local y_offset = self.is_2p and 804 or 0
tex.draw_texture(tex.get_texture(self.path .. "/" .. self.name .. "/" .. tostring(self.texture_index)), {
frame = self.texture_change.attribute,
+1 -2
View File
@@ -54,8 +54,7 @@ function Chibi13:update(current_time_ms, bpm)
end
function Chibi13:draw()
local game_2p_offset = tex.get_skin_config("game_2p_offset") or { y = 0 }
local y_offset = self.is_2p and game_2p_offset.y or 0
local y_offset = self.is_2p and 804 or 0
tex.draw_texture(self._id_tail, {
frame = self.frame,
+1 -2
View File
@@ -40,8 +40,7 @@ function Chibi2:update(current_time_ms, bpm)
end
function Chibi2:draw()
local game_2p_offset = tex.get_skin_config("game_2p_offset") or { y = 0 }
local y_offset = self.is_2p and game_2p_offset.y or 0
local y_offset = self.is_2p and 804 or 0
local tex_info = tex.get_texture_info(self.name, tostring(self.texture_index))
if not tex_info then return end
+1 -2
View File
@@ -14,8 +14,7 @@ function Chibi4.new(index, bpm, is_2p, path)
end
function Chibi4:draw()
local game_2p_offset = tex.get_skin_config("game_2p_offset") or { y = 0 }
local y_offset = self.is_2p and game_2p_offset.y or 0
local y_offset = self.is_2p and 804 or 0
tex.draw_texture(tex.get_texture(self.path .. "/" .. self.name .. "/" .. tostring(self.texture_index)), {
frame = self.texture_change.attribute,
+1 -2
View File
@@ -14,8 +14,7 @@ function Chibi5.new(index, bpm, is_2p, path)
end
function Chibi5:draw()
local game_2p_offset = tex.get_skin_config("game_2p_offset") or { y = 0 }
local y_offset = self.is_2p and game_2p_offset.y or 0
local y_offset = self.is_2p and 804 or 0
tex.draw_texture(tex.get_texture(self.path .. "/" .. self.name .. "/" .. tostring(self.texture_index)), {
frame = self.texture_change.attribute,
+1 -2
View File
@@ -14,8 +14,7 @@ function Chibi8.new(index, bpm, is_2p, path)
end
function Chibi8:draw()
local game_2p_offset = tex.get_skin_config("game_2p_offset") or { y = 0 }
local y_offset = self.is_2p and game_2p_offset.y or 0
local y_offset = self.is_2p and 804 or 0
tex.draw_texture(tex.get_texture(self.path .. "/" .. self.name .. "/" .. tostring(self.texture_index)), {
frame = self.texture_change.attribute,
+1 -2
View File
@@ -18,8 +18,7 @@ function ChibiBad.new(index, bpm, is_2p, path)
local screen_width = tex.get_screen_width()
local screen_scale = tex.get_screen_scale()
local skin_config = tex.get_skin_config("game_2p_offset")
self.game_2p_offset_y = skin_config and skin_config.y or 0
self.game_2p_offset_y = 804
self.texture_index = math.random(0, 2)
self.keyframes = { 3, 4 }
+1 -2
View File
@@ -29,8 +29,7 @@ function BaseChibi.new(index, bpm, is_2p, path)
})
self.vert_move:start()
local skin_config = tex.get_skin_config("game_2p_offset")
self.game_2p_offset_y = skin_config and skin_config.y or 0
self.game_2p_offset_y = 804
local texture_keys = tex.get_texture_keys(self.name)
local digit_keys = {}
+40 -8
View File
@@ -1,5 +1,7 @@
-- 段位道場 exam-panel extras only Lua can draw: the soul-gauge pass-threshold
-- callout plate + captions, anchored on the gauge's own 50-cell grid.
-- callout plate + captions and the white threshold marker on the threshold cell, anchored
-- on the gauge's own 50-cell grid. It also hands the threshold (in cells) to the gauge script
-- (g_dan_gauge_border), which colours the track by it.
local M = {}
M.__index = M
@@ -11,23 +13,30 @@ local LABEL_SIZE = 30 -- arcade MS 明朝 36; ours reads
local WHITE = { 255, 255, 255, 255 }
local BLACK = { 0, 0, 0, 255 }
local PLATE_W, PLATE_H = 586, 60
local PLATE_W, PLATE_H = 586, 60 -- the plate's grey body; the art adds a 9 px margin
local PLATE_ART_PAD = 9 -- (the pill's top/left edge and the drop shadow)
local PLATE_GAP = 12 -- px between the plate's bottom and the bar top
local PLATE_OVERHANG = 24 -- px the plate extends PAST the threshold
local PILL_CX, PILL_CY = 150, 20 -- 魂ゲージ ink centre, plate-local
local VALUE_RIGHT = 532 -- 100%以上 is RIGHT-aligned to this
local VALUE_CY = 22 -- its ink centre y, plate-local
local VALUE_CY = 35 -- its ink centre y, plate-local
local NAME_SIZE = 26 -- arcade id 142
local VALUE_SIZE = 36 -- arcade id 141
-- the threshold marker (gauge_border_cell): its white inside (x 7, y 7 in the art) lands on
-- the threshold cell's left edge + 1, from y 238, as the cabinet's border_N
local MARKER_INNER_X, MARKER_INNER_Y = 7, 7
local MARKER_Y = 238
local CAP_FILL = { 255, 255, 255, 255 }
local CAP_OUTLINE = { 80, 60, 45, 255 } -- #503C2D
local VALUE_OUTLINE = { 0, 0, 0, 255 }
function M.new()
return setmetatable({ state = nil, label = nil, label_for = nil,
name_label = nil, plate = nil, plate_tried = false }, M)
name_label = nil, plate = nil, plate_tried = false,
marker = nil, marker_tried = false }, M)
end
function M:plate_id()
@@ -38,9 +47,12 @@ function M:plate_id()
return self.plate
end
-- Called from Background:handle_dan.
function M:handle(state)
self.state = state
function M:marker_id()
if not self.marker_tried then
self.marker_tried = true
self.marker = tex.get_texture("game/dan_info/gauge_border_cell")
end
return self.marker
end
local function gauge_exam(state)
@@ -51,6 +63,14 @@ local function gauge_exam(state)
return nil
end
-- Called from Background:handle_dan.
function M:handle(state)
self.state = state
local ex = gauge_exam(state)
_G.g_dan_gauge_border = (ex and ex.red and ex.red > 0)
and math.max(1, math.min(CELL_COUNT, math.floor(ex.red / 2))) or nil
end
-- Called from Background:draw_fore(), i.e. after the whole GAME_DAN HUD.
function M:draw()
local st = self.state
@@ -84,7 +104,7 @@ function M:draw()
local px = math.max(0, math.floor(x - PLATE_W + PLATE_OVERHANG + 0.5))
local py = GAUGE_Y - PLATE_GAP - PLATE_H
if pid then
tex.draw_texture(pid, { x = px, y = py })
tex.draw_texture(pid, { x = px - PLATE_ART_PAD, y = py - PLATE_ART_PAD })
end
-- fail soft: with no plate art the two captions still draw, at the same places
@@ -103,4 +123,16 @@ function M:draw()
end
end
-- The threshold marker, drawn over the lane's frame as on the cabinet (it reaches below the
-- gauge), so from Background:draw_fore() rather than with the plate in the gauge layer.
function M:draw_marker()
local ex = gauge_exam(self.state)
if not ex or not ex.red or ex.red <= 0 then return end
local n = math.max(1, math.min(CELL_COUNT, math.floor(ex.red / 2)))
local mid = self:marker_id()
if not mid then return end
local cell_left = GAUGE_X0 + CELL_PITCH * (n - 1)
tex.draw_texture(mid, { x = cell_left + 1 - MARKER_INNER_X, y = MARKER_Y - MARKER_INNER_Y })
end
return M
+394 -8
View File
@@ -47,12 +47,14 @@ function DanSelect.new()
end
-- pos: selected chip x (the textures' own json positions carry the rest);
-- now_ms: engine clock; moved_ms: ms since the last ribbon step (-1 = never).
local function draw_cursor(self, pos, now_ms, moved_ms)
-- now_ms: engine clock; moved_ms: ms since the last ribbon step (-1 = never);
-- y: how far the selected chip has dropped (see draw_box below).
local function draw_cursor(self, pos, now_ms, moved_ms, y)
y = y or 0
if self.t_cursor then
local f = (now_ms * 0.06) % 60
local a = CUR:get("#259@0", f, "a") or 1
tex.draw_texture(self.t_cursor, { x = pos, fade = a })
tex.draw_texture(self.t_cursor, { x = pos, y = y, fade = a })
end
if moved_ms and moved_ms >= 0 then
local f = moved_ms * 0.06
@@ -61,10 +63,10 @@ local function draw_cursor(self, pos, now_ms, moved_ms)
local a = ARW:get("#261@0", f, "a") or 0
if a > 0 then
if self.t_arrow_r then
tex.draw_texture(self.t_arrow_r, { x = pos + drift, fade = a })
tex.draw_texture(self.t_arrow_r, { x = pos + drift, y = y, fade = a })
end
if self.t_arrow_l then
tex.draw_texture(self.t_arrow_l, { x = pos - drift, fade = a })
tex.draw_texture(self.t_arrow_l, { x = pos - drift, y = y, fade = a })
end
end
end
@@ -73,6 +75,146 @@ end
if HAS_CLIPS then DanSelect.draw_cursor = draw_cursor end
-- The level is the cabinet's own art, one "star + number" image per level
-- (yellow_box/difficulty_level, frames 1..10 and 10+), in place of the parent's star and
-- level digits, which are held back.
local function draw_level(level, x, y, f)
local id = tex.get_texture("dan_select/yellow_box/difficulty_level")
if not id or level < 1 then return end
tex.draw_texture(id, { frame = math.min(level, 11) - 1, x = x, y = y, fade = f })
end
-- The course rows are set as the cabinet's: the song title alone (no subtitle line), and the
-- exam values with narrow digits beside full-width 以上/未満 and a little room between them.
-- The skin has one font, so each text is cut into runs of ASCII and of everything else, each
-- run made on its own and scaled as it is drawn, the runs butted together. The parent is handed
-- the box through a view whose song_subtitle_text gives nothing and whose song_title_text gives
-- such a title, and the captions it makes for the exam values are made the same way. Only CJK
-- languages are rescaled; the skin's font for the others is narrow already.
local function cjk_language()
local l = tex.language() or ""
return l:find("^ja") or l:find("^zh") or l:find("^ko") or l == "tw" or l == "cn"
end
local TITLE_CJK = { latin = 1, cjk = 1.02, sy = 1, dy = 0, max_w = 1100 }
local VALUE_CJK = { latin = 0.85, cjk = 1.0, sy = 1.0, dy = 0, gap = 8 }
local TITLE_PLAIN = { latin = 1, cjk = 1, sy = 1, dy = 0, max_w = 1100 }
local VALUE_PLAIN = { latin = 1, cjk = 1, sy = 1, dy = 0 }
local function runs_of(str)
local runs, cur, ascii = {}, {}, nil
for ch in str:gmatch("[%z\1-\127\194-\244][\128-\191]*") do
local a = ch:byte() < 128
if ascii ~= nil and a ~= ascii then
runs[#runs + 1] = { text = table.concat(cur), ascii = ascii }
cur = {}
end
cur[#cur + 1] = ch
ascii = a
end
if #cur > 0 then runs[#runs + 1] = { text = table.concat(cur), ascii = ascii } end
return runs
end
-- create: text.create_raw_text as it was before any wrapping. The parts' sizes are read when
-- they are used, since a text's texture (and size) may still be building when it is made.
local function mixed_text(create, str, size, color, outline_color, outline, spacing, style)
local pad = math.floor((outline or 0) * tex.get_screen_scale()) + 2
local parts = {}
for _, r in ipairs(runs_of(str)) do
parts[#parts + 1] = { t = create(r.text, size, color, outline_color, false, outline, spacing),
sx = r.ascii and style.latin or style.cjk }
end
local function layout()
local function span(k)
local x = 0
for n, q in ipairs(parts) do
q.x = x
local next_sx = parts[n + 1] and parts[n + 1].sx * k or 0
x = x + (q.t.width - pad) * q.sx * k - pad * next_sx
if parts[n + 1] then x = x + (style.gap or 0) * k end
end
local last = parts[#parts]
return last and (last.x + last.t.width * last.sx * k) or 0
end
local k, w = 1, span(1)
if style.max_w and w > style.max_w then
k = style.max_w / w
w = span(k)
end
local h = 0
for _, q in ipairs(parts) do h = math.max(h, q.t.height) end
return k, w, h * style.sy
end
return setmetatable({
text = str,
draw = function(_, p)
local k = layout()
for _, q in ipairs(parts) do
local sx = q.sx * k
q.t:draw({ x = p.x + q.x, y = (p.y or 0) + style.dy, fade = p.fade,
x2 = q.t.width * (sx - 1), y2 = q.t.height * (style.sy - 1) })
end
end,
}, {
__index = function(_, key)
if key == "width" then local _, w = layout(); return w end
if key == "height" then local _, _, h = layout(); return h end
end,
})
end
local title_cache = {} -- by string, size and outline: texts are built once, not per frame
local raw_create = text.create_raw_text -- the engine's, before draw_dan_open wraps it
local function course_view(box)
local titles = {}
return setmetatable({}, {
__index = function(_, k)
if k == "song_subtitle_text" then return function() return nil end end
if k == "song_title_text" then
return function(_, i)
if titles[i] == nil then
local t = box:song_title_text(i)
local ok, str = pcall(function() return t and t.text end)
local td = tex.get_skin_config("dan_title")
if t and ok and type(str) == "string" and str ~= "" and td then
local ol = td.outline >= 0 and td.outline or 5
local key = str .. "\0" .. td.font_size .. "\0" .. ol
title_cache[key] = title_cache[key]
or mixed_text(raw_create, str, td.font_size,
{ 255, 255, 255, 255 }, { 0, 0, 0, 255 }, ol, 2,
cjk_language() and TITLE_CJK or TITLE_PLAIN)
titles[i] = title_cache[key]
else
titles[i] = t or false -- an engine without OutlinedText.text
end
end
return titles[i] or nil
end
end
local v = box[k]
if type(v) == "function" then
return function(_, ...) return v(box, ...) end
end
return v
end,
})
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
@@ -82,16 +224,43 @@ local held_stamp -- shared: the boxes and the title can be drawn through diffe
if parent_open then
function DanSelect:draw_dan_open(box)
local stamp = tex.get_texture("dan_select/yellow_box/clear_mark")
if not stamp or box.clear_mark <= 0 then return parent_open(self, box) end
local level = tex.get_texture("dan_select/yellow_box/difficulty_level")
local hide = {}
if level then
for _, n in ipairs({ "difficulty_star", "difficulty_num", "difficulty_x" }) do
local t = tex.get_texture("dan_select/yellow_box/" .. n)
if t then hide[#hide + 1] = t end
end
end
local draw = tex.draw_texture
tex.draw_texture = function(id, p)
if id == stamp then return end
for _, t in ipairs(hide) do -- handles compare with ==, not as table keys
if id == t then return end
end
return draw(id, p)
end
local ok, err = pcall(parent_open, self, box)
local create = text.create_raw_text
text.create_raw_text = function(str, size, color, outline_color, vertical, outline, spacing, ...)
if vertical or type(str) ~= "string" then -- only the exam value captions
return raw_create(str, size, color, outline_color, vertical, outline, spacing, ...)
end
return mixed_text(raw_create, str, size, color, outline_color, outline, spacing,
cjk_language() and VALUE_CJK or VALUE_PLAIN)
end
local ok, err = pcall(parent_open, self, course_view(box))
text.create_raw_text = create
tex.draw_texture = draw
if not ok then error(err, 0) end
held_stamp = { id = stamp, frame = box.clear_mark - 1, fade = box.open_fade.attribute }
local f = box.open_fade.attribute
local off = tex.get_skin_config("dan_yellow_box_offset") or { x = 0, y = 0 }
if level then
for i = 0, box:song_count() - 1 do
draw_level(box:song_level(i), i * (off.x or 0), i * (off.y or 0), f)
end
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()
@@ -101,3 +270,220 @@ if parent_open then
if s then tex.draw_texture(s.id, { frame = s.frame, fade = s.fade }) end
end
end
-- The back entry is one more chip in the top strip (back/folder, laid out like box/folder);
-- the parent's opening board is its own layout, so nothing opens under it here.
-- Its label comes from skin_config dan_back_label, so it follows the language setting. It is set
-- like the dan chip names (black, no outline: dan_chip_name_black), vertical for CJK and
-- across, squeezed to the chip, for other languages.
local CJK = { ja = true, zh = true, ko = true, tw = true, cn = true }
local back_label
local BACK_ACROSS_SIZE = 0.7 -- size of a label set across, against dan_back_label.font_size
local function get_back_label()
if back_label == nil then
local cfg = tex.get_skin_config("dan_back_label")
if not cfg then back_label = false; return false end
local lang = tex.language()
local vertical = CJK[lang] or CJK[lang:sub(1, 2)] or false
-- a word set across has only the chip's width, so it takes a smaller size than the
-- vertical labels rather than being squeezed hard
local size = vertical and cfg.font_size or math.floor(cfg.font_size * BACK_ACROSS_SIZE + 0.5)
back_label = {
cfg = cfg,
vertical = vertical,
main = raw_create(tex.skin_text("dan_back_label"), size,
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, vertical, 0, 2),
}
end
return back_label
end
local function draw_back_label(bx, fade, y)
local label = get_back_label()
if not label then return end
local cfg, main = label.cfg, label.main
local sx, sy = 1, 1
if label.vertical then
sy = math.min(1, cfg.height / main.height)
else
sx = math.min(1, cfg.width / main.width) -- width: chip face less the border
end
local w, h = main.width * sx, main.height * sy
main:draw({ x = bx + cfg.x - w / 2, y = cfg.y + (cfg.height - h) / 2 + y,
x2 = w - main.width, y2 = h - main.height, fade = fade })
end
-- The selected chip drops below the strip, as the cabinet's does, easing there and back.
-- Only draw_cursor (called after every box) is told where the cursor is, so the boxes are
-- held back in draw_box and drawn from draw_cursor.
local SELECTED_DROP = 22
local DROP_MS = 60 -- time constant of the ease
local drop = {} -- chip key -> current drop
local held_boxes = {}
local last_ms
local function chip_key(box)
return box.is_back and "\0back" or box.text_name
end
local function chip_drop(box)
return drop[chip_key(box)] or 0
end
local function draw_chip_name(box, bx, y, fade)
local name = box:chip_name()
if not name then return end
local nb = tex.get_skin_config("dan_chip_name") or { x = 0, y = 0 }
name:draw({
x = bx + nb.x - name.width / 2,
y = nb.y + y,
y2 = math.min(name.height, nb.height or name.height) - name.height,
fade = fade,
})
end
-- the chip as the parent draws it (folder, stamp, name), at its drop
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 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
function DanSelect:draw_back_box(box)
local bx, fade, y = box:box_x(), box.fade.attribute, chip_drop(box)
local id = tex.get_texture("dan_select/back/folder")
if id then tex.draw_texture(id, { x = bx, y = y, fade = fade }) end
draw_back_label(bx, fade, y)
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 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 = sf, x = box:box_x(), y = chip_drop(box),
fade = box.fade.attribute })
end
end
local parent_draw_box = DanSelect.draw_box
function DanSelect:draw_box(box)
held_boxes[#held_boxes + 1] = box
end
local cursor_parent = DanSelect.draw_cursor
function DanSelect:draw_cursor(pos, now_ms, moved_ms)
local boxes = held_boxes
held_boxes = {}
local k = last_ms and math.min(1, math.max(0, now_ms - last_ms) / DROP_MS) or 1
last_ms = now_ms
local selected
for _, box in ipairs(boxes) do
local key = chip_key(box)
local is_sel = math.abs(box:box_x() - pos) < 1
if is_sel then selected = box end
local d = drop[key] or 0
d = d + ((is_sel and SELECTED_DROP or 0) - d) * k
drop[key] = (math.abs(d) >= 0.05) and d or nil
end
-- draw every box even if one fails, then report the first failure
local err
for _, box in ipairs(boxes) do
local ok, e = pcall(parent_draw_box, self, box)
if not ok and not err then err = e end
end
if err then error(err, 0) end
local y = selected and chip_drop(selected) or 0
if cursor_parent then
cursor_parent(self, pos, now_ms, moved_ms, y)
elseif self.t_cursor then
tex.draw_texture(self.t_cursor, { x = pos, y = y })
end
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). With no best
-- (a course never played, or an engine without them) the row is not drawn at all, pill
-- included. The gauge box gets yellow_box/exam_gauge_best_pill, the right-hand boxes
-- 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 } -- exam_gauge_best_pill, 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, font_size)
font_size = font_size or (tex.get_skin_config(key) or {}).font_size
if not font_size 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, 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(pill, value, etype, px, py, pw, f)
if value == nil then return end
if pill then tex.draw_texture(pill, { x = px, y = py, fade = f }) end
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
local str = tostring(value) .. (etype == "gauge" and " %" or "")
local t = best_text("dan_exam_best_value", str, 26)
if t then
t:draw({ x = px + pw - BEST_VALUE_R - t.width, y = py + (BEST_H - t.height) / 2, fade = f })
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 gauge_pill = tex.get_texture("dan_select/yellow_box/exam_gauge_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(gauge_pill, 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
local v = gothrough and call(box, "exam_best", i) or call(box, "exam_song_best", i, k)
draw_best_row(pill, v, etype, px, py, BEST_RIGHT.w, f)
end
right_row = right_row + 1
end
end
end
end
+1 -1
View File
@@ -191,7 +191,7 @@ function EntryBox.new(text_str, font_size)
for i, key in ipairs(mode.comment_keys) do lines[i] = tex.skin_text(key, lang) end
for i, line in ipairs(lines) do
self.info[i] = text.create_raw_text(line, INFO_SIZE, INFO_COLOR, INFO_OUTLINE, false,
INFO_BORDER / tex.get_screen_scale(), INFO_SPACING)
INFO_BORDER / tex.get_screen_scale(), INFO_SPACING, 1.0, "FOT-Seurat_Pro_B.otf")
end
end
+2 -3
View File
@@ -7,18 +7,17 @@ function EntryPlayer.new(side)
-- fold the side-select cursor (0=1P, 2=2P) to 0/1
self.side = (side == 0) and 0 or 1
local drum_offset_cfg = tex.get_skin_config("entry_drum_offset")
local chara_offset_r = tex.get_skin_config("entry_chara_offset_r")
self.chara_y_base = chara_offset_r.y
if side == 0 then
self.drum = tex.get_texture("entry/side_select/red_drum")
self.drum_offset = drum_offset_cfg.x
self.drum_offset = 0
local chara_l = tex.get_skin_config("entry_chara_offset_l")
self.chara_x_offset = chara_l.x
else
self.drum = tex.get_texture("entry/side_select/blue_drum")
self.drum_offset = drum_offset_cfg.y
self.drum_offset = 960
self.chara_x_offset = chara_offset_r.x
end
+8 -14
View File
@@ -113,10 +113,8 @@ end
function DanGameDraw:exam_row(info, y, song_index, frame_ms)
local t = self.t
local dei = tex.get_skin_config("dan_exam_info_game") or tex.get_skin_config("dan_exam_info")
local bm = tex.get_skin_config("dan_exam_border_margin")
local border_margin = bm and bm.x or tex.get_skin_config("dan_score_box_margin").x
local vm = tex.get_skin_config("dan_value_counter_margin")
local value_margin = vm and vm.x or border_margin
local border_margin = 26
local value_margin = 56
tex.draw_texture(t.exam_bg, { y = y })
tex.draw_texture(t.exam_badge, { frame = info.gothrough and 0 or 1 + math.min(song_index, 2), y = y })
@@ -124,8 +122,7 @@ function DanGameDraw:exam_row(info, y, song_index, frame_ms)
local all = info.gothrough
tex.draw_texture(all and t.exam_frame_back_all or t.exam_overlay_1, { y = y })
local wa = tex.get_skin_config("dan_exam_bar_all")
local bar_full = (all and wa) and wa.width or dei.width
local bar_full = all and 972 or dei.width
if info.failed then
if t.exam_fail then tex.draw_texture(t.exam_fail, { y = y, x2 = bar_full }) end
@@ -156,8 +153,7 @@ function DanGameDraw:exam_row(info, y, song_index, frame_ms)
local gauge_shift = 0
if info.exam_type == "gauge" then
tex.draw_texture(t.exam_percent, { y = y, index = 0 })
local gs = tex.get_skin_config("dan_exam_gauge_shift")
gauge_shift = -(gs and gs.x or border_margin)
gauge_shift = -48
end
self:digit_counter(tostring(info.red_value), border_margin, t.exam_border_counter, 0, y, gauge_shift)
end
@@ -165,7 +161,7 @@ function DanGameDraw:exam_row(info, y, song_index, frame_ms)
if info.failed then
tex.draw_texture(t.exam_failed, { y = y })
else
local vl = tex.get_skin_config("dan_exam_value_left")
local vl = { x = 528 }
local live = tostring(info.counter_value)
if vl then
local vc = tex.get_texture_info("dan_info", "value_counter")
@@ -186,11 +182,9 @@ function DanGameDraw:exam_row(info, y, song_index, frame_ms)
end
if not all then
local sp = tex.get_skin_config("dan_exam_sub_row")
local sub_pitch = sp and sp.y or 50.0
local sub_margin = sp and sp.x or 20.0
local sb = tex.get_skin_config("dan_exam_sub_bar")
local sub_full = sb and sb.width or 234.0
local sub_pitch = 50.0
local sub_margin = 20.0
local sub_full = 234.0
for j = 0, 1 do
local sy = y + j * sub_pitch
tex.draw_texture(t.exam_sub_bg, { y = sy })
+89 -4
View File
@@ -4,6 +4,7 @@
-- length-1 (at length it left a dark gap cell before it)
-- * the clear mark sits gauge_clear_mark_offset cells (skin_config: 1, the cell edge) before
-- the exact clear fraction, not the parent's 87/60
-- The dan gauge is drawn as the cabinet's tamashii_gauge (see draw_dan below).
-- Everything else is the parent's file, loaded from its own copy.
-- the parent skin's copy of a script: the second match on package.path (the first is this file)
@@ -23,10 +24,20 @@ assert(load_parent("game/gauge"), "game/gauge: the parent skin has no gauge scri
local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
local parent_new = Gauge.new
function Gauge.new(...)
local self = parent_new(...)
local mark = tex.get_skin_config("gauge_clear_mark_offset")
self.clear_mark_offset = mark and mark.x
function Gauge.new(is_2p, dan, string_diff, opts)
local self = parent_new(is_2p, dan, string_diff, opts)
self.clear_mark_offset = 1
if dan then
local screen = (opts and opts.screen) or "game"
local p = (opts and opts.player_str and (opts.player_str .. "_")) or (is_2p and "2p_" or "1p_")
local function t(name) return tex.get_texture(screen .. "/gauge_dan/" .. name) end
self.cab = {
track_red = t("track_red"),
lamp = t(p .. "lamp"),
lamp_clear = t("lamp_clear"),
fade_clear = t("bar_fade_clear"),
}
end
return self
end
@@ -101,3 +112,77 @@ function Gauge:render(y, mirror, idx, points, previous_points, max_points, clear
self:blit(self.tamashii_dark, nil, nil, y, nil, nil, nil, idx)
end
end
-- The dan gauge as the cabinet's tamashii_gauge draws it: the gold track (border), the red
-- track (track_red, gauge_bg) up to the threshold, the lit cells as one lamp stretched 21 px
-- per cell (lamp_clear, yellow, once the gauge reaches the threshold), the glow on a newly lit
-- cell, the cell separators at the cabinet's 103/255, then 魂: grey, white once cleared, and
-- in flames at full. The threshold comes from the dan exam (background dan_info sets
-- g_dan_gauge_border, in cells); without it, or without the cabinet pieces, the parent draws.
local CAB_CELL = 21
local CAB_TRACK = 20.88 -- gauge_bg: 160 px x 0.1305 per cell
local CAB_SEPARATOR = 103 / 255
local parent_draw_dan = Gauge.draw_dan
-- The cabinet draws the gauge over the lane; the engine draws the lane after it, so its top
-- edge (y 276, 184 px x 1.5) hides the cells' last rows. The gauge leaves a redraw for the
-- dan background's draw_fore (g_dan_gauge_redraw), which repeats it clipped to that strip.
local function draw_cab(self, border, points, previous_points, max_points, is_rainbow,
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
local cab = self.cab
local function layer(t, x, x2, fade, frame, scale, center)
if t then
tex.draw_texture(t, { x = x, x2 = x2, fade = fade, frame = frame, scale = scale, center = center })
end
end
local length, solid, alpha, show_up = self:cells(points, previous_points, max_points, anim_active, anim_alpha)
local clear = length >= border
layer(self.border)
if border > 0 then layer(cab.track_red, nil, CAB_TRACK * border - 160) end
if solid > 0 then layer(clear and cab.lamp_clear or cab.lamp, nil, CAB_CELL * solid - 8) 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)
layer(self.rainbow, nil, nil, rainbow_fade, frame_a)
layer(self.rainbow, nil, nil, rainbow_fade * f, frame_b)
end
if show_up and length > 0 then
layer(clear and cab.fade_clear or self.bar_fade, (length - 1) * CAB_CELL, nil, alpha)
end
layer(self.overlay, nil, nil, CAB_SEPARATOR)
if is_rainbow then
layer(self.fire, nil, nil, nil, fire_frame, 0.75, true)
layer(self.tamashii)
if fire_frame == 0 or fire_frame == 1 or fire_frame == 4 or fire_frame == 5 then
layer(self.tamashii_overlay, nil, nil, 0.5)
end
elseif clear then
layer(self.tamashii)
else
layer(self.tamashii_dark)
end
end
function Gauge:draw_dan(points, previous_points, max_points, is_rainbow,
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
local cab = self.cab
local border = _G.g_dan_gauge_border
if not (cab and cab.track_red and cab.lamp and cab.lamp_clear and border) then
_G.g_dan_gauge_redraw = nil
return parent_draw_dan(self, points, previous_points, max_points, is_rainbow,
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
end
draw_cab(self, border, points, previous_points, max_points, is_rainbow,
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
_G.g_dan_gauge_redraw = function()
draw_cab(self, border, points, previous_points, max_points, is_rainbow,
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
end
end
+94
View File
@@ -0,0 +1,94 @@
-- This skin's note arc: the parent's script with the flight and the big-note sparks redone as
-- the cabinet's (onp_jump):
-- * the note flies from the judge circle to 魂 in 30 frames on the cabinet's path, here a
-- cubic Bezier fitted to it (within 6 px), P1 arcing up and P2 down, each with its own fit;
-- it then waits at 魂 until the engine's flight (31 frames) ends
-- * a big note leaves 9 sparks (hit_effect/firework, the cabinet's 13-frame spark on black),
-- the first at frame 5 and then every 3 frames, each centred where the note was about 2
-- frames before, at full size, added onto the scene
-- The balloon keeps the parent's flight and rainbow (the cabinet's balloon has its own path).
-- Everything else is the parent's file, loaded from its own copy.
-- the parent skin's copy of a script: the second match on package.path (the first is this file)
local function load_parent(name)
local seen = false
for tmpl in package.path:gmatch("[^;]+") do
local chunk = loadfile((tmpl:gsub("%?", name)))
if chunk then
if seen then return chunk end
seen = true
end
end
end
assert(load_parent("game/note_arc"), "game/note_arc: the parent skin has no note_arc script")()
local FRAME_MS = 16.67
local FLIGHT_MS = 30 * FRAME_MS
-- control points as offsets from the start (c1) and from the end (c2)
local CONTROL = {
[1] = { c1x = 196.8, c1y = -474.8, c2x = -300.4, c2y = -419.3 },
[2] = { c1x = 178.5, c1y = 486.4, c2x = -314.9, c2y = 414.3 },
}
-- sparks: spawn frames, and where each sits on the 30-frame flight (frames)
local SPARK_COUNT = 9
local SPARK_SPAWN, SPARK_SPAWN_STEP = 5, 3
local SPARK_AT, SPARK_AT_STEP = 2.58, 3.085
local parent_new = NoteArc.new
function NoteArc.new(note_tex_type, big, is_balloon, player_num, start_x, start_y)
local self = parent_new(note_tex_type, big, is_balloon, player_num, start_x, start_y)
local c = CONTROL[self.p2 and 2 or 1]
self.c1x, self.c1y = self.sx + c.c1x, self.sy + c.c1y
self.c2x, self.c2y = self.ex + c.c2x, self.ey + c.c2y
-- a spark is centred on the note: both textures' own offsets and sizes
local note = tex.get_texture_info("notes", tostring(note_tex_type))
local spark = self.t_firework and tex.get_texture_info("hit_effect", "firework")
if note and spark then
self.spark_dx = note.x[1] - spark.x[1] + (note.x2[1] - spark.x2[1]) / 2
self.spark_dy = note.y[1] - spark.y[1] + (note.y2[1] - spark.y2[1]) / 2
end
return self
end
local parent_point = NoteArc.point
local parent_draw = NoteArc.draw
-- the cabinet's flight, progress 0..1 over its 30 frames
function NoteArc:point(progress)
if self.is_balloon then return parent_point(self, progress) end
local t = math.max(0, math.min(1, progress))
local u = 1 - t
local b0, b1, b2, b3 = u * u * u, 3 * u * u * t, 3 * u * t * t, t * t * t
return b0 * self.sx + b1 * self.c1x + b2 * self.c2x + b3 * self.ex,
b0 * self.sy + b1 * self.c1y + b2 * self.c2y + b3 * self.ey
end
function NoteArc:draw_fireworks(y, elapsed_ms)
if not self.spark_dx then return end
for i = 0, SPARK_COUNT - 1 do
local age_ms = elapsed_ms - (SPARK_SPAWN + SPARK_SPAWN_STEP * i) * FRAME_MS
local frame = math.floor(age_ms / FRAME_MS)
if age_ms >= 0 and frame < self.firework_frames then
local fx, fy = self:point((SPARK_AT + SPARK_AT_STEP * i) * FRAME_MS / FLIGHT_MS)
tex.draw_texture(self.t_firework, {
frame = frame, center = true, blend = "additive",
x = fx + self.spark_dx, y = y + fy + self.spark_dy,
})
end
end
end
function NoteArc:draw(y, elapsed_ms, duration_ms)
if self.is_balloon then return parent_draw(self, y, elapsed_ms, duration_ms) end
if self.big and self.t_firework and self.firework_frames > 0 then
self:draw_fireworks(y, elapsed_ms)
end
if elapsed_ms < duration_ms then
local x_i, y_i = self:point(elapsed_ms / FLIGHT_MS)
tex.draw_texture(self.t_note, { x = x_i, y = y + y_i })
end
end
return NoteArc
+1 -2
View File
@@ -18,8 +18,7 @@ function BottomCharacters.new()
self.t_chara_center = tex.get_texture("result/bottom/chara_center")
self.t_flowers = tex.get_texture("result/bottom/flowers")
local fl = tex.get_skin_config("result_flowers_offset")
self.sc_flowers_offset = fl and fl.x or 0
self.sc_flowers_offset = 1188
self.flower_index = 0
self.flower_start = nil
+10 -13
View File
@@ -276,8 +276,7 @@ function DanResultDraw:draw_page1(now)
local lv = tostring(song.diff_level)
local dm = tex.get_skin_config("dan_result_diff_num_margin").x
local dl = tex.get_skin_config("dan_result_diff_num_lead")
local lead = (dl and dl.x or 0.0) * (#lv - 1)
local lead = 9 * (#lv - 1)
for j = 1, #lv do
tex.draw_texture(self.t_diff_num, {frame = tonumber(lv:sub(j, j)),
x = sx - lead + (j - 1) * dm, y = y})
@@ -406,15 +405,13 @@ function DanResultDraw:draw_exam_info(fade, now, scale)
scale = scale or 1.0
local rd = self.rd
local on_page = now - self.page_start_ms
local dei = tex.get_skin_config("dan_exam_info_result") or tex.get_skin_config("dan_exam_info")
local dei = { x = 52, y = 154, width = 972 }
local offset_y = dei.y * scale
local margin = dei.x * scale
local sr = tex.get_skin_config("dan_result_exam_sub_row")
local sub_pitch = (sr and sr.y or 465.0) * scale
local sb = tex.get_skin_config("dan_result_exam_sub_bar")
local sub_full = sb and sb.width or 324.0
local sub_margin = (sb and sb.x or 27.0) * scale
local sub_pitch = 465 * scale
local sub_full = 324
local sub_margin = 27 * scale
local border_id = self.border_id
local border_pitch = (self.has_border_digits and 26.0 or margin) * scale
@@ -479,7 +476,7 @@ function DanResultDraw:draw_exam_info(fade, now, scale)
self:draw_exam_fill(sbs, sub_full * sp, sx, y, scale, fade, true)
tex.draw_texture(self.t_exam_sub_front, {scale = scale, x = sx, y = y, fade = fade})
local sbt = tex.get_skin_config("dan_result_exam_border_song")
local sbt = { x = 850, y = 468, font_size = 20, outline = 7 / 3 }
local scap = nil
local sbt_ol = 3.5 / tex.get_screen_scale()
if sbt then
@@ -528,7 +525,8 @@ function DanResultDraw:draw_exam_info(fade, now, scale)
cap_dy = 52.0 * scale
end
local bt = tex.get_skin_config(tamashii_row and "dan_result_gauge_border_text" or "dan_result_exam_border_text")
local bt = tamashii_row and { x = 498, y = 460, font_size = 25, outline = 7 / 3 }
or { x = 772, y = 420, font_size = 36, outline = 8 / 3 }
local capt = nil
local bt_ol = 4.0 / tex.get_screen_scale()
if bt then
@@ -635,7 +633,7 @@ function DanResultDraw:draw_page2(fade, now)
tex.draw_texture(self.t_result_exam_header, {fade = fade})
tex.draw_texture(self.t_score_box, {fade = fade})
local sm = tex.get_skin_config("dan_score_box_margin").x
local sm = 46
if totals_landed or on_page >= self.totals_start then
self:draw_digit_counter(tostring(rd.score), sm, self.t_score_counter, 0, 0.0, fade, 1.0, sm, roll_t)
end
@@ -788,8 +786,7 @@ function DanResultDraw:draw_nosave_banner()
if not self.nosave_text then
local s = tex.skin_text("dan_result_nosave")
if s == "" then s = "今回の挑戦は記録されません" end
local nt = tex.get_skin_config("dan_result_nosave_text")
self.nosave_text = text.create_raw_text(s, (nt and nt.font_size > 0) and nt.font_size or 24,
self.nosave_text = text.create_raw_text(s, 24,
{255,255,255,255}, {0,0,0,0}, false, 0.0)
end
@@ -49,13 +49,8 @@ function SongSelect:draw_pattern(bx, by, p, fade)
end
-- The genre board title, re-made at the skin_config folder_box_name size.
local FOLDER_TITLE_SIZE = nil
local FOLDER_TITLE_SIZE = 54
function SongSelect:folder_title(box)
if FOLDER_TITLE_SIZE == nil then
local cfg = tex.get_skin_config("folder_box_name")
FOLDER_TITLE_SIZE = (cfg and cfg.font_size and cfg.font_size > 0) and cfg.font_size or false
end
if not FOLDER_TITLE_SIZE then return box:name() end
local key = box.text_name
if not key or key == "" then return box:name() end
local ff = folder_frame(box)
+69 -36
View File
@@ -3,6 +3,7 @@
663598fc4f10c6e082d0cfa94f87de8867974c01c4c778250e15f7417cc11177 *./Fonts/font_kr.ttf
8eb080ec4a5af8461ba46ddf1f2755311913f180d2d9beddb070d808ad7fe7b3 *./Fonts/font.ttf
2da2748fda2bcba911b4d79b5f49d6b6f6d968ec07f1ea430e7293137cabffc6 *./Fonts/font_tw.ttf
19e5370dfb141710217e9fc06755f615e827e3f463f33d20aa276ee78c86bfd1 *./Fonts/FOT-Seurat_Pro_B.otf
8822ead5678c535daf068cbe75fc489d54cb3eb315a6abb74b453144928e0b51 *./.gitattributes
787d65f45d673897ae041c2be8c717bfd238df2a7a938e8110086e81d1ad7c15 *./Graphics/background/bga_b_001_dai/s1.png
674e00a406edcfcab7863e716ffc5b32e08830c4dc5dc2dbc5d2482281bbf5dd *./Graphics/background/bga_b_001_dai/texture.json
@@ -3329,8 +3330,16 @@ ef0b4b6c457c5ee174f9b9ccca8be313b799038be09113bc521c01d21126afbf *./Graphics/dan
1b80a57d99a7c80afc2271f261471059d39341301f3b4d97b208d86ecc5dce84 *./Graphics/dan_result/tamashii/tamashii_lit.png
0ee53c28d2c1e104d3f3b7b8e91486147540b905d3ddbb10f7f2a1a068ec7a91 *./Graphics/dan_result/tamashii/texture.json
10065ee0763749eb7e0e0027572d0dc578b0055d4ad633f67614ff7fb4b10780 *./Graphics/dan_select/animation.json
1fc18a7b407b17bf7adeae511968998c6a667ae0b6eb008895dc9867a6714dd6 *./Graphics/dan_select/back/folder.png
a7d33686dc618520da047779b3a47be6219940d386b32c1c3e54bb5aceae22ae *./Graphics/dan_select/back/texture.json
3b3d8b12304ec62c9273e2b51074b44a6b45463a1c57e4b877767aed0345b6f0 *./Graphics/dan_select/box/arrow_l.png
895a8cd5d2de9ff8f1d8c272324d1a951a2d2ce88ceb8942cefc43aaf7508aaa *./Graphics/dan_select/box/arrow_r.png
108925ad487038a40cb711be11c751b31205a2e9527e97f2dec4410503fe5cb6 *./Graphics/dan_select/box/clear_mark/0.png
0f06e751125fe6c733d59dc16b7c71aba2a0463c4436d8618782367faed4fd49 *./Graphics/dan_select/box/clear_mark/1.png
8add25664596650e50acf0a5786a1ca44e3cca3a7ff1a0815f8c4b13d99f9b71 *./Graphics/dan_select/box/clear_mark/2.png
dd126fb0697f9d54e73694c69f3ab54998b8176ffdd3c5dbe10e8b6029edb0d9 *./Graphics/dan_select/box/clear_mark/3.png
55b4cca4ce4874e95bc1265b53e0affcf477ccf4b63bd8f925db91c55597b171 *./Graphics/dan_select/box/clear_mark/4.png
8ce42b15149894471e7644a836613106a9302004211a084b6144ef66d11be07f *./Graphics/dan_select/box/clear_mark/5.png
af2bc41a290a137882377f644143db0ffeb88e09c07c7e64a7c984939feacb57 *./Graphics/dan_select/box/cursor.png
ebe09a11c7fb54ec788301688e8b72fefb56e60f6f5faa009eb30e7a6daf73f7 *./Graphics/dan_select/box/folder/0.png
ebe09a11c7fb54ec788301688e8b72fefb56e60f6f5faa009eb30e7a6daf73f7 *./Graphics/dan_select/box/folder/1.png
@@ -3339,7 +3348,7 @@ cd1f1abd28f620daa82c754e534ae5db109bf5396a3b9cefc17269ecc311cc67 *./Graphics/dan
47b54ec0b0ccccb7003d3e6a9247f1561c368446c56d355fb16831576919de0c *./Graphics/dan_select/box/folder/4.png
b8ab754cf2572c19503ab87c5bf24ec1a9b04e1979a6dda1204754bde76ca334 *./Graphics/dan_select/box/folder/5.png
6618676b7cd9b10d34ea5c77db694b7a9bfa20e00c1adc3f1360d7b58395f830 *./Graphics/dan_select/box/folder/6.png
1d4c046f5b002483fea0141996fde37460ea982d6cd54a9b361bd184205f934f *./Graphics/dan_select/box/texture.json
2ffbd8736449b0abf258f3b90772fdabc10945cc3d23259a23a77feac86264aa *./Graphics/dan_select/box/texture.json
a96f4865380131db7f110a085dc2b96ce9cbcb56167c8297edb0df1a468c3552 *./Graphics/dan_select/confirm_box/bg.png
5760a3508a5f41e9778601a1f4d4ed8b7bc26000dc75b96383f3e2088c67b2a9 *./Graphics/dan_select/confirm_box/confirmation_text.png
b5fba1d4f955a7254a2d3b3662336cb0ac19c7ed395062edc5936d218a870c29 *./Graphics/dan_select/confirm_box/no.png
@@ -3356,11 +3365,28 @@ b68761fdbdf87838919b821df2eefbac8331234b936144654bf9af97fd4ba61a *./Graphics/dan
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/dan_select/global/dan_select.png
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/dan_select/global/footer.png
1654e64f95d335434831291332c01e58f07303dd1626bb5f3ffdc0e1dcf79d82 *./Graphics/dan_select/global/texture.json
433af3c4eef82636a70592e1bebaa44d9b8f88da5abe240fe55e06535d659110 *./Graphics/dan_select/yellow_box/clear_mark/0.png
d4b24aa80e9e804737a7dbb45e9ea1bf6e1c0e2c893fb892102cde28c721c3bb *./Graphics/dan_select/yellow_box/clear_mark/1.png
8d0be9e425230fc2542f208b8494f0d007c4c23bd3a491a279d2d6ce2b7d0f62 *./Graphics/dan_select/yellow_box/clear_mark/2.png
d1cdbdb980dd549cdb8a806b7d1adc1e14193772e8cd7a62785714879a83613b *./Graphics/dan_select/yellow_box/clear_mark/3.png
0505531898b9f3e9d174464e0306517f3804304c3a9eda4a7d41897dc65b73be *./Graphics/dan_select/yellow_box/clear_mark/4.png
15c702977afc97112aff1d435e87040ea3262ecd66fcfb9ca4dfa769311b23ff *./Graphics/dan_select/yellow_box/clear_mark/5.png
9a6964ecfd9cf3b7f34a534a67b17f7ab0225b8c89e051214e5f8534581b002c *./Graphics/dan_select/yellow_box/difficulty/0.png
06a3fc664c9255c79b3996ef885e7c958f7ad7941ceccf91f70557d3e072ee92 *./Graphics/dan_select/yellow_box/difficulty/1.png
64d114e854cf179d97b592f8e6ac81232e8bdee6dbe27eb303a1de80324b1375 *./Graphics/dan_select/yellow_box/difficulty/2.png
31fa9ee020295d93bfb9cefa84d7f0a793eb6987922e485d4a68850f2d71013f *./Graphics/dan_select/yellow_box/difficulty/3.png
45960c9d19500c2f16ac388589f9a16e229f419773e259826e5a26dc39e10a14 *./Graphics/dan_select/yellow_box/difficulty/4.png
7a8488aae35dc8b279c0dfe10384b8f00fad2dee3ad1e60dd5772a432859d6af *./Graphics/dan_select/yellow_box/difficulty_level/0.png
1cc06453bff6e46e5ebf6bfaa8bdc268df3635ad37705b34165d13a2293c8c0e *./Graphics/dan_select/yellow_box/difficulty_level/10.png
bd85a2c83fcdc5e2cdaf06f1ffa966253469da4f0bbde53342cd7686a6f96a9c *./Graphics/dan_select/yellow_box/difficulty_level/1.png
3012ba59ef42231675b250b0a938bfd75d873de9d61f3569968d7c409ffe1be9 *./Graphics/dan_select/yellow_box/difficulty_level/2.png
ef2d82d94e4ab1d480b45e4ae13782210e54d17082ddc4172d2abe2f1cd598ea *./Graphics/dan_select/yellow_box/difficulty_level/3.png
e6834082724df4028007b8fac86ed3b8cbccb3741ff14ca7e227d0ad03a27158 *./Graphics/dan_select/yellow_box/difficulty_level/4.png
063373e623beed7494c636f619f10e98adc1c2b92bdac47ff9ebd4287f4b408b *./Graphics/dan_select/yellow_box/difficulty_level/5.png
088b3a9087ba64aeec320d94a95498ac83116f438c437a8825384c2144feffa7 *./Graphics/dan_select/yellow_box/difficulty_level/6.png
eed585daf6e7675be2c51f9dd315392400b8075a4dbbc7de8e9670e0cc76e2fd *./Graphics/dan_select/yellow_box/difficulty_level/7.png
23579f9c3f6d2e54d3df4ad8b64bdddd5a014d3d989af8e0a0b13a0383e2d173 *./Graphics/dan_select/yellow_box/difficulty_level/8.png
0e0ff6a91affcd09f57190a71b3a6b61af0553c4d281364f508b99770365cf6b *./Graphics/dan_select/yellow_box/difficulty_level/9.png
0014f3473839f3113477ee1489fa201b0b9a57b128d1f4fa0051e453cd995e08 *./Graphics/dan_select/yellow_box/difficulty_num/0.png
3599e784a847bc372f6091033b47b2fdd272735bdccf537a3841300c0806afe3 *./Graphics/dan_select/yellow_box/difficulty_num/1.png
cdaeb5239022380363b69aafc483eca858886827d464ac4a726142b9449789b3 *./Graphics/dan_select/yellow_box/difficulty_num/2.png
@@ -3372,7 +3398,9 @@ cdaeb5239022380363b69aafc483eca858886827d464ac4a726142b9449789b3 *./Graphics/dan
cfcd12ad72854553a219383d5ab5154a2866b83dcfc018e78a810cc46b5ca3a2 *./Graphics/dan_select/yellow_box/difficulty_num/8.png
2d6d2c2f3eb674283f4c1feb828b9ce732aaec8ae210d0123b0c44aad99559cd *./Graphics/dan_select/yellow_box/difficulty_num/9.png
4840d915478f13f1adbbc866c8eaa72dbb27393ad2c88dc54c285101e40f48ae *./Graphics/dan_select/yellow_box/difficulty_star.png
c2153f77e11087fcb078ae38527fa83bef29791e3700e30cc87fec4405a66d0f *./Graphics/dan_select/yellow_box/difficulty_ura.png
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/dan_select/yellow_box/difficulty_x.png
9d171b073242c4448e0664533aa54e3f1c337d5e7fd32e7a1e3fa55865382c8f *./Graphics/dan_select/yellow_box/exam_best_pill.png
a5ea57b78b0e4959035cb394f98e19c8a57d9607cd646564002781e6eb82570d *./Graphics/dan_select/yellow_box/exam_box_bottom_left.png
86ce13a7c3215c7922d92aaa5ad8620778cfbcc444142d68399c9c2e92662e1a *./Graphics/dan_select/yellow_box/exam_box_bottom.png
153446952af71a6cc57b3b1e2a5dceda6bc0ee3c94bbaf8518e9270efab08bd3 *./Graphics/dan_select/yellow_box/exam_box_bottom_right.png
@@ -3382,20 +3410,21 @@ d56d768e8db76b6e945c7725ca480bd3d01424a10b705ffe5c007f722a298571 *./Graphics/dan
bb5d9cbce1b83f26cd3564d96beed21dadc05ee609cb9e69b04310c4b297a871 *./Graphics/dan_select/yellow_box/exam_box_top_left.png
7dcce8395c86653a21e229373d40c6ceabe83614a324b42a72e09059c61c6034 *./Graphics/dan_select/yellow_box/exam_box_top.png
f75307055462832bd99c82a5fe6729f47a4e29f63414a1065af11b30320d766c *./Graphics/dan_select/yellow_box/exam_box_top_right.png
2455c80a86f4003cfc32f0f08227bf2d96378bb72be5d483db86932010c471a3 *./Graphics/dan_select/yellow_box/exam_combo.png
1bff70c16e8317b31c917e471c0b8e142e5fd2c61369bf631778f46559a10429 *./Graphics/dan_select/yellow_box/exam_combo.png
f33b63c29cdcf63cf002f0cac08f96015ed299e25d1707f045a6a544161716da *./Graphics/dan_select/yellow_box/exam_frame.png
a754e1f57dbd22ba06ea57ccc84d326bc866a801e6922d28638d75dc6c005245 *./Graphics/dan_select/yellow_box/exam_gauge_box.png
7b7c40a55e76b262c1497d290ee3b457d1c3f0eae47d91f50563d011ae4b6997 *./Graphics/dan_select/yellow_box/exam_gauge.png
cafca767d283873211e2050e760c1bd135bc17d1fab8a4ec4312f602d222f3b3 *./Graphics/dan_select/yellow_box/exam_gauge_best_pill.png
c84900caf5c24158b217d2a071b3056d625d8508afc7c736ec36eb373a091a97 *./Graphics/dan_select/yellow_box/exam_gauge_box.png
8b39d7613a1d267671c38bbfc5c1295650f3f836f2d2ce326a591ccf963d5c78 *./Graphics/dan_select/yellow_box/exam_gauge.png
edd28bdb9dede112547425eda5cf99277a5d48e82fae8707fb97d76a080065f5 *./Graphics/dan_select/yellow_box/exam_header.png
3b186760910e39d5e7f2f87f1aa26037dab39116697fbe517499ade1f1e64553 *./Graphics/dan_select/yellow_box/exam_hit.png
4425a0a162803b976266e153118ca93f8a82b128ec77c6a1316f5d2544b0b7fb *./Graphics/dan_select/yellow_box/exam_judgebad.png
748b89b1d19ee060581238d824a00bea5e8dd93dc0a3118a8f34dcd1216af1c6 *./Graphics/dan_select/yellow_box/exam_judgegood.png
8a30d3014394dde6c4764f800ddf178681cc038d35e18d33dc0f2738638edcb2 *./Graphics/dan_select/yellow_box/exam_judgeperfect.png
3298eec052791aa93a1b55d4a68f0f60346885465b4382226254cdb6237f4562 *./Graphics/dan_select/yellow_box/exam_hit.png
f6a859d2565cfe7cc12d1e8ae5030a2175839505c7d4cf325f4114f517c1b068 *./Graphics/dan_select/yellow_box/exam_judgebad.png
02732c307ce94e16badb7097e4e1c00284ca0168daad756a895a7f6759e2fe66 *./Graphics/dan_select/yellow_box/exam_judgegood.png
97a88b44d48582c936f8554d962a73c3ba2f107ac93933962c605a9d29068e09 *./Graphics/dan_select/yellow_box/exam_judgeperfect.png
1ae7e1e71602e7d131df4de6bba65120437556e2245e2609d622a5f33bd71d85 *./Graphics/dan_select/yellow_box/exam_less.png
de8dc6bf524e3fee2cb1ad1af8f6b5a8d9b4ea2b7ff8ad8972ef9f3df40ef7f9 *./Graphics/dan_select/yellow_box/exam_more.png
fd5fbc75d68c3db99731f988e99a3a042dba89e848e31f461527cbeb52af7257 *./Graphics/dan_select/yellow_box/exam_percent.png
169352110d05d5edf708f9397e5e2a09610ac8bfb2c99491b2be120d140d141d *./Graphics/dan_select/yellow_box/exam_roll.png
f910fbdfa1d7a342fcfa7a6ceba1cac5a510540beb0c9ea8bb466e2d4d376d86 *./Graphics/dan_select/yellow_box/exam_score.png
e987122b780b2121c5d6fc50c38234c53fcd4dcf0fae578cf02bdcecb122130f *./Graphics/dan_select/yellow_box/exam_roll.png
9fc89499a1be002343efbcf6f57cca44be72e79fe13e027e09003e7501cff527 *./Graphics/dan_select/yellow_box/exam_score.png
07e16b16076866dde8300a6d9cc46bf39865cbf1a028a4c289fd49e838a310fd *./Graphics/dan_select/yellow_box/exam_seg_label/0.png
6d807e5bde1f182b52dbf547ca613f51725a102f91ac685827e39d3d1ac35111 *./Graphics/dan_select/yellow_box/exam_seg_label/1.png
d1f084583e4afc5a51abdd8b00ab4124205be8b4351b968a150761ad5cdd8196 *./Graphics/dan_select/yellow_box/exam_seg_label/2.png
@@ -3457,7 +3486,7 @@ aae5cba4ab39d7b29c44bb43c79ae59c6ed7ddd151c8840bfeaf2bb4d6278c3d *./Graphics/dan
ac0e5f9f354f6059ea7687a706221ff863d317f6783f854897f023a5315e8d56 *./Graphics/dan_select/yellow_box/song_label/0.png
340ea6974d9c74280d7532d6eb66b7eab2fd2634071325f4ba4654edb89d9e8e *./Graphics/dan_select/yellow_box/song_label/1.png
5839347db9c87f848fe112052938d42de85d10448df52626d27d3b39147c9bdd *./Graphics/dan_select/yellow_box/song_label/2.png
cb43d113c38c040566f05245c7259592599647754231d16de591850a0d2627eb *./Graphics/dan_select/yellow_box/texture.json
bc8541193a345e1559f59c0dc2b3ca6bcbc2c764f65ba762b315fac34af4b0ff *./Graphics/dan_select/yellow_box/texture.json
52b3b7c93ee491e74e3e4a627f77dd1b1689a58be3f0d814bf1fafc5cb101ec1 *./Graphics/dan_select/yellow_box/total_notes_bg.png
ded547deee71bf781f90e2d9c29ab2c0a8f3dbf1ec5f745a345859ebf7810184 *./Graphics/dan_select/yellow_box/total_notes_counter/0.png
caea6b27ce43889309a7d27150b37914ef64725dbd0765eab2c996839699b8d3 *./Graphics/dan_select/yellow_box/total_notes_counter/1.png
@@ -3522,9 +3551,8 @@ f9ccdaa7eb687a7deec037abce189a034408f83f2155040336a5bc121e17beef *./Graphics/gam
dd670a393e337c750fc3e04607a8f8ea2498075a91cd1c00d7c9915cf9a301e3 *./Graphics/game/balloon/bubble.png
1b0efdf1daa0df76d5ec06873459432f0b0e76c84bc895ca6ea7afd976045aaf *./Graphics/game/balloon/counter.png
1c978f85589a545109200c5a5e8cb4c8765137d942d909e22253473843f9f0d0 *./Graphics/game/balloon/pop.png
29a0a48a03ce3d76b3e975c7522151226b9a9a07f3681b2cbdc04a1f44a7660a *./Graphics/game/balloon/rainbow_mask.png
dc7b62dca2e7afebbc221e3b3762b8bd4bee5e68f57dfa09b592992e99d38b98 *./Graphics/game/balloon/rainbow.png
3c86bcd2b426717b1fe948d624e653ceebd35f7c551b6f0b3dc2c11f66fdd8a5 *./Graphics/game/balloon/texture.json
f86e7a7e054a1e1dba513f10dadd8e27f60371da71849deb51eebcf6ec786160 *./Graphics/game/balloon/texture.json
daf78148f4a1c84c7a60eef329c3a1d1aeb68433b0a26ea2ecf145aec3cd96fe *./Graphics/game/branch/expert_bg.png
87f1e3a29a1ba7b581ada4e4540614459f2bf4b346013a3d50f1c12418ba012a *./Graphics/game/branch/master_bg.png
dfe3a7225dd4deb324bc4c11bcff24c770e8b7ad2b2cff75d271bc4504a01e6b *./Graphics/game/branch/texture.json
@@ -3613,7 +3641,7 @@ d50720de35ff3221e810ad8e784fe8d7e51a74261b4ec28ff3124804abf01fac *./Graphics/gam
7411ad455a701ea3033ae48bdd19451eff4ac62f90d0b086628435b04edb59ec *./Graphics/game/dan_info/frame/5.png
3f8fcdabe54c971d4786f731647c441cb3ae22bbf125b9bc01eddc2b6ca5530c *./Graphics/game/dan_info/frame/6.png
5b5e48222e6713ec44a8a14f6eb46b2839f8cc4588953973a38c37b9e77b162d *./Graphics/game/dan_info/gauge_border_cell.png
060e1ae8a3ffcdd68fdf642a80c86263295536652c41dbf76817aacd0c0128e9 *./Graphics/game/dan_info/gauge_border_plate.png
f17f353558be8f2c6e3a3be114c03611384c1475d292e8b38bd176e60299c953 *./Graphics/game/dan_info/gauge_border_plate.png
6b0159e72495340ca85bad5fac95adab1410c81ad8ddfe5675c33d3a9866e437 *./Graphics/game/dan_info/rank_plate/0.png
6a0be1a970b16183cf8b69f7dc0cd14da5d31881cdacc0ec693fffdf257506b2 *./Graphics/game/dan_info/rank_plate/10.png
d052e74c3f374621c2453243b608d4acbb80c200c08e2c77518c619253a1cfe3 *./Graphics/game/dan_info/rank_plate/11.png
@@ -4042,11 +4070,15 @@ e77420c4531e32305746e931d0e3221173cc6d651b33329c846cf08f08bca217 *./Graphics/gam
af4cb626437fdb9e354e81858c2ae60d83e532aae2e568b6299921129d20841e *./Graphics/game/gauge/clear_ja.png
27a25757806a1bef35ef5c37ac29c1f9493bdc78728fce9d80e1e3c44117b513 *./Graphics/game/gauge_dan/1p_bar_fade.png
5334beebaf0465383e56388ab56095e59fb4663333ed31f8393c4c5eea42240d *./Graphics/game/gauge_dan/1p_bar.png
a7073f04a6f717214aabd6f60f80fde4a4656012327780ccfaa6df51b0cf6269 *./Graphics/game/gauge_dan/1p_lamp.png
75f972d21dcf46ade838ca5088cf69931ed73af66c4528cbec4de5cf168dd59e *./Graphics/game/gauge_dan/1p_unfilled.png
27a25757806a1bef35ef5c37ac29c1f9493bdc78728fce9d80e1e3c44117b513 *./Graphics/game/gauge_dan/2p_bar_fade.png
5334beebaf0465383e56388ab56095e59fb4663333ed31f8393c4c5eea42240d *./Graphics/game/gauge_dan/2p_bar.png
feee6a6b22b4fbe5fefb51a7568f1f0c9f553e37f543f5498042ab37357bd18e *./Graphics/game/gauge_dan/2p_lamp.png
aafa2152633353d49b56bc8cec3784dcc95b8e855a8573f0199c220f7b4b951c *./Graphics/game/gauge_dan/2p_unfilled.png
c0b93b68d5618c46103efe2f338affdee84f0afd82c967016640ccd347b357c5 *./Graphics/game/gauge_dan/bar_fade_clear.png
b9c2494f470dbcd1e8046b36ab4ee7b781fdd5989c03d3047140e554e9ac7079 *./Graphics/game/gauge_dan/border.png
ecf728861f1e98daff53b3cbfb5acb5c7e48c90dc0268bb1f7b82361deb1af18 *./Graphics/game/gauge_dan/lamp_clear.png
26ec11da3f7dadddd3190d248eb111d879997bf4ac2f1bbdbeb2694dbf4edf47 *./Graphics/game/gauge_dan/overlay.png
9e2a61ab12824a53a79378364611d874a1958f77331191f0b37c0fda007645bd *./Graphics/game/gauge_dan/rainbow.png
ef0b4b6c457c5ee174f9b9ccca8be313b799038be09113bc521c01d21126afbf *./Graphics/game/gauge_dan/tamashii_dark.png
@@ -4060,7 +4092,8 @@ f1f354444c95251b136b0feac381dacddcc33bd0f324a912178bfcb0cd2b9846 *./Graphics/gam
16bd30db3aa41354ccc725443d31306e221bc721f6fe4d8e31d060ce1c866c51 *./Graphics/game/gauge_dan/tamashii_fire/7.png
1370bfba37463f76ab8b8f40f308cab7b29982eacbae068fcd46df5f1e2dacd0 *./Graphics/game/gauge_dan/tamashii_overlay.png
1b80a57d99a7c80afc2271f261471059d39341301f3b4d97b208d86ecc5dce84 *./Graphics/game/gauge_dan/tamashii.png
55ccfbfc6943133a75ccf4f08d603203bb6afbcb06ae1a9487b9dc74e71c9703 *./Graphics/game/gauge_dan/texture.json
9720b853a141842433d45ae706c7e7ecec8e918b37a61cce9757e3b2fbbc9548 *./Graphics/game/gauge_dan/texture.json
15b7143bdf6632718f0b1ce429ab81a3e221429f15c7e9de48712521d7091a6f *./Graphics/game/gauge_dan/track_red.png
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/game/gauge/hit_effect_circle_big.png
e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/game/gauge/hit_effect_circle.png
8ce6d952089be1e8de286949f0287f34ad191b82d3bf3ad174d15ccb1e6232d1 *./Graphics/game/gauge/hit_effect.png
@@ -4266,7 +4299,7 @@ e0f89dc98bc3cd5e36fe43afbf3d9ce142f69be881931e0a9733700e0df30628 *./Graphics/glo
c4885df24a9c9929662146a2d2fbc83d22236e435b92d581065e51951576f126 *./Graphics/global/result_transition/texture.json
0522af352a53b2f725d7de0af7b9ca3712f9cb4040b4270f0680a61468f2a76f *./Graphics/global/timer/bg.png
8d4ac9bb885e4ccaa86e511616609401a36a46ee43e77aea805ec45472afc828 *./Graphics/global/timer/bg_red.png
8e5fdfca1cea4791973542c781e989935097b46142623d5a0a1bcfd90e8554dd *./Graphics/global/timer/counter_black.png
9e2603b145e05131c9e2989ca788df8a5edb58733c5c5bdbe5533785ce6ab6cd *./Graphics/global/timer/counter_black.png
0c3149ab950b82c4148a3e01b8c257381df6949c701788d99595becad175d5a6 *./Graphics/global/timer/counter_white.png
c26cfcc9fa8071b7345932a5cfa5d8bebb613a37128f1b3236ae410f8d1c9c85 *./Graphics/global/timer/highlight.png
b7b51ea91a604bccfd3bb05ce70f0819620f0d17bf593c0578682d3c3b810a18 *./Graphics/global/timer/texture.json
@@ -4374,7 +4407,7 @@ d21dc53600bab83b80352bad38cd598d216c6e1279a4d54a0a085ad82ad1430d *./Graphics/res
684c22481d2a0e4bb2d6dd67b5df87650e081edfeadffcc70c377c393334c06d *./Graphics/result/score/score_shinuchi_en.png
1c160a1a14016ea3a5f761b040db433420476363224011d615613af660e7d0e1 *./Graphics/result/score/score_shinuchi_ja.png
89c4d6afafb8010ec4da0b9f72f10f677ec8c87677fcb3d2c9edde923a5b5f9f *./Graphics/result/score/texture.json
546297e182cf47f1d498cf09c0dfa0bc46b162bab5fc7820077f6ee2a1003754 *./Graphics/skin_config.json
2d004f89ccc61113ccba0e0591003dec320500a9c493d641848a6d6c5240651b *./Graphics/skin_config.json
a05d23f0997446d4db2b745602bff7fc3d2cdce968a1c24e078684d41cf2982c *./Graphics/song_select/animation.json
27e427b29774e04dc739b1c58a7205565de88cea6370876b623f8e13a7106b5c *./Graphics/song_select/box/back_graphic.png
b74432db46ec6d7ec080fbee6df6029c1451e243d30813fcf597a21704de4e74 *./Graphics/song_select/box/background/0.png
@@ -4833,11 +4866,11 @@ eb2bb15e87cc83d66b320e0e4cbcbd2d5385881f36eca27fe73740439055ef6c *./Scripts/anim
5789c13c7958010f2878f9a0b119a50af4f362e754dc06ca3683ce742d507d25 *./Scripts/anim/title_idle.lua
34df97052c186c9588ff6a3c339501318c5e30ab9eecb97d1271c400ab9cfba1 *./Scripts/anim/title_idle_map.lua
66797bb60d6bacde5d882136a7dee9cda2f3e02282dd2ebaf2ee37346db14f70 *./Scripts/anim/wheel_decide.lua
5c16b475a7530f3892afb3b91499b14e0d46c1d41a946e09161a364a287d048d *./Scripts/background/background.lua
c7d27db9d4fcacba0e70d27f1abc8b31c109cb2877c15d93ed71ea850b4825b6 *./Scripts/background/background.lua
8736233c8c570fb4c1870248b07b616b4cf48528ebe269c9f06f8257edd7c9e3 *./Scripts/background/bg_collabs/a3.lua
e4ff773b74b780eb310a43053399f33a34b16885627d42c5255bafaf05d53734 *./Scripts/background/bg_collabs/animal.lua
60c12b294fff74b15c7f54001374434d3f88572129336de622a809130b1fa73d *./Scripts/background/bg_collabs/buttoburst.lua
7a20ec7bf715a91d7d4c1e53814d03a7e9b638540489b686dc6c29804a4fad03 *./Scripts/background/bg_collabs/dan.lua
21c0d0ad67c6b581da7c1fd5b6c1e5ebaff49027b21a1d33aba3e13dec003a48 *./Scripts/background/bg_collabs/dan.lua
e514657c28c18d6b913e24b416694cd9e0dc4f61d229b42e423ea62ac5ff69a3 *./Scripts/background/bg_collabs/funassyi.lua
7fa5d269efdb938c275a25e73d2cbebbad610fb49cfc6a17d8e56ad9bd3d5b41 *./Scripts/background/bg_collabs/imas.lua
d6a27cd79db76d7cdb3fcf70134fadae0679e728f2b2bd615ce4b8c465b44c28 *./Scripts/background/bg_collabs/imas_sidem.lua
@@ -4953,19 +4986,19 @@ f1abac2a469adf39ab62d4155279502382138c293159a7c89974dddba626af3c *./Scripts/back
7a46d630d24766ebcf1ed07f5e46fba051998f4a61903cd582275d787ed09202 *./Scripts/background/bg_objects/bg_anim.lua
fb9ec8d460861278976befcf2d8f523d4068cdfd1fafd9adce9ab4bc0b5816ff *./Scripts/background/bg_objects/bg_fever.lua
346175ecb1747f9d16f783ac9953efc9f6286bcf7af3565e1c35549f96e0e3d8 *./Scripts/background/bg_objects/bg_normal.lua
bc66cc31bfb3fac4483e2a1a9c04cf4d9c827ce4018c0858d0a7b162e91178f4 *./Scripts/background/bg_objects/chibi/0.lua
18417683592cb2da46d1e806a71d6c29b06d0ee695b5565a6c0d7ff5c0e4038d *./Scripts/background/bg_objects/chibi/13.lua
4ff8913ee850bd04ef2e9ce80a9d09c8ad1f13edfa253b482c200df1d142fc01 *./Scripts/background/bg_objects/chibi/2.lua
2aa954c626b4ac0472501086b9c0bcf15e92529ca5fe97ccbe080c551512641e *./Scripts/background/bg_objects/chibi/4.lua
d63b0f392c96c2d4d6ad5043d84662674cf9995ba4d5e0370e8fe1fba30ef2b0 *./Scripts/background/bg_objects/chibi/5.lua
d16d6073ebcd811905f673989e0cfa87c76a6630d96987e42a702c854ed330de *./Scripts/background/bg_objects/chibi/8.lua
7971cf8c9e8599fed0891cc1de0626e1f0f653e3733b7ed8a3fdf1dc68950ef8 *./Scripts/background/bg_objects/chibi/bad.lua
d2b0af4afd579a7e897d90c3af7128f644b9cc45464b56cbae5fae2e0abcdaa6 *./Scripts/background/bg_objects/chibi/base.lua
49addac31746a12abcc2f4e70d3b3f267027bcbeff0034adfa4d175a294869ff *./Scripts/background/bg_objects/chibi/0.lua
6c47558d9a24276cfebd88579826a04371aa3b8e57ec04468ed3f6b709261565 *./Scripts/background/bg_objects/chibi/13.lua
c7813104ce1ee52511f563231a24707c19271a4785a070c9ce06baf16f28b103 *./Scripts/background/bg_objects/chibi/2.lua
87776a26be421eb16b42971067109fcf83d54d39ea9ddb199af37b793bf13972 *./Scripts/background/bg_objects/chibi/4.lua
a99e878049c81ab7ff283da1ad6070dcedc6568ed2f6916803cb8b813bc8ccfa *./Scripts/background/bg_objects/chibi/5.lua
4510543b61d049bb4580506232d2b769ff7221aac7f7e035a05f08d5d93ea7f3 *./Scripts/background/bg_objects/chibi/8.lua
d10f75aca4a6b77642f59454cdc0a1284c5f845813439be01d928609769fd831 *./Scripts/background/bg_objects/chibi/bad.lua
8afb972cd9d5e14e7ef3d3a4061136e911e1f3686e6993aa75144cfd547756a9 *./Scripts/background/bg_objects/chibi/base.lua
d398c362848a29b81603c57dbefac089a3b2f2aea5accb43bdc76a8695ec0e37 *./Scripts/background/bg_objects/chibi.lua
6aa3e90eb09ac7a5a3ee5b6ec060958225733738d7e8116b6662e67aa010196f *./Scripts/background/bg_objects/collab_dancer_model.lua
9bfbffa09eeafc2836bac7391fdbb277899342e6f07cfe366d6f8da6701c0d3d *./Scripts/background/bg_objects/collab_parent.lua
7c753b553e1cc4fbe2e066442a812be488d20864fed6b8e0c3834a18bddddf77 *./Scripts/background/bg_objects/dancer.lua
94670a496a7cc38c0f87a3dce12384aa5875e121e576afd9d955b834e5b142f3 *./Scripts/background/bg_objects/dan_info.lua
816763b6a04858853a6519ea753f07e57a5d94d7754430caeec9f355b8ea262e *./Scripts/background/bg_objects/dan_info.lua
1ce550bce8d8d814b48847e564acb0bfae5062ecd6fa97ddc39914e8692f9569 *./Scripts/background/bg_objects/donbg/1.lua
1ce550bce8d8d814b48847e564acb0bfae5062ecd6fa97ddc39914e8692f9569 *./Scripts/background/bg_objects/donbg/2.lua
1ce550bce8d8d814b48847e564acb0bfae5062ecd6fa97ddc39914e8692f9569 *./Scripts/background/bg_objects/donbg/3.lua
@@ -5005,14 +5038,14 @@ f204455c907d3e0e7affb89db3649a709a27d528d84cc58d51a7d8cfaa1d3deb *./Scripts/back
4e17bf53815d1e586fdba5f3501d6f2d9935ad5604da871d2e7e89c87499aedd *./Scripts/background/dancer_data/dancer_3.lua
6e2b3c136611c688cdfbe44b0bbcb9d25c2ab647903246b07f2aef9baa6bab0b *./Scripts/background/dancer_data/dancer_4.lua
3a4f1f45bb54c4303dc97afcc6f67df831d6d6011a2264baed3d933c789d210e *./Scripts/background/dancer_data/dancer_5.lua
e8f58cd79a9a2fea5730eb30ecf69a1e3dedf654840a4ffa9428e8418d34f777 *./Scripts/dan_select/dan_select.lua
020f929896e3f58c27bf54881afbbf1597ebd14951b5476f9a97a29fa670e2fc *./Scripts/entry/box.lua
6544c461e406cc22deda684b65793dcf78f8c808b4b3f1556624da960321bae7 *./Scripts/dan_select/dan_select.lua
f4debb503c757b88627e9011fa835ffc41596523829b619bf56ef0b64f1c16ce *./Scripts/entry/box.lua
0a941cea73b6a81f2c92219be139a43f5902067ce468ffd189520395b4739c91 *./Scripts/entry/costume_menu.lua
83fc6c160c85a68a75d146f455cb4e18fc962c23a0020d28ac6943a1843db504 *./Scripts/entry/entry.lua
b11a395fa5c274b6294541ac0a6c24b28a5721e75af702eca02bc536a4db8f54 *./Scripts/entry/player.lua
28715aa09accbe226c477c18231d22a95d4500ca97da62a4b706d2287eeafd6c *./Scripts/entry/player.lua
8a993e86d3d6e653d47bc6d9bae67e0648ad27ae89293959c26de04869ef0219 *./Scripts/game/clip_player.lua
13f6d670d95b75abcbbddeddcb442ab32e6c32afeefc8ebf1b8bc703b57a9827 *./Scripts/game/combo_announce.lua
6d183a19e81d4d2f679c5ee20052363f47a53d64101b4354b5df6f75bb31cec7 *./Scripts/game/dan_game_draw.lua
35794daa412f028529bc75d20fdb7bef83ffbc46e96dab3c039803ba14b1741a *./Scripts/game/dan_game_draw.lua
5749994b631898c91e246110bb4b5e67aa3fdc395c4d59b49c4ee72a44e0043d *./Scripts/game/ending_anim/ending_clear.lua
33764ed8566bf003802816710a84f7bb01ef7a6ccd549b130d896f20c6e2a3b0 *./Scripts/game/ending_anim/ending_donderful.lua
1e5c509028b1a67acc2e40eed6222b51bc0e87a3d5e7eb8a4e3a3b1da4bc319b *./Scripts/game/ending_anim/ending_fail.lua
@@ -5022,7 +5055,7 @@ f4de8faceba1417bbdf0c408275f36b91022c93539178bd2d59018623bac759b *./Scripts/game
826c02cac90412a42722d0fa23e5f08878b00f32ca564607d08bd36fdecc0de4 *./Scripts/game/ending_anim/rank_hud_out.lua
6c885099876d77ea14d4588edb3de5105ecef7f8b83e2787a3bdb25918e5b920 *./Scripts/game/ending_anim/rank_result_kiwami.lua
02a2a424b68fce7b172807ce60df5c2b41121cb65f2edcc5a1e43b77702a4008 *./Scripts/game/ending_anim/rank_result.lua
8f8f0910e33b6cc90646e81c2674a3c31004106ff9fe2b38788bcd2067691ffc *./Scripts/game/gauge.lua
1a2b3f478eea7ea15a74d4142293d8731916a64f845dfbc9c4bf7d5469b38720 *./Scripts/game/gauge.lua
53ac15fdeee0ffc98670e128ff3cddc0ba66e0e8cbd91ab440628b0fd7d804ff *./Scripts/game_over/game_over.lua
6e4a0e75474a06dc9181e4c1c6de9a7cb9f5019e155d7275ce84b39712f36aeb *./Scripts/global/allnet_indicator.lua
a24e5eb9ac289325facb2fe023b16a343ef1ecf7e57cbb988bb81e2514665cf3 *./Scripts/global/coin_overlay.lua
@@ -5032,8 +5065,8 @@ b8828910262c4b19f53589abdcf1f77faa0eb2d326eb524c6b46399548c260ae *./Scripts/glob
34645d4c05dcb582ddaad6e3d2e1075c476471c81e0ce68e33f7b0bbfa3c0f2b *./Scripts/global/result_transition.lua
97bc832add42c186d57dec5bc774b9c42424051124c6e754b0a32bcf711fff21 *./Scripts/global/timer.lua
ca051ca99199e3529c85f3c5ce81d11bd763be295fed1d0bb39e33d8f5f2a3a7 *./Scripts/global/transition.lua
cba4e6940f37bb2fdd124acb9242e3147397660471a62d547d0a30ad06598a0c *./Scripts/result/bottom_characters.lua
bc1567d77db047e2473a4279bacf902d857312b6d5b005c20563ae098bc45c8c *./Scripts/result/dan_result_draw.lua
b458c0c88c2544c93f1402b7506e51c0ca47b67aee2573e130d57c20079c7260 *./Scripts/result/bottom_characters.lua
78790cf3e7388f1daed8b93e12ef03e696d6b573ad6a9c7419408b4108a17e92 *./Scripts/result/dan_result_draw.lua
5100bbdacb2464227ad50262c5c9daf56ca4ca17dc0aa121fd64bc72946dab8a *./Scripts/result/high_score_indicator.lua
be8afab142d2a20bd98b0ac22b2d5db474d0a80a5a921c0415fe482c672ee498 *./Scripts/result/result_background.lua
21ef39a4e4d3906f952922dedd590db7a210a128e7b1e9081b658735052582ef *./Scripts/result/result_bg_layers.lua
@@ -5046,7 +5079,7 @@ eeec060b381c4d06071870f40972ee1c91d2255a6a94fd1b42b3f072c112c5a4 *./Scripts/song
49d6b0e063c3afbeb304a1f60d228c2bf7229d4604f08f50ba1382049259592e *./Scripts/song_select/file_navigator/box_back.lua
57a2328d147455939ebacbcb829fdd398b20e5139dc2ea100839385db4c64aaa *./Scripts/song_select/file_navigator/box_base.lua
6bf1a5c3117ae2cdb62add55f1848ffef0b5f3969ae4ea3aa4bd708039c0bf9a *./Scripts/song_select/file_navigator/box_dan.lua
bae5f33d0431e157434fc33cd237e5012acb5b176c79ef32d4d8290e9db2200e *./Scripts/song_select/file_navigator/box_folder.lua
68d34cca0410009549749de71f1fe4abeedc8a158bd7a58201406c51dbe721c5 *./Scripts/song_select/file_navigator/box_folder.lua
89f3549fb980f615fdd052a999e6e7e4ffa6274ee4dc316e0764f237174cf03f *./Scripts/song_select/file_navigator/box_song.lua
c9ca418c0c89afd3bc317218d380edb2042716865e6c99697323dd2aa5f7cbd4 *./Scripts/song_select/modifier.lua
f1f68bd39d99da00b564167c0ba7e69582d6f0075c477cd4f3b7c41c246670a9 *./Scripts/song_select/selector.lua