From ac01aa63ba9feb178a9fb027b04ae6be721c57e3 Mon Sep 17 00:00:00 2001 From: somepin <79652090+somepin@users.noreply.github.com> Date: Wed, 5 Nov 2025 10:50:49 -0500 Subject: [PATCH] Implement animated rainbow nameplate and enable via config --- config.toml | 2 ++ libs/global_data.py | 1 + libs/global_objects.py | 21 +++++++++++++++++---- scenes/dan/dan_select.py | 2 +- scenes/entry.py | 5 +++-- scenes/game.py | 2 +- scenes/result.py | 2 +- scenes/song_select.py | 2 +- 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/config.toml b/config.toml index ac73c7b..a1a2c26 100644 --- a/config.toml +++ b/config.toml @@ -17,6 +17,7 @@ title = 'ドンだーデビュー!' title_bg = 0 dan = -1 gold = false +rainbow = false [nameplate_2p] name = 'かつちゃん' @@ -24,6 +25,7 @@ title = 'ドンだーデビュー!' title_bg = 1 dan = -1 gold = false +rainbow = false [paths] tja_path = ['Songs'] diff --git a/libs/global_data.py b/libs/global_data.py index 2bde4fd..4b8df98 100644 --- a/libs/global_data.py +++ b/libs/global_data.py @@ -21,6 +21,7 @@ class NameplateConfig(TypedDict): title_bg: int dan: int gold: bool + rainbow: bool class PathsConfig(TypedDict): tja_path: list[str] diff --git a/libs/global_objects.py b/libs/global_objects.py index 5088af5..078ef7e 100644 --- a/libs/global_objects.py +++ b/libs/global_objects.py @@ -7,7 +7,7 @@ from libs.audio import audio class Nameplate: """Nameplate for displaying player information.""" - def __init__(self, name: str, title: str, player_num: int, dan: int, is_gold: bool, title_bg: int): + def __init__(self, name: str, title: str, player_num: int, dan: int, is_gold: bool, is_rainbow: bool, title_bg: int): """Initialize a Nameplate object. Args: @@ -16,21 +16,29 @@ class Nameplate: player_num (int): The player's number. dan (int): The player's dan level. is_gold (bool): Whether the player's dan is gold. + is_rainbow (bool): Whether the player's nameplate background is rainbow. + title_bg (int): The player's non-rainbow nameplate background. """ self.name = OutlinedText(name, 22, ray.WHITE, outline_thickness=3.0) self.title = OutlinedText(title, 20, ray.BLACK, outline_thickness=0) self.dan_index = dan self.player_num = player_num self.is_gold = is_gold + self.is_rainbow = is_rainbow self.title_bg = title_bg + if self.is_rainbow == True: + self.rainbow_animation = global_tex.get_animation(12) + self.rainbow_animation.start() def update(self, current_time_ms: float): """Update the Nameplate object. Args: current_time_ms (float): The current time in milliseconds. - Currently unused as rainbow nameplates are not implemented. """ - pass + if self.is_rainbow == True: + self.rainbow_animation.update(current_time_ms) + if self.rainbow_animation.is_finished: + self.rainbow_animation.restart() def unload(self): """Unload the Nameplate object.""" @@ -52,7 +60,12 @@ class Nameplate: else: frame = self.title_bg title_offset = 14 - tex.draw_texture('nameplate', 'frame_top', frame=frame, x=x, y=y, fade=fade) + if self.is_rainbow == True: + if 0 < self.rainbow_animation.attribute < 6: + tex.draw_texture('nameplate', 'frame_top_rainbow', frame=self.rainbow_animation.attribute-1, x=x, y=y, fade=fade) + tex.draw_texture('nameplate', 'frame_top_rainbow', frame=self.rainbow_animation.attribute, x=x, y=y, fade=fade) + else: + tex.draw_texture('nameplate', 'frame_top', frame=frame, x=x, y=y, fade=fade) tex.draw_texture('nameplate', 'outline', x=x, y=y, fade=fade) offset = 0 if self.dan_index != -1: diff --git a/scenes/dan/dan_select.py b/scenes/dan/dan_select.py index d5da339..ccf927a 100644 --- a/scenes/dan/dan_select.py +++ b/scenes/dan/dan_select.py @@ -135,7 +135,7 @@ class DanSelectPlayer: self.chara = Chara2D(int(self.player_num) - 1, 100) plate_info = global_data.config[f'nameplate_{self.player_num}p'] self.nameplate = Nameplate(plate_info['name'], plate_info['title'], - int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['title_bg']) + int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) def update(self, current_time): """Update player state""" diff --git a/scenes/entry.py b/scenes/entry.py index 17ad986..55e4f3b 100644 --- a/scenes/entry.py +++ b/scenes/entry.py @@ -34,7 +34,7 @@ class EntryScreen(Screen): # Initial nameplate for side selection plate_info = global_data.config['nameplate_1p'] - self.nameplate = Nameplate(plate_info['name'], plate_info['title'], -1, -1, False, 0) + self.nameplate = Nameplate(plate_info['name'], plate_info['title'], -1, -1, False, False, 0) self.coin_overlay = CoinOverlay() self.allnet_indicator = AllNetIcon() @@ -102,7 +102,7 @@ class EntryScreen(Screen): audio.play_sound('don', 'sound') self.state = State.SELECT_SIDE plate_info = global_data.config['nameplate_2p'] - self.nameplate = Nameplate(plate_info['name'], plate_info['title'], -1, -1, False, 1) + self.nameplate = Nameplate(plate_info['name'], plate_info['title'], -1, -1, False, False, 1) self.chara = Chara2D(1, 100) self.side_select_fade.restart() self.side = 1 @@ -240,6 +240,7 @@ class EntryPlayer: player_num, plate_info['dan'], plate_info['gold'], + plate_info['rainbow'], plate_info['title_bg'] ) self.indicator = Indicator(Indicator.State.SELECT) diff --git a/scenes/game.py b/scenes/game.py index d4cb482..8495cb2 100644 --- a/scenes/game.py +++ b/scenes/game.py @@ -328,7 +328,7 @@ class Player: self.ending_anim: Optional[FailAnimation | ClearAnimation | FCAnimation] = None self.is_gogo_time = False plate_info = global_data.config[f'nameplate_{self.is_2p+1}p'] - self.nameplate = Nameplate(plate_info['name'], plate_info['title'], global_data.player_num, plate_info['dan'], plate_info['gold'], plate_info['title_bg']) + self.nameplate = Nameplate(plate_info['name'], plate_info['title'], global_data.player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) self.chara = Chara2D(player_number - 1, self.bpm) if global_data.config['general']['judge_counter']: self.judge_counter = JudgeCounter() diff --git a/scenes/result.py b/scenes/result.py index 0b34d67..ce600b2 100644 --- a/scenes/result.py +++ b/scenes/result.py @@ -120,7 +120,7 @@ class ResultPlayer: session_data = global_data.session_data[int(self.player_num)-1] self.score_animator = ScoreAnimator(session_data.result_score) plate_info = global_data.config[f'nameplate_{self.player_num}p'] - self.nameplate = Nameplate(plate_info['name'], plate_info['title'], int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['title_bg']) + self.nameplate = Nameplate(plate_info['name'], plate_info['title'], int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) self.score, self.good, self.ok, self.bad, self.max_combo, self.total_drumroll = '', '', '', '', '', '' self.update_list: list[tuple[str, int]] = [('score', session_data.result_score), ('good', session_data.result_good), diff --git a/scenes/song_select.py b/scenes/song_select.py index 3583991..e5d9813 100644 --- a/scenes/song_select.py +++ b/scenes/song_select.py @@ -399,7 +399,7 @@ class SongSelectPlayer: self.chara = Chara2D(int(self.player_num) - 1, 100) plate_info = global_data.config[f'nameplate_{self.player_num}p'] self.nameplate = Nameplate(plate_info['name'], plate_info['title'], - int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['title_bg']) + int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) def update(self, current_time): """Update player state"""