mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
branches work maybe idk
This commit is contained in:
18
libs/tja.py
18
libs/tja.py
@@ -751,6 +751,7 @@ class TJAParser:
|
||||
state.time_signature = float(numerator) / float(denominator)
|
||||
|
||||
def handle_scroll(self, part: str, state: ParserState):
|
||||
if state.scroll_type != ScrollType.BMSCROLL:
|
||||
if 'i' in part:
|
||||
normalized = part.replace('.i', 'j').replace('i', 'j')
|
||||
normalized = normalized.replace(',', '')
|
||||
@@ -790,7 +791,7 @@ class TJAParser:
|
||||
state.start_branch_y_scroll = state.scroll_y_modifier
|
||||
state.start_branch_barline = state.barline_display
|
||||
state.branch_balloon_index = state.balloon_index
|
||||
branch_params = part[13:]
|
||||
branch_params = part
|
||||
|
||||
def set_branch_params(bar_list: list[Note], branch_params: str, section_bar: Optional[Note]):
|
||||
if bar_list and len(bar_list) > 1:
|
||||
@@ -827,6 +828,7 @@ class TJAParser:
|
||||
|
||||
def handle_lyric(self, part: str, state: ParserState):
|
||||
timeline_obj = TimelineObject()
|
||||
timeline_obj.hit_ms = self.current_ms
|
||||
timeline_obj.lyric = part
|
||||
state.curr_timeline.append(timeline_obj)
|
||||
|
||||
@@ -891,21 +893,20 @@ class TJAParser:
|
||||
|
||||
def handle_gogostart(self, part: str, state: ParserState):
|
||||
timeline_obj = TimelineObject()
|
||||
timeline_obj.hit_ms = self.current_ms
|
||||
timeline_obj.gogo_time = True
|
||||
state.curr_timeline.append(timeline_obj)
|
||||
|
||||
def handle_gogoend(self, part: str, state: ParserState):
|
||||
timeline_obj = TimelineObject()
|
||||
timeline_obj.hit_ms = self.current_ms
|
||||
timeline_obj.gogo_time = False
|
||||
state.curr_timeline.append(timeline_obj)
|
||||
|
||||
def handle_delay(self, part: str, state: ParserState):
|
||||
delay_ms = float(part) * 1000
|
||||
if state.scroll_type == ScrollType.BMSCROLL or state.scroll_type == ScrollType.HBSCROLL:
|
||||
if delay_ms <= 0:
|
||||
# No changes if not positive
|
||||
pass
|
||||
else:
|
||||
if delay_ms > 0:
|
||||
# Do not modify current_ms, it will be modified live
|
||||
state.delay_current += delay_ms
|
||||
|
||||
@@ -927,7 +928,6 @@ class TJAParser:
|
||||
if state.sudden_moving == 0:
|
||||
state.sudden_moving = float('inf')
|
||||
|
||||
'''
|
||||
def handle_m(self, part: str, state: ParserState):
|
||||
self.branch_m.append(NoteList())
|
||||
state.curr_note_list = self.branch_m[-1].play_notes
|
||||
@@ -972,7 +972,6 @@ class TJAParser:
|
||||
state.barline_display = state.start_branch_barline
|
||||
state.balloon_index = state.branch_balloon_index
|
||||
state.is_branching = True
|
||||
'''
|
||||
|
||||
def add_bar(self, state: ParserState):
|
||||
bar_line = Note()
|
||||
@@ -1044,13 +1043,16 @@ class TJAParser:
|
||||
init_bpm.bpm = state.bpm
|
||||
state.curr_timeline.append(init_bpm)
|
||||
|
||||
state.bpmchange_last_bpm = state.bpm
|
||||
state.delay_last_note_ms = self.current_ms
|
||||
|
||||
for bar in notes:
|
||||
bar_length = sum(len(part) for part in bar if '#' not in part)
|
||||
state.barline_added = False
|
||||
|
||||
for part in bar:
|
||||
if part.startswith('#'):
|
||||
for cmd_prefix, handler in commands.items():
|
||||
for cmd_prefix, handler in sorted(commands.items(), key=lambda x: len(x[0]), reverse=True):
|
||||
if part.startswith(cmd_prefix):
|
||||
value = part[len(cmd_prefix):].strip()
|
||||
handler(value, state)
|
||||
|
||||
109
scenes/game.py
109
scenes/game.py
@@ -138,7 +138,6 @@ class GameScreen(Screen):
|
||||
self.tja = TJAParser(song, start_delay=self.start_delay)
|
||||
if self.tja.metadata.bgmovie != Path() and self.tja.metadata.bgmovie.exists():
|
||||
self.movie = VideoPlayer(self.tja.metadata.bgmovie)
|
||||
self.movie.set_volume(0.0)
|
||||
else:
|
||||
self.movie = None
|
||||
global_data.session_data[global_data.player_num].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
|
||||
@@ -214,6 +213,7 @@ class GameScreen(Screen):
|
||||
logger.info(f"Song started at {ms_from_start}")
|
||||
if self.movie is not None:
|
||||
self.movie.start(get_current_ms())
|
||||
self.movie.set_volume(0.0)
|
||||
self.song_started = True
|
||||
|
||||
def pause_song(self):
|
||||
@@ -384,6 +384,33 @@ class Player:
|
||||
self.autoplay_hit_side = Side.LEFT
|
||||
self.last_subdivision = -1
|
||||
|
||||
def get_load_time(self, note):
|
||||
note_half_w = tex.textures["notes"]["1"].width // 2
|
||||
travel_distance = tex.screen_width - GameScreen.JUDGE_X
|
||||
|
||||
base_pixels_per_ms = (note.bpm / 240000 * abs(note.scroll_x) * travel_distance * tex.screen_scale)
|
||||
|
||||
if base_pixels_per_ms == 0:
|
||||
base_pixels_per_ms = (note.bpm / 240000 * abs(note.scroll_y) * travel_distance * tex.screen_scale)
|
||||
|
||||
normal_travel_ms = (travel_distance + note_half_w) / base_pixels_per_ms
|
||||
|
||||
if not hasattr(note, "sudden_appear_ms") or not hasattr(note, "sudden_moving_ms") or note.sudden_appear_ms == float("inf"):
|
||||
note.load_ms = note.hit_ms - normal_travel_ms
|
||||
note.unload_ms = note.hit_ms + normal_travel_ms
|
||||
return
|
||||
|
||||
note.load_ms = note.hit_ms - note.sudden_appear_ms
|
||||
movement_duration = note.sudden_moving_ms
|
||||
|
||||
if movement_duration <= 0:
|
||||
movement_duration = normal_travel_ms
|
||||
|
||||
sudden_pixels_per_ms = travel_distance / movement_duration
|
||||
unload_offset = travel_distance / sudden_pixels_per_ms
|
||||
note.unload_ms = note.hit_ms + unload_offset
|
||||
|
||||
|
||||
def reset_chart(self):
|
||||
notes, self.branch_m, self.branch_e, self.branch_n = self.tja.notes_to_position(self.difficulty)
|
||||
self.play_notes, self.draw_note_list, self.draw_bar_list = apply_modifiers(notes, self.modifiers)
|
||||
@@ -417,69 +444,45 @@ class Player:
|
||||
if self.timeline and hasattr(self.timeline[self.timeline_index], 'bpm'):
|
||||
self.bpm = self.timeline[self.timeline_index].bpm
|
||||
for note in chain(self.draw_note_list, self.draw_bar_list):
|
||||
distance_x = tex.screen_width - GameScreen.JUDGE_X
|
||||
distance_y = abs(note.scroll_y * ((tex.screen_width - GameScreen.JUDGE_X)/tex.screen_width) * tex.screen_width)
|
||||
total_distance = math.sqrt(distance_x**2 + distance_y**2)
|
||||
|
||||
pixels_per_ms = note.bpm / 240000 * abs(note.scroll_x) * ((tex.screen_width - tex.textures["notes"]["1"].width//2) - GameScreen.JUDGE_X) * tex.screen_scale
|
||||
|
||||
if pixels_per_ms == 0:
|
||||
pixels_per_ms = note.bpm / 240000 * abs(note.scroll_y) * ((tex.screen_width - tex.textures["notes"]["1"].width//2) - GameScreen.JUDGE_X) * tex.screen_scale
|
||||
|
||||
if note.scroll_x >= 0:
|
||||
base_load_offset = total_distance / pixels_per_ms
|
||||
note.unload_ms = note.hit_ms + (GameScreen.JUDGE_X / pixels_per_ms)
|
||||
else:
|
||||
base_load_offset = GameScreen.JUDGE_X / pixels_per_ms
|
||||
note.unload_ms = note.hit_ms + (total_distance / pixels_per_ms)
|
||||
|
||||
if hasattr(note, 'sudden_appear_ms') and hasattr(note, 'sudden_moving_ms') and note.sudden_appear_ms != float('inf'):
|
||||
note.load_ms = note.hit_ms - note.sudden_appear_ms
|
||||
if note.scroll_x >= 0:
|
||||
note.unload_ms = note.hit_ms + note.sudden_appear_ms - note.sudden_moving_ms + (GameScreen.JUDGE_X / pixels_per_ms)
|
||||
else:
|
||||
note.unload_ms = note.hit_ms + note.sudden_appear_ms - note.sudden_moving_ms + (total_distance / pixels_per_ms)
|
||||
else:
|
||||
note.load_ms = note.hit_ms - base_load_offset
|
||||
self.get_load_time(note)
|
||||
|
||||
self.draw_note_list = deque(sorted(self.draw_note_list, key=lambda n: n.load_ms))
|
||||
self.draw_bar_list = deque(sorted(self.draw_bar_list, key=lambda n: n.load_ms))
|
||||
|
||||
# Handle HBSCROLL, BMSCROLL (pre-modify hit_ms, so that notes can't be literally hit, but are still visually different) - basically it applies the transformations of #BPMCHANGE and #DELAY to hit_ms, so that notes can't be hit even if its visaulyl
|
||||
for i, o in enumerate(self.timeline):
|
||||
if hasattr(o, 'bpmchange'):
|
||||
hit_ms = o.hit_ms
|
||||
bpmchange = o.bpmchange
|
||||
for note in chain(self.play_notes, self.current_bars, self.draw_bar_list):
|
||||
for note in chain(self.draw_note_list, self.draw_bar_list):
|
||||
if note.hit_ms > hit_ms:
|
||||
note.hit_ms = (note.hit_ms - hit_ms) / bpmchange + hit_ms
|
||||
for i2 in range(i + 1, len(self.timeline)):
|
||||
o2 = self.timeline[i2]
|
||||
if not hasattr(o2, 'bpmchange'):
|
||||
continue
|
||||
o2.hit_ms = (o2.hit_ms - hit_ms) / bpmchange + hit_ms
|
||||
elif hasattr(o, 'delay'):
|
||||
hit_ms = o.hit_ms
|
||||
delay = o.delay
|
||||
for note in chain(self.play_notes, self.current_bars, self.draw_bar_list):
|
||||
for note in chain(self.draw_note_list, self.draw_bar_list):
|
||||
if note.hit_ms > hit_ms:
|
||||
note.hit_ms += delay
|
||||
for i2 in range(i + 1, len(self.timeline)):
|
||||
o2 = self.timeline[i2]
|
||||
if not hasattr(o2, 'delay'):
|
||||
continue
|
||||
o2.hit_ms += delay
|
||||
|
||||
# Decide end_time after all transforms have been applied
|
||||
self.end_time = 0
|
||||
if self.play_notes:
|
||||
self.end_time = self.play_notes[-1].hit_ms
|
||||
if self.branch_m:
|
||||
for section in self.branch_m:
|
||||
if section.play_notes:
|
||||
self.end_time = max(self.end_time, section.play_notes[-1].hit_ms)
|
||||
if self.branch_e:
|
||||
for section in self.branch_e:
|
||||
if section.play_notes:
|
||||
self.end_time = max(self.end_time, section.play_notes[-1].hit_ms)
|
||||
if self.branch_n:
|
||||
for section in self.branch_n:
|
||||
self.end_time = self.play_notes[-1].hit_ms if self.play_notes else 0
|
||||
|
||||
for branch in (self.branch_m, self.branch_e, self.branch_n):
|
||||
if branch:
|
||||
for section in branch:
|
||||
for note in section.draw_notes or []:
|
||||
self.get_load_time(note)
|
||||
for note in section.bars or []:
|
||||
self.get_load_time(note)
|
||||
if section.play_notes:
|
||||
self.end_time = max(self.end_time, section.play_notes[-1].hit_ms)
|
||||
|
||||
@@ -504,11 +507,15 @@ class Player:
|
||||
return self.score, self.good_count, self.ok_count, self.bad_count, self.max_combo, self.total_drumroll
|
||||
|
||||
def get_position_x(self, note, current_ms):
|
||||
if self.delay_start:
|
||||
current_ms = self.delay_start
|
||||
speedx = note.bpm / 240000 * note.scroll_x * (tex.screen_width - GameScreen.JUDGE_X) * tex.screen_scale
|
||||
return GameScreen.JUDGE_X + (note.hit_ms - current_ms) * speedx
|
||||
|
||||
|
||||
def get_position_y(self, note, current_ms):
|
||||
if self.delay_start:
|
||||
current_ms = self.delay_start
|
||||
speedy = note.bpm / 240000 * note.scroll_y * ((tex.screen_width - GameScreen.JUDGE_X)/tex.screen_width) * tex.screen_width
|
||||
return (note.hit_ms - current_ms) * speedy
|
||||
|
||||
@@ -589,25 +596,15 @@ class Player:
|
||||
timeline_object = self.timeline[self.timeline_index]
|
||||
should_advance = False
|
||||
|
||||
'''
|
||||
if hasattr(timeline_object, 'bpmchange') and timeline_object.hit_ms <= current_ms:
|
||||
hit_ms = timeline_object.hit_ms
|
||||
bpmchange = timeline_object.bpmchange
|
||||
# Adjust notes (visually)
|
||||
for note in chain(self.play_notes, self.current_bars, self.draw_bar_list):
|
||||
# Already modified
|
||||
# note.hit_ms = (note.hit_ms - hit_ms) / bpmchange + hit_ms
|
||||
# time_diff * note.pixels_per_frame need to be the same before and after the adjustment
|
||||
# that means time_diff should be divided by self.bpmchange.bpmchange
|
||||
# current_ms = self.bpmchange.hit_ms
|
||||
time_diff = note.load_ms - hit_ms
|
||||
note.load_ms = time_diff / bpmchange + hit_ms
|
||||
for note in chain(self.current_notes_draw, self.current_bars, self.draw_note_list, self.draw_bar_list):
|
||||
note.bpm *= bpmchange
|
||||
self.get_load_time(note)
|
||||
|
||||
note.pixels_per_frame_x *= bpmchange
|
||||
note.pixels_per_frame_y *= bpmchange
|
||||
self.bpm *= bpmchange
|
||||
should_advance = True
|
||||
'''
|
||||
|
||||
if hasattr(timeline_object, 'delay') and timeline_object.hit_ms <= current_ms:
|
||||
hit_ms = timeline_object.hit_ms
|
||||
@@ -666,7 +663,6 @@ class Player:
|
||||
logger.info(f'branch condition measures started with conditions {self.branch_condition}, {e_req}, {m_req}, {self.current_bars[-1].hit_ms}')
|
||||
if not self.is_branch:
|
||||
self.is_branch = True
|
||||
'''
|
||||
if self.branch_condition == 'r':
|
||||
end_time = self.branch_m[0].bars[0].load_ms
|
||||
end_roll = -1
|
||||
@@ -706,7 +702,6 @@ class Player:
|
||||
seen_notes.add(note)
|
||||
|
||||
self.curr_branch_reqs = [e_req, m_req, branch_start_time, max(len(seen_notes), 1)]
|
||||
'''
|
||||
def play_note_manager(self, current_ms: float, background: Optional[Background]):
|
||||
"""Manages the play_notes and removes if necessary"""
|
||||
if self.don_notes and self.don_notes[0].hit_ms + Player.TIMING_BAD < current_ms:
|
||||
@@ -1099,7 +1094,6 @@ class Player:
|
||||
self.animation_manager(self.draw_drum_hit_list, current_time)
|
||||
self.get_judge_position(ms_from_start)
|
||||
self.handle_scroll_type_commands(ms_from_start)
|
||||
'''
|
||||
if self.delay_start is not None and self.delay_end is not None:
|
||||
# Currently, a delay is active: notes should be frozen at ms = delay_start
|
||||
# Check if it ended
|
||||
@@ -1109,7 +1103,6 @@ class Player:
|
||||
note.load_ms += delay
|
||||
self.delay_start = None
|
||||
self.delay_end = None
|
||||
'''
|
||||
self.update_bpm(ms_from_start)
|
||||
|
||||
# More efficient arc management
|
||||
|
||||
Reference in New Issue
Block a user