bug fixes

This commit is contained in:
Anthony Samms
2025-12-15 10:24:06 -05:00
parent 1ef4d10ed6
commit 1c88e3ab31
5 changed files with 76 additions and 52 deletions

View File

@@ -48,10 +48,8 @@ class BaseChibi:
textures = [((duration / len(self.keyframes))*i, (duration / len(self.keyframes))*(i+1), index) for i, index in enumerate(self.keyframes)] textures = [((duration / len(self.keyframes))*i, (duration / len(self.keyframes))*(i+1), index) for i, index in enumerate(self.keyframes)]
self.texture_change = Animation.create_texture_change(duration, textures=textures) self.texture_change = Animation.create_texture_change(duration, textures=textures)
self.texture_change.start() self.texture_change.start()
self.hori_move = Animation.create_move(60000 / self.bpm * 5, total_distance=self.tex.screen_width) self.hori_move.duration = 60000 / self.bpm * 5
self.hori_move.start() self.vert_move.duration = 60000 / self.bpm / 2
self.vert_move = Animation.create_move(60000 / self.bpm / 2, total_distance=50 * self.tex.screen_scale, reverse_delay=0)
self.vert_move.start()
def draw(self, tex: TextureWrapper): def draw(self, tex: TextureWrapper):
tex.draw_texture(self.name, str(self.index), frame=self.texture_change.attribute, x=self.hori_move.attribute, y=-self.vert_move.attribute+(self.is_2p*tex.skin_config["game_2p_offset"].y)) tex.draw_texture(self.name, str(self.index), frame=self.texture_change.attribute, x=self.hori_move.attribute, y=-self.vert_move.attribute+(self.is_2p*tex.skin_config["game_2p_offset"].y))

View File

@@ -1157,7 +1157,6 @@ class FileNavigator:
content_items.append(self.all_song_files[song_key]) content_items.append(self.all_song_files[song_key])
self.directory_contents[dir_key] = content_items self.directory_contents[dir_key] = content_items
self.crown_cache_dirty.add(dir_key)
else: else:
# For directories without box.def, still process their children # For directories without box.def, still process their children
@@ -1374,22 +1373,56 @@ class FileNavigator:
def _calculate_directory_crowns(self, dir_key: str, tja_files: list): def _calculate_directory_crowns(self, dir_key: str, tja_files: list):
"""Pre-calculate crowns for a directory""" """Pre-calculate crowns for a directory"""
all_scores = dict() all_scores = dict()
crowns = dict() child_has_any_crown = [] # Track if each child has been played at all
for song_obj in tja_files: for item in tja_files:
if not isinstance(song_obj, SongFile): has_crown = False
continue if isinstance(item, SongFile):
for diff in song_obj.box.scores: has_crown = any((item.box.scores.get(d) or (None,)*6)[5] is not None
for d in [Difficulty.EASY, Difficulty.NORMAL, Difficulty.HARD, Difficulty.ONI])
for diff in item.box.scores:
if diff not in all_scores: if diff not in all_scores:
all_scores[diff] = [] all_scores[diff] = []
all_scores[diff].append(song_obj.box.scores[diff]) all_scores[diff].append(item.box.scores[diff])
elif isinstance(item, Directory):
child_key = str(item.path)
child_crowns = self._get_directory_crowns_cached(child_key)
has_crown = bool(child_crowns) # Directory is "played" if it has any crowns
if not child_crowns:
# Unplayed directory - add None for all difficulties
for diff in [Difficulty.EASY, Difficulty.NORMAL, Difficulty.HARD, Difficulty.ONI]:
if diff not in all_scores:
all_scores[diff] = []
all_scores[diff].append((None, None, None, None, None, None))
else:
# Played directory - add its crowns
for diff in [Difficulty.EASY, Difficulty.NORMAL, Difficulty.HARD, Difficulty.ONI]:
if diff not in all_scores:
all_scores[diff] = []
if diff in child_crowns:
all_scores[diff].append((None, None, None, None, None, child_crowns[diff]))
else:
# This directory doesn't have this difficulty, but it's been played
# Don't add anything - this child doesn't count for this difficulty
pass
child_has_any_crown.append(has_crown)
# If ANY child is completely unplayed, no crowns at all
if not all(child_has_any_crown):
self.directory_crowns[dir_key] = {}
return
crowns = {}
for diff in all_scores: for diff in all_scores:
if all(score is not None and score[5] == Crown.DFC for score in all_scores[diff]): if any(score is None or score[5] is None for score in all_scores[diff]):
continue
if all(score[5] == Crown.DFC for score in all_scores[diff]):
crowns[diff] = Crown.DFC crowns[diff] = Crown.DFC
elif all(score is not None and score[5] == Crown.FC for score in all_scores[diff]): elif all(score[5] == Crown.FC for score in all_scores[diff]):
crowns[diff] = Crown.FC crowns[diff] = Crown.FC
elif all(score is not None and score[5] >= Crown.CLEAR for score in all_scores[diff]): elif all(score[5] >= Crown.CLEAR for score in all_scores[diff]):
crowns[diff] = Crown.CLEAR crowns[diff] = Crown.CLEAR
self.directory_crowns[dir_key] = crowns self.directory_crowns[dir_key] = crowns

View File

@@ -3,6 +3,7 @@ import logging
import json import json
import sqlite3 import sqlite3
import time import time
import csv
from pathlib import Path from pathlib import Path
from libs.global_data import Crown from libs.global_data import Crown
@@ -69,10 +70,12 @@ def build_song_hashes(output_dir=Path("cache")):
if output_path.exists(): if output_path.exists():
with open(output_path, "r", encoding="utf-8") as f: with open(output_path, "r", encoding="utf-8") as f:
song_hashes = json.load(f, cls=DiffHashesDecoder) song_hashes = json.load(f, cls=DiffHashesDecoder)
'''
for hash in song_hashes: for hash in song_hashes:
entry = song_hashes[hash][0] entry = song_hashes[hash][0]
for diff in entry["diff_hashes"]: for diff in entry["diff_hashes"]:
db_updates.append((entry["diff_hashes"][diff], entry["title"]["en"], entry["title"].get("ja", ""), int(diff))) db_updates.append((entry["diff_hashes"][diff], entry["title"]["en"], entry["title"].get("ja", ""), int(diff)))
'''
if index_path.exists(): if index_path.exists():
with open(index_path, "r", encoding="utf-8") as f: with open(index_path, "r", encoding="utf-8") as f:
@@ -111,7 +114,6 @@ def build_song_hashes(output_dir=Path("cache")):
del song_hashes[current_hash] del song_hashes[current_hash]
del path_to_hash[tja_path_str] del path_to_hash[tja_path_str]
# Process only files that need updating
song_count = 0 song_count = 0
total_songs = len(files_to_process) total_songs = len(files_to_process)
if total_songs > 0: if total_songs > 0:
@@ -167,7 +169,7 @@ def build_song_hashes(output_dir=Path("cache")):
# Prepare database updates for each difficulty # Prepare database updates for each difficulty
en_name = tja.metadata.title.get('en', '') if isinstance(tja.metadata.title, dict) else str(tja.metadata.title) en_name = tja.metadata.title.get('en', '') if isinstance(tja.metadata.title, dict) else str(tja.metadata.title)
jp_name = tja.metadata.title.get('jp', '') if isinstance(tja.metadata.title, dict) else '' jp_name = tja.metadata.title.get('ja', '') if isinstance(tja.metadata.title, dict) else ''
score_ini_path = tja_path.with_suffix('.tja.score.ini') score_ini_path = tja_path.with_suffix('.tja.score.ini')
if score_ini_path.exists(): if score_ini_path.exists():
@@ -319,7 +321,6 @@ def process_tja_file(tja_file):
hash = tja.hash_note_data(all_notes) hash = tja.hash_note_data(all_notes)
return hash return hash
'''
def get_japanese_songs_for_version(csv_file_path, version_column): def get_japanese_songs_for_version(csv_file_path, version_column):
# Read CSV file and filter rows where the specified version column has 'YES' # Read CSV file and filter rows where the specified version column has 'YES'
version_songs = [] version_songs = []
@@ -398,13 +399,17 @@ def get_japanese_songs_for_version(csv_file_path, version_column):
if len(matches) == 1: if len(matches) == 1:
path = matches[0][1] path = matches[0][1]
elif len(matches) > 1: elif len(matches) > 1:
logger.info( print(
f"Multiple matches found for '{title.split('')[0]} ({title.split('')[1] if len(title.split('')) > 1 else ''})':" f"Multiple matches found for '{title.split('')[0]} ({title.split('')[1] if len(title.split('')) > 1 else ''})':"
) )
for i, (key, path_val) in enumerate(matches, 1): for i, (key, path_val) in enumerate(matches, 1):
logger.info(f"{i}. {key}: {path_val}") print(f"{i}. {key}: {path_val}")
choice = int(input("Choose number: ")) - 1 choice = input("Choose number: ")
if choice.isdigit():
choice = int(choice) - 1
path = matches[choice][1] path = matches[choice][1]
else:
path = Path(choice)
else: else:
path = Path(input(f"NOT FOUND {title}: ")) path = Path(input(f"NOT FOUND {title}: "))
hash = process_tja_file(path) hash = process_tja_file(path)
@@ -415,7 +420,7 @@ def get_japanese_songs_for_version(csv_file_path, version_column):
text_files[genre].append( text_files[genre].append(
f"{hash}|{tja_parse.metadata.title['en'].strip()}|{tja_parse.metadata.subtitle['en'].strip()}" f"{hash}|{tja_parse.metadata.title['en'].strip()}|{tja_parse.metadata.subtitle['en'].strip()}"
) )
logger.info(f"Added {title}: {path}") print(f"Added {title}: {path}")
for genre in text_files: for genre in text_files:
if not Path(version_column).exists(): if not Path(version_column).exists():
Path(version_column).mkdir() Path(version_column).mkdir()
@@ -431,6 +436,9 @@ def get_japanese_songs_for_version(csv_file_path, version_column):
return text_files return text_files
if len(sys.argv) > 1: '''
get_japanese_songs_for_version(sys.argv[1], sys.argv[2]) versions = ['AC6']
for version in versions:
print(version)
get_japanese_songs_for_version('full.csv', version)
''' '''

View File

@@ -649,24 +649,7 @@ class Player:
self.is_branch = True self.is_branch = True
if self.branch_condition == 'r': if self.branch_condition == 'r':
end_time = self.branch_m[0].bars[0].load_ms end_time = self.branch_m[0].bars[0].load_ms
end_roll = -1 self.curr_branch_reqs = [e_req, m_req, end_time, 1]
note_lists = [
self.other_notes,
self.branch_m[0].play_notes if self.branch_m else [],
self.branch_e[0].play_notes if self.branch_e else [],
self.branch_n[0].play_notes if self.branch_n else [],
]
end_roll = -1
for notes in note_lists:
for i in range(len(notes)-1, -1, -1):
if notes[i].type == NoteType.TAIL and notes[i].hit_ms <= end_time:
end_roll = notes[i].hit_ms
break
if end_roll != -1:
break
self.curr_branch_reqs = [e_req, m_req, end_roll, 1]
elif self.branch_condition == 'p': elif self.branch_condition == 'p':
start_time = self.current_bars[0].hit_ms if self.current_bars else self.current_bars[-1].hit_ms start_time = self.current_bars[0].hit_ms if self.current_bars else self.current_bars[-1].hit_ms
branch_start_time = self.branch_m[0].bars[0].load_ms branch_start_time = self.branch_m[0].bars[0].load_ms
@@ -827,7 +810,7 @@ class Player:
if drum_type != DrumType.DON: if drum_type != DrumType.DON:
return return
if note.is_kusudama: if note.is_kusudama:
self.check_kusudama(note) self.check_kusudama(note, current_time)
return return
if self.balloon_anim is None: if self.balloon_anim is None:
self.balloon_anim = BalloonAnimation(current_time, note.count, self.player_num, self.is_2p) self.balloon_anim = BalloonAnimation(current_time, note.count, self.player_num, self.is_2p)
@@ -843,7 +826,7 @@ class Player:
self.note_correct(note, current_time) self.note_correct(note, current_time)
self.curr_balloon_count = 0 self.curr_balloon_count = 0
def check_kusudama(self, note: Balloon): def check_kusudama(self, note: Balloon, current_time: float):
"""Checks if the player has popped a kusudama""" """Checks if the player has popped a kusudama"""
if self.kusudama_anim is None: if self.kusudama_anim is None:
self.kusudama_anim = KusudamaAnimation(note.count) self.kusudama_anim = KusudamaAnimation(note.count)
@@ -855,6 +838,7 @@ class Player:
audio.play_sound('kusudama_pop', 'hitsound') audio.play_sound('kusudama_pop', 'hitsound')
self.is_balloon = False self.is_balloon = False
note.popped = True note.popped = True
self.kusudama_anim.update(current_time, note.popped)
self.curr_balloon_count = 0 self.curr_balloon_count = 0
def check_note(self, ms_from_start: float, drum_type: DrumType, current_time: float, background: Optional[Background]): def check_note(self, ms_from_start: float, drum_type: DrumType, current_time: float, background: Optional[Background]):
@@ -876,7 +860,7 @@ class Player:
self.check_drumroll(drum_type, background, current_time) self.check_drumroll(drum_type, background, current_time)
elif self.is_balloon: elif self.is_balloon:
if not isinstance(curr_note, Balloon): if not isinstance(curr_note, Balloon):
raise Exception("Balloon mode entered but current note is not balloon") return
self.check_balloon(drum_type, curr_note, current_time) self.check_balloon(drum_type, curr_note, current_time)
else: else:
self.curr_drumroll_count = 0 self.curr_drumroll_count = 0

View File

@@ -686,12 +686,13 @@ class SongSelectPlayer:
def draw_background_diffs(self, state: int): def draw_background_diffs(self, state: int):
if (self.selected_song and state == State.SONG_SELECTED and self.selected_difficulty >= Difficulty.EASY): if (self.selected_song and state == State.SONG_SELECTED and self.selected_difficulty >= Difficulty.EASY):
if self.player_num == PlayerNum.P2: if self.player_num == PlayerNum.P2:
tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, fade=min(0.5, self.selected_diff_fadein.attribute), x=1025, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute) x_offset = 1025 * tex.screen_scale
tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, fade=min(0.5, self.selected_diff_fadein.attribute), x=x_offset, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute)
if self.selected_diff_highlight_fade.is_reversing or self.selected_diff_highlight_fade.is_finished: if self.selected_diff_highlight_fade.is_reversing or self.selected_diff_highlight_fade.is_finished:
tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, x=1025, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute) tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, x=x_offset, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute)
tex.draw_texture('global', 'background_diff_highlight', frame=min(Difficulty.ONI, self.selected_difficulty), fade=self.selected_diff_highlight_fade.attribute, x=1025) tex.draw_texture('global', 'background_diff_highlight', frame=min(Difficulty.ONI, self.selected_difficulty), fade=self.selected_diff_highlight_fade.attribute, x=x_offset)
tex.draw_texture('global', 'bg_diff_text_bg', x=1025, fade=min(0.5, self.selected_diff_text_fadein.attribute), scale=self.selected_diff_text_resize.attribute, center=True) tex.draw_texture('global', 'bg_diff_text_bg', x=x_offset, fade=min(0.5, self.selected_diff_text_fadein.attribute), scale=self.selected_diff_text_resize.attribute, center=True)
tex.draw_texture('global', 'bg_diff_text', frame=min(Difficulty.ONI, self.selected_difficulty), x=1025, fade=self.selected_diff_text_fadein.attribute, scale=self.selected_diff_text_resize.attribute, center=True) tex.draw_texture('global', 'bg_diff_text', frame=min(Difficulty.ONI, self.selected_difficulty), x=x_offset, fade=self.selected_diff_text_fadein.attribute, scale=self.selected_diff_text_resize.attribute, center=True)
else: else:
tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, fade=min(0.5, self.selected_diff_fadein.attribute), y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute) tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, fade=min(0.5, self.selected_diff_fadein.attribute), y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute)
if self.selected_diff_highlight_fade.is_reversing or self.selected_diff_highlight_fade.is_finished: if self.selected_diff_highlight_fade.is_reversing or self.selected_diff_highlight_fade.is_finished: