add dan result screen

This commit is contained in:
Anthony Samms
2025-11-08 17:31:02 -05:00
parent 20f9f6f05a
commit d03eac9e29
9 changed files with 401 additions and 57 deletions

View File

@@ -32,6 +32,7 @@ from scenes.song_select import SongSelectScreen
from scenes.title import TitleScreen
from scenes.two_player.song_select import TwoPlayerSongSelectScreen
from scenes.dan.dan_select import DanSelectScreen
from scenes.dan.dan_result import DanResultScreen
logger = logging.getLogger(__name__)
@@ -47,6 +48,7 @@ class Screens:
SONG_SELECT_2P = "SONG_SELECT_2P"
DAN_SELECT = "DAN_SELECT"
GAME_DAN = "GAME_DAN"
DAN_RESULT = "DAN_RESULT"
SETTINGS = "SETTINGS"
DEV_MENU = "DEV_MENU"
LOADING = "LOADING"
@@ -163,6 +165,7 @@ def main():
dev_screen = DevScreen('dev')
dan_select_screen = DanSelectScreen('dan_select')
game_screen_dan = DanGameScreen('game_dan')
dan_result_screen = DanResultScreen('dan_result')
screen_mapping: dict[str, Screen] = {
Screens.ENTRY: entry_screen,
@@ -177,6 +180,7 @@ def main():
Screens.DEV_MENU: dev_screen,
Screens.DAN_SELECT: dan_select_screen,
Screens.GAME_DAN: game_screen_dan,
Screens.DAN_RESULT: dan_result_screen,
Screens.LOADING: load_screen
}
target = ray.load_render_texture(screen_width, screen_height)

View File

@@ -492,7 +492,7 @@ class YellowBox:
self._draw_text(song_box)
class DanBox:
def __init__(self, title: str, color: int, songs: list[tuple[TJAParser, int, int]], exams: list['Exam']):
def __init__(self, title: str, color: int, songs: list[tuple[TJAParser, int, int, int]], exams: list['Exam']):
self.position = -11111
self.start_position = -1
self.target_position = -1
@@ -505,7 +505,7 @@ class DanBox:
self.exams = exams
self.song_text: list[tuple[OutlinedText, OutlinedText]] = []
self.total_notes = 0
for song, genre_index, difficulty in self.songs:
for song, genre_index, difficulty, level in self.songs:
notes, branch_m, branch_e, branch_n = song.notes_to_position(difficulty)
self.total_notes += sum(1 for note in notes.play_notes if note.type < 5)
for branch in branch_m:
@@ -550,7 +550,7 @@ class DanBox:
self.name = OutlinedText(self.title, 40, ray.WHITE, vertical=True)
self.hori_name = OutlinedText(self.title, 40, ray.WHITE)
if self.is_open and not self.song_text:
for song, genre, difficulty in self.songs:
for song, genre, difficulty, level in self.songs:
title = song.metadata.title.get(global_data.config["general"]["language"], song.metadata.title["en"])
subtitle = song.metadata.subtitle.get(global_data.config["general"]["language"], "")
title_text = OutlinedText(title, 40, ray.WHITE, vertical=True)
@@ -907,7 +907,8 @@ class DanCourse(FileSystemItem):
_, genre_index, _ = parse_box_def(path.parent.parent)
else:
genre_index = 9
self.charts.append((TJAParser(path), genre_index, difficulty))
tja = TJAParser(path)
self.charts.append((tja, genre_index, difficulty, tja.metadata.course_data[difficulty].level))
else:
pass
#do something with song_title, song_subtitle

View File

@@ -90,6 +90,65 @@ class Modifiers:
inverse: bool = False
random: int = 0
@dataclass
class DanResultSong:
"""
Data class for storing dan result song data.
"""
selected_difficulty: int = 0
diff_level: int = 0
song_title: str = "default_title"
genre_index: int = 0
good: int = 0
ok: int = 0
bad: int = 0
drumroll: int = 0
class DanResultExam:
"""
Data class for storing dan result exam data.
"""
progress: float = 0
counter_value: int = 0
bar_texture: str = "exam_red"
failed: bool = False
@dataclass
class DanResultData:
"""
Data class for storing dan result data.
"""
dan_color: int = 0
dan_title: str = "default_title"
score: int = 0
gauge_length: float = 0.0
max_combo: int = 0
songs: list[DanResultSong] = field(default_factory=list)
exams: list[Any] = field(default_factory=list)
exam_data: list[DanResultExam] = field(default_factory=list)
@dataclass
class ResultData:
"""
Data class for storing result data.
result_score: The score achieved in the game.
result_good: The number of good notes achieved in the game.
result_ok: The number of ok notes achieved in the game.
result_bad: The number of bad notes achieved in the game.
result_max_combo: The maximum combo achieved in the game.
result_total_drumroll: The total drumroll achieved in the game.
result_gauge_length: The length of the gauge achieved in the game.
prev_score: The previous score pulled from the database.
"""
score: int = 0
good: int = 0
ok: int = 0
bad: int = 0
max_combo: int = 0
total_drumroll: int = 0
gauge_length: float = 0
prev_score: int = 0
@dataclass
class SessionData:
"""Data class for storing session data. Wiped after the result screen.
@@ -99,30 +158,16 @@ class SessionData:
dan_color: int: The emblem color of the selected dan
selected_difficulty: The difficulty level selected by the user.
song_title: The title of the song being played.
genre_index: The index of the genre being played.
result_score: The score achieved in the game.
result_good: The number of good notes achieved in the game.
result_ok: The number of ok notes achieved in the game.
result_bad: The number of bad notes achieved in the game.
result_max_combo: The maximum combo achieved in the game.
result_total_drumroll: The total drumroll achieved in the game.
result_gauge_length: The length of the gauge achieved in the game.
prev_score: The previous score pulled from the database."""
genre_index: The index of the genre being played."""
selected_song: Path = Path()
selected_dan: list[tuple[Any, int, int]] = field(default_factory=lambda: [])
selected_dan: list[tuple[Any, int, int, int]] = field(default_factory=lambda: [])
selected_dan_exam: list[Any] = field(default_factory=lambda: [])
dan_color: int = 0
selected_difficulty: int = 0
song_title: str = ''
song_title: str = "default_title"
genre_index: int = 0
result_score: int = 0
result_good: int = 0
result_ok: int = 0
result_bad: int = 0
result_max_combo: int = 0
result_total_drumroll: int = 0
result_gauge_length: float = 0
prev_score: int = 0
result_data: ResultData = field(default_factory=lambda: ResultData())
dan_result_data: DanResultData = field(default_factory=lambda: DanResultData())
@dataclass
class GlobalData:

View File

@@ -26,7 +26,7 @@ class Nameplate:
self.is_gold = is_gold
self.is_rainbow = is_rainbow
self.title_bg = title_bg
if self.is_rainbow == True:
if self.is_rainbow:
self.rainbow_animation = global_tex.get_animation(12)
self.rainbow_animation.start()
def update(self, current_time_ms: float):
@@ -35,7 +35,7 @@ class Nameplate:
Args:
current_time_ms (float): The current time in milliseconds.
"""
if self.is_rainbow == True:
if self.is_rainbow:
self.rainbow_animation.update(current_time_ms)
if self.rainbow_animation.is_finished:
self.rainbow_animation.restart()
@@ -60,7 +60,7 @@ class Nameplate:
else:
frame = self.title_bg
title_offset = 14
if self.is_rainbow == True:
if self.is_rainbow:
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)

View File

@@ -0,0 +1,265 @@
import logging
import pyray as ray
from libs.animation import Animation
from libs.chara_2d import Chara2D
from libs.global_data import reset_session
from libs.audio import audio
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate
from libs.screen import Screen
from libs.texture import tex
from libs.utils import (
OutlinedText,
get_current_ms,
global_data,
is_l_don_pressed,
is_r_don_pressed
)
from scenes.game import Gauge
from scenes.result import Background
logger = logging.getLogger(__name__)
class DanResultScreen(Screen):
def on_screen_start(self):
super().on_screen_start()
audio.play_sound('bgm', 'music')
self.fade_out = tex.get_animation(0)
self.coin_overlay = CoinOverlay()
self.allnet_indicator = AllNetIcon()
self.start_ms = get_current_ms()
self.background = Background('4', 1280)
self.player = DanResultPlayer(global_data.player_num)
self.is_result_2 = False
self.result_2_fade_in = tex.get_animation(1)
self.gauge = DanGauge(str(global_data.player_num), global_data.session_data[global_data.player_num-1].dan_result_data.gauge_length)
self.song_names = [OutlinedText(song.song_title, 40, ray.WHITE) for song in global_data.session_data[global_data.player_num-1].dan_result_data.songs]
self.hori_name = OutlinedText(global_data.session_data[global_data.player_num-1].dan_result_data.dan_title, 40, ray.WHITE)
self.exam_info = global_data.session_data[global_data.player_num-1].dan_result_data.exams
self.exam_data = global_data.session_data[global_data.player_num-1].dan_result_data.exam_data
print(global_data.session_data[global_data.player_num-1].dan_result_data.songs)
def on_screen_end(self, next_screen: str):
reset_session()
return super().on_screen_end(next_screen)
def handle_input(self):
if is_r_don_pressed() or is_l_don_pressed():
if self.is_result_2:
self.fade_out.start()
audio.play_sound('don', 'sound')
else:
audio.play_sound('don', 'sound')
self.result_2_fade_in.start()
self.is_result_2 = True
def update(self):
super().update()
current_time = get_current_ms()
self.player.update(current_time)
self.handle_input()
self.result_2_fade_in.update(current_time)
self.fade_out.update(current_time)
self.gauge.update(current_time)
if self.fade_out.is_finished:
self.fade_out.update(current_time)
return self.on_screen_end("DAN_SELECT")
def draw_overlay(self):
ray.draw_rectangle(0, 0, 1280, 720, ray.fade(ray.BLACK, self.fade_out.attribute))
self.coin_overlay.draw()
self.allnet_indicator.draw()
def draw_song_info_1(self):
result_data = global_data.session_data[global_data.player_num-1].dan_result_data
height = 191
for i in range(len(result_data.songs)):
song = result_data.songs[i]
tex.draw_texture('background', 'genre_banner', y=i*height, frame=song.genre_index)
self.song_names[i].draw(x=1230 - self.song_names[i].texture.width, y=i*height + 90)
tex.draw_texture('result_info', 'song_num', frame=i, y=i*height)
tex.draw_texture('result_info', 'difficulty', frame=song.selected_difficulty, y=i*height)
tex.draw_texture('result_info', 'diff_star', y=i*height)
tex.draw_texture('result_info', 'diff_x', y=i*height)
counter = str(song.diff_level)[::-1]
margin = 12
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'diff_num', frame=int(digit), x=-(j*margin), y=i*height)
tex.draw_texture('result_info', 'good', y=i*height)
margin = 24
counter = str(song.good)[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=0, frame=int(digit), x=-(j*margin), y=i*height)
tex.draw_texture('result_info', 'ok', y=i*height)
counter = str(song.ok)[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=1, frame=int(digit), x=-(j*margin), y=i*height)
tex.draw_texture('result_info', 'bad', y=i*height)
counter = str(song.bad)[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=2, frame=int(digit), x=-(j*margin), y=i*height)
tex.draw_texture('result_info', 'drumroll', y=i*height)
counter = str(song.drumroll)[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=3, frame=int(digit), x=-(j*margin), y=i*height)
def draw_song_info_2(self, fade: float):
result_data = global_data.session_data[global_data.player_num-1].dan_result_data
tex.draw_texture('background', 'result_2_bg', fade=fade)
for i in range(5):
tex.draw_texture('background', 'result_2_divider', fade=fade, x=i*240)
tex.draw_texture('background', 'result_2_pullout', fade=fade)
tex.draw_texture('result_info', 'dan_emblem', fade=fade, frame=result_data.dan_color)
self.hori_name.draw(outline_color=ray.BLACK, x=276 - (self.hori_name.texture.width//2),
y=123, x2=min(self.hori_name.texture.width, 275)-self.hori_name.texture.width, color=ray.fade(ray.WHITE, fade))
tex.draw_texture('result_info', 'good', index=1, fade=fade)
margin = 24
counter = str(sum(song.good for song in result_data.songs))[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=4, frame=int(digit), x=-(j*margin), fade=fade)
tex.draw_texture('result_info', 'ok', index=1, fade=fade)
counter = str(sum(song.ok for song in result_data.songs))[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=5, frame=int(digit), x=-(j*margin), fade=fade)
tex.draw_texture('result_info', 'bad', index=1, fade=fade)
counter = str(sum(song.bad for song in result_data.songs))[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=6, frame=int(digit), x=-(j*margin), fade=fade)
tex.draw_texture('result_info', 'drumroll', index=1, fade=fade)
counter = str(sum(song.drumroll for song in result_data.songs))[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=7, frame=int(digit), x=-(j*margin), fade=fade)
tex.draw_texture('result_info', 'max_combo', fade=fade)
counter = str(result_data.max_combo)[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=8, frame=int(digit), x=-(j*margin), fade=fade)
tex.draw_texture('result_info', 'max_hits', fade=fade)
counter = str(sum(song.drumroll + song.ok + song.bad + song.good for song in result_data.songs))[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'counter', index=9, frame=int(digit), x=-(j*margin), fade=fade)
tex.draw_texture('result_info', 'exam_header', fade=fade)
tex.draw_texture('result_info', 'score_box', fade=fade)
margin = 22
counter = str(result_data.score)[::-1]
for j, digit in enumerate(counter):
tex.draw_texture('result_info', 'score_counter', frame=int(digit), x=-(j*margin), fade=fade)
self.gauge.draw(fade)
self.draw_dan_info(fade)
if any(exam_data.failed for exam_data in self.exam_data):
tex.draw_texture('exam_info', 'fail', fade=fade)
elif all(exam_data.progress >= exam.gold for exam_data, exam in zip(self.exam_data, self.exam_info)):
tex.draw_texture('exam_info', 'gold_clear', fade=fade)
else:
tex.draw_texture('exam_info', 'red_clear', fade=fade)
def draw_dan_info(self, fade: float, scale=0.8):
# Draw exam info
for i, exam in enumerate(self.exam_info):
exam_data = self.exam_data[i]
y_offset = i * 94 * scale # Scale the y offset
tex.draw_texture('exam_info', 'exam_bg', y=y_offset, fade=fade, scale=scale)
tex.draw_texture('exam_info', 'exam_overlay_1', y=y_offset, fade=fade, scale=scale)
# Draw progress bar
tex.draw_texture('exam_info', exam_data.bar_texture, x2=940*exam_data.progress*scale, y=y_offset, fade=fade, scale=scale)
# Draw exam type and red value counter
red_counter = str(exam.red)
self._draw_counter(red_counter, margin=22*scale, texture='value_counter', index=0, y=y_offset, fade=fade, scale=scale)
tex.draw_texture('exam_info', f'exam_{exam.type}', y=y_offset, x=-len(red_counter)*20*scale, fade=fade, scale=scale)
# Draw range indicator
if exam.range == 'less':
tex.draw_texture('exam_info', 'exam_less', y=y_offset, fade=fade, scale=scale)
elif exam.range == 'more':
tex.draw_texture('exam_info', 'exam_more', y=y_offset, fade=fade, scale=scale)
# Draw current value counter
tex.draw_texture('exam_info', 'exam_overlay_2', y=y_offset, fade=fade, scale=scale)
value_counter = str(exam_data.counter_value)
self._draw_counter(value_counter, margin=22*scale, texture='value_counter', index=1, y=y_offset, fade=fade, scale=scale)
if exam.type == 'gauge':
tex.draw_texture('exam_info', 'exam_percent', y=y_offset, index=1, fade=fade, scale=scale)
if exam_data.failed:
tex.draw_texture('exam_info', 'exam_bg', fade=min(fade, 0.5), y=y_offset, scale=scale)
tex.draw_texture('exam_info', 'exam_failed', y=y_offset, fade=fade, scale=scale)
def _draw_counter(self, counter, margin, texture, index=None, y: float = 0.0, fade=0.0, scale=1.0):
"""Helper to draw digit counters"""
for j in range(len(counter)):
kwargs = {'frame': int(counter[j]), 'x': -(len(counter) - j) * margin, 'y': y, 'fade': fade, 'scale': scale}
if index is not None:
kwargs['index'] = index
tex.draw_texture('exam_info', texture, **kwargs)
def draw(self):
self.background.draw()
self.draw_song_info_1()
self.draw_song_info_2(self.result_2_fade_in.attribute)
self.player.draw()
self.draw_overlay()
class DanResultPlayer:
def __init__(self, player_num: int):
plate_info = global_data.config[f'nameplate_{player_num}p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg'])
self.chara = Chara2D(player_num-1, 100)
def update(self, current_time_ms: float):
self.nameplate.update(current_time_ms)
self.chara.update(current_time_ms, 100, False, False)
def draw(self):
self.nameplate.draw(10, 585)
self.chara.draw(0, 405)
class DanGauge(Gauge):
"""The player's gauge"""
def __init__(self, player_num: str, gauge_length: float):
self.player_num = player_num
self.gauge_length = gauge_length
self.visual_length = int(self.gauge_length * 8)
self.gauge_max = 89
self.tamashii_fire_change = tex.get_animation(25)
self.is_clear = False
self.is_rainbow = False
self.rainbow_animation = Animation.create_texture_change((16.67*8) * 3, textures=[((16.67 * 3) * i, (16.67 * 3) * (i + 1), i) for i in range(8)])
self.rainbow_animation.start()
self.rainbow_fade_in = Animation.create_fade(450, initial_opacity=0.0, final_opacity=1.0)
self.rainbow_fade_in.start()
def update(self, current_ms: float):
self.is_rainbow = self.gauge_length == self.gauge_max
self.is_clear = self.is_rainbow
self.tamashii_fire_change.update(current_ms)
self.rainbow_animation.update(current_ms)
self.rainbow_fade_in.update(current_ms)
if self.rainbow_animation.is_finished:
self.rainbow_animation.restart()
def draw(self, fade: float = 1.0):
tex.draw_texture('gauge', f'{self.player_num}p_unfilled', fade=fade)
if not self.is_rainbow:
tex.draw_texture('gauge', f'{self.player_num}p_bar', x2=self.visual_length-8, fade=fade)
# Rainbow effect for full gauge
if self.is_rainbow:
if 0 < self.rainbow_animation.attribute < 8:
tex.draw_texture('gauge', 'rainbow', frame=self.rainbow_animation.attribute-1, fade=min(self.rainbow_fade_in.attribute, fade))
tex.draw_texture('gauge', 'rainbow', frame=self.rainbow_animation.attribute, fade=min(self.rainbow_fade_in.attribute, fade))
tex.draw_texture('gauge', 'overlay', fade=min(fade, 0.15))
# Draw clear status indicators
tex.draw_texture('gauge', 'footer', fade=fade)
if self.is_rainbow:
tex.draw_texture('gauge', 'tamashii_fire', scale=0.75, center=True, frame=self.tamashii_fire_change.attribute, fade=fade)
tex.draw_texture('gauge', 'tamashii', fade=fade)
if self.is_rainbow and self.tamashii_fire_change.attribute in (0, 1, 4, 5):
tex.draw_texture('gauge', 'tamashii_overlay', fade=min(fade, 0.5))
else:
tex.draw_texture('gauge', 'tamashii_dark', fade=fade)

View File

@@ -6,7 +6,7 @@ from libs.animation import Animation
from libs.audio import audio
from libs.background import Background
from libs.file_navigator import Exam
from libs.global_data import global_data
from libs.global_data import DanResultExam, DanResultSong, global_data
from libs.global_objects import AllNetIcon
from libs.tja import TJAParser
from libs.transition import Transition
@@ -61,7 +61,7 @@ class DanGameScreen(GameScreen):
songs = copy.deepcopy(session_data.selected_dan)
self.exams = copy.deepcopy(session_data.selected_dan_exam)
self.total_notes = 0
for song, genre_index, difficulty in songs:
for song, genre_index, difficulty, level in songs:
notes, branch_m, branch_e, branch_n = song.notes_to_position(difficulty)
self.total_notes += sum(1 for note in notes.play_notes if note.type < 5)
for branch in branch_m:
@@ -70,7 +70,7 @@ class DanGameScreen(GameScreen):
self.total_notes += sum(1 for note in branch.play_notes if note.type < 5)
for branch in branch_n:
self.total_notes += sum(1 for note in branch.play_notes if note.type < 5)
song, genre_index, difficulty = songs[self.song_index]
song, genre_index, difficulty, level = songs[self.song_index]
session_data.selected_difficulty = difficulty
self.init_tja(song.file_path)
self.color = session_data.dan_color
@@ -87,7 +87,7 @@ class DanGameScreen(GameScreen):
def change_song(self):
session_data = global_data.session_data[global_data.player_num-1]
songs = session_data.selected_dan
song, genre_index, difficulty = songs[self.song_index]
song, genre_index, difficulty, level = songs[self.song_index]
session_data.selected_difficulty = difficulty
self.player_1.difficulty = difficulty
self.tja = TJAParser(song.file_path, start_delay=self.start_delay, distance=SCREEN_WIDTH - GameScreen.JUDGE_X)
@@ -174,6 +174,8 @@ class DanGameScreen(GameScreen):
@override
def spawn_ending_anims(self):
if sum(song.bad for song in global_data.session_data[global_data.player_num-1].dan_result_data.songs) == 0:
self.player_1.ending_anim = FCAnimation(self.player_1.is_2p)
if self.player_1.gauge.is_clear and not any(self.exam_failed):
self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p)
elif not self.player_1.gauge.is_clear:
@@ -201,12 +203,40 @@ class DanGameScreen(GameScreen):
if self.result_transition.is_finished and not audio.is_sound_playing('dan_transition'):
logger.info("Result transition finished, moving to RESULT screen")
return self.on_screen_end('RESULT')
return self.on_screen_end('DAN_RESULT')
elif self.current_ms >= self.player_1.end_time + 1000:
session_data = global_data.session_data[global_data.player_num-1]
if len(session_data.selected_dan) > len(session_data.dan_result_data.songs):
song_info = DanResultSong()
song_info.song_title = self.song_info.song_name
song_info.genre_index = session_data.selected_dan[self.song_index][1]
song_info.selected_difficulty = session_data.selected_dan[self.song_index][2]
song_info.diff_level = session_data.selected_dan[self.song_index][3]
prev_good_count = sum(song.good for song in session_data.dan_result_data.songs)
prev_ok_count = sum(song.ok for song in session_data.dan_result_data.songs)
prev_bad_count = sum(song.bad for song in session_data.dan_result_data.songs)
prev_drumroll_count = sum(song.drumroll for song in session_data.dan_result_data.songs)
song_info.good = self.player_1.good_count - prev_good_count
song_info.ok = self.player_1.ok_count - prev_ok_count
song_info.bad = self.player_1.bad_count - prev_bad_count
song_info.drumroll = self.player_1.total_drumroll - prev_drumroll_count
session_data.dan_result_data.songs.append(song_info)
if self.song_index == len(session_data.selected_dan) - 1:
if self.end_ms != 0:
if current_time >= self.end_ms + 1000:
session_data.dan_result_data.dan_color = self.color
session_data.dan_result_data.dan_title = self.hori_name.text
session_data.dan_result_data.score = self.player_1.score
session_data.dan_result_data.gauge_length = self.player_1.gauge.gauge_length
session_data.dan_result_data.max_combo = self.player_1.max_combo
session_data.dan_result_data.exams = self.exams
for i in range(len(self.exams)):
exam_data = DanResultExam()
exam_data.bar_texture = self.dan_info_cache["exam_data"][i]["bar_texture"]
exam_data.counter_value = self.dan_info_cache["exam_data"][i]["counter_value"]
exam_data.failed = self.exam_failed[i]
exam_data.progress = self.dan_info_cache["exam_data"][i]["progress"]
session_data.dan_result_data.exam_data.append(exam_data)
if self.player_1.ending_anim is None:
self.spawn_ending_anims()
if current_time >= self.end_ms + 8533.34:

View File

@@ -164,29 +164,29 @@ class GameScreen(Screen):
existing_score = result[0] if result is not None else None
existing_crown = result[1] if result is not None and len(result) > 1 and result[1] is not None else 0
crown = 0
if session_data.result_bad and session_data.result_ok == 0:
if session_data.result_data.bad and session_data.result_data.ok == 0:
crown = 3
elif session_data.result_bad == 0:
elif session_data.result_data.bad == 0:
crown = 2
elif self.player_1.gauge.is_clear:
crown = 1
logger.info(f"Existing score: {existing_score}, Existing crown: {existing_crown}, New score: {session_data.result_score}, New crown: {crown}")
if result is None or (existing_score is not None and session_data.result_score > existing_score):
logger.info(f"Existing score: {existing_score}, Existing crown: {existing_crown}, New score: {session_data.result_data.score}, New crown: {crown}")
if result is None or (existing_score is not None and session_data.result_data.score > existing_score):
insert_query = '''
INSERT OR REPLACE INTO Scores (hash, en_name, jp_name, diff, score, good, ok, bad, drumroll, combo, clear)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
'''
data = (hash, self.tja.metadata.title['en'],
self.tja.metadata.title.get('ja', ''), self.player_1.difficulty,
session_data.result_score, session_data.result_good,
session_data.result_ok, session_data.result_bad,
session_data.result_total_drumroll, session_data.result_max_combo, crown)
session_data.result_data.score, session_data.result_data.good,
session_data.result_data.ok, session_data.result_data.bad,
session_data.result_data.total_drumroll, session_data.result_data.max_combo, crown)
cursor.execute(insert_query, data)
session_data.prev_score = existing_score if existing_score is not None else 0
logger.info(f"Wrote score {session_data.result_score} for {self.tja.metadata.title['en']}")
session_data.result_data.prev_score = existing_score if existing_score is not None else 0
logger.info(f"Wrote score {session_data.result_data.score} for {self.tja.metadata.title['en']}")
con.commit()
if result is None or (existing_crown is not None and crown > existing_crown):
cursor.execute("UPDATE Scores SET crown = ? WHERE hash = ?", (crown, hash))
cursor.execute("UPDATE Scores SET clear = ? WHERE hash = ?", (crown, hash))
con.commit()
def start_song(self, current_time):
@@ -212,7 +212,7 @@ class GameScreen(Screen):
return self.on_screen_end('SONG_SELECT')
def spawn_ending_anims(self):
if global_data.session_data[global_data.player_num-1].result_bad == 0:
if global_data.session_data[global_data.player_num-1].result_data.bad == 0:
self.player_1.ending_anim = FCAnimation(self.player_1.is_2p)
elif self.player_1.gauge.is_clear:
self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p)
@@ -247,8 +247,8 @@ class GameScreen(Screen):
return self.on_screen_end('RESULT')
elif self.current_ms >= self.player_1.end_time:
session_data = global_data.session_data[global_data.player_num-1]
session_data.result_score, session_data.result_good, session_data.result_ok, session_data.result_bad, session_data.result_max_combo, session_data.result_total_drumroll = self.player_1.get_result_score()
session_data.result_gauge_length = self.player_1.gauge.gauge_length
session_data.result_data.score, session_data.result_data.good, session_data.result_data.ok, session_data.result_data.bad, session_data.result_data.max_combo, session_data.result_data.total_drumroll = self.player_1.get_result_score()
session_data.result_data.gauge_length = self.player_1.gauge.gauge_length
if self.end_ms != 0:
if current_time >= self.end_ms + 1000:
if self.player_1.ending_anim is None:

View File

@@ -118,20 +118,20 @@ class ResultPlayer:
self.high_score_indicator = None
self.chara = Chara2D(int(self.player_num) - 1, 100)
session_data = global_data.session_data[int(self.player_num)-1]
self.score_animator = ScoreAnimator(session_data.result_score)
self.score_animator = ScoreAnimator(session_data.result_data.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['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),
('ok', session_data.result_ok),
('bad', session_data.result_bad),
('max_combo', session_data.result_max_combo),
('total_drumroll', session_data.result_total_drumroll)]
self.update_list: list[tuple[str, int]] = [('score', session_data.result_data.score),
('good', session_data.result_data.good),
('ok', session_data.result_data.ok),
('bad', session_data.result_data.bad),
('max_combo', session_data.result_data.max_combo),
('total_drumroll', session_data.result_data.total_drumroll)]
self.update_index = 0
if session_data.result_ok == 0 and session_data.result_bad == 0:
if session_data.result_data.ok == 0 and session_data.result_data.bad == 0:
self.crown_type = 'crown_dfc'
elif session_data.result_bad == 0:
elif session_data.result_data.bad == 0:
self.crown_type = 'crown_fc'
else:
self.crown_type = 'crown_clear'
@@ -163,13 +163,13 @@ class ResultPlayer:
self.score_delay += 16.67 * 3
if self.update_index > 0 and self.high_score_indicator is None:
session_data = global_data.session_data[int(self.player_num)-1]
if session_data.result_score > session_data.prev_score:
self.high_score_indicator = HighScoreIndicator(session_data.prev_score, session_data.result_score, self.is_2p)
if session_data.result_data.score > session_data.result_data.prev_score:
self.high_score_indicator = HighScoreIndicator(session_data.result_data.prev_score, session_data.result_data.score, self.is_2p)
def update(self, current_ms: float, fade_in_finished: bool, is_skipped: bool):
self.fade_in_finished = fade_in_finished
if self.fade_in_finished and self.gauge is None:
self.gauge = Gauge(self.player_num, global_data.session_data[int(self.player_num)-1].result_gauge_length, self.is_2p)
self.gauge = Gauge(self.player_num, global_data.session_data[int(self.player_num)-1].result_data.gauge_length, self.is_2p)
self.bottom_characters.start()
self.bottom_characters.update(self.state)
self.update_score_animation(is_skipped)

View File

@@ -11,7 +11,6 @@ class TwoPlayerResultScreen(ResultScreen):
self.fade_in = FadeIn('3')
self.player_1 = ResultPlayer('1', True, False)
self.player_2 = ResultPlayer('2', True, True)
logger.info("TwoPlayerResultScreen started, background and players initialized")
def update(self):
super(ResultScreen, self).update()