Handle per-chart metadata for rgt files (and pre-empt breakage for sm files)

This commit is contained in:
Luke Hubmayer-Werner 2020-12-25 23:11:09 +10:30
parent c1188d2a72
commit 71deb80dbd
3 changed files with 74 additions and 48 deletions

View File

@ -272,8 +272,9 @@ class RGT:
chart_ids.append(line.lstrip('[').rstrip(']'))
lines.append([])
elif !line.empty():
lines[-1].append(line)
lines[-1].push_back(line)
file.close()
print('Parsing chart: ', filename)
match format:
Format.RGTS:
@ -290,15 +291,19 @@ class RGT:
return charts
return format
static func parse_rgtx(lines):
static func parse_rgtx(lines: PoolStringArray):
return [] # To be implemented later
const beats_per_measure = 4.0 # TODO: Bit of an ugly hack, need to revisit this later
static func parse_rgts(lines):
var notes = []
var slide_ids = {}
var slide_stars = {} # Multiple stars might link to one star. We only care about linking for the spin speed.
var last_star = []
static func parse_rgts(lines: PoolStringArray):
var metadata := {}
var num_taps := 0
var num_holds := 0
var num_slides := 0
var notes := []
var slide_ids := {}
var slide_stars := {} # Multiple stars might link to one star. We only care about linking for the spin speed.
var last_star := []
for i in Rules.COLS:
last_star.append(null)
@ -306,23 +311,26 @@ class RGT:
if len(line) < 4: # shortest legal line would be like '1:1t'
continue
var s = line.split(':')
var time = float(s[0]) * beats_per_measure
var note_hits = []
var note_nonhits = []
var time := float(s[0]) * beats_per_measure
var note_hits := []
var note_nonhits := []
for i in range(1, len(s)):
var n = s[i]
var column = int(n[0])
var column := int(n[0])
var ntype = n[1]
n = n.substr(2)
match ntype:
't': # tap
note_hits.append(Note.NoteTap.new(time, column))
num_taps += 1
'b': # break
note_hits.append(Note.NoteTap.new(time, column, true))
num_taps += 1
'h': # hold
var duration = float(n) * beats_per_measure
note_hits.append(Note.NoteHold.new(time, column, duration))
num_holds += 1
's': # slide star
var star = Note.NoteStar.new(time, column)
note_hits.append(star)
@ -334,6 +342,7 @@ class RGT:
var slide = Note.NoteSlide.new(time, column)
slide_ids[slide_id] = slide
note_nonhits.append(slide)
num_slides += 1
'e': # slide end
var slide_type = n[0] # numeric digit, left as str just in case
var slide_id = int(n.substr(1))
@ -359,7 +368,10 @@ class RGT:
for note in note_hits: # Set multihit on each one
note.double_hit = true
notes += note_hits + note_nonhits
return notes
metadata['num_taps'] = num_taps
metadata['num_holds'] = num_holds
metadata['num_slides'] = num_slides
return [metadata, notes]
class SM:
@ -490,14 +502,17 @@ class SM:
metadata['num_mines'] = num_mines
return [metadata, notes]
static func load_file(filename):
static func load_file(filename: String) -> Array:
# Output is [metadata, [[meta0, chart0], ..., [metaN, chartN]]]
# Technically, declarations end with a semicolon instead of a linebreak.
# This is a PITA to do correctly in GDScript and the files in our collection are well-behaved with linebreaks anyway, so we won't bother.
var file := File.new()
var err := file.open(filename, File.READ)
if err != OK:
print(err)
return err
match file.open(filename, File.READ):
OK:
pass
var err:
print_debug('Error loading file: ', err)
return []
var length = file.get_len()
var lines = [[]] # First list will be header, then every subsequent one is a chart
while (file.get_position() < (length-1)): # Could probably replace this with file.eof_reached()
@ -594,8 +609,9 @@ func load_filelist(filelist: Array, directory=''):
key += 1
'sm': # Stepmania, multiple charts
var res = SM.load_file(filename)
for k in res:
charts[k] = res[k]
for chart in res[1]:
var diff = chart[0].difficulty_str
charts[diff] = chart[1]
_:
pass
return charts
@ -652,19 +668,22 @@ func init_directory(directory: String):
func save_json(filename: String, data: Dictionary):
filename = userroot + filename
var dir = filename.rsplit('/', true, 1)[0]
var err = FileLoader.init_directory(dir)
if err != OK:
print('Error making directory for JSON file: ', err, ERROR_CODES[err])
return err
match FileLoader.init_directory(dir):
OK:
pass
var err:
print_debug('Error making directory for JSON file: ', err, ERROR_CODES[err])
return err
var json = JSON.print(data)
var file = File.new()
err = file.open(filename, File.WRITE)
if err != OK:
print('Error saving JSON file: ', err, ERROR_CODES[err])
return err
file.store_string(json)
file.close()
return OK
match file.open(filename, File.WRITE):
OK:
file.store_string(json)
file.close()
return OK
var err:
print_debug('Error saving JSON file: ', err, ERROR_CODES[err])
return err
func load_json(filename: String):
var file = File.new()

View File

@ -45,10 +45,13 @@ func save_score() -> int:
var data = {'score_data': scorescreen_score_data, 'song_key': scorescreen_song_key}
var dt = scorescreen_datetime
var filename = 'scores/%04d%02d%02dT%02d%02d%02d.json'%[dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second]
var err = FileLoader.save_json(filename, data)
if err == OK:
scorescreen_saved = true
return err
match FileLoader.save_json(filename, data):
OK:
scorescreen_saved = true
return OK
var err:
print_debug('Error saving score file %s'%filename)
return err
func load_score(filename):
var result = FileLoader.load_json('scores/%s'%filename)
@ -59,10 +62,9 @@ func load_score(filename):
for key in result.score_data:
var value = {}
for k2 in result.score_data[key]:
if k2 == 'MISS':
value[k2] = result.score_data[key][k2]
else:
value[int(k2)] = result.score_data[key][k2]
if k2 != 'MISS':
k2 = int(k2) # Could use something more robust later
value[k2] = result.score_data[key][k2]
data[int(key)] = value
scorescreen_score_data = data
scorescreen_song_key = result.song_key
@ -182,18 +184,17 @@ func _draw_chart_select(center: Vector2) -> Array:
# TODO: This is relatively expensive so we probably want to calculate this stuff once instead of every frame
var all_notes = Library.get_song_charts(selected_song_key).values()[selected_difficulty]
var chart: Array = Library.get_song_charts(selected_song_key).values()[selected_difficulty]
var all_notes: Array = chart[1]
var meta: Dictionary = chart[0]
var song_data = Library.all_songs[selected_song_key]
var note_counts = {Note.NOTE_TAP: 0, Note.NOTE_HOLD: 0, Note.NOTE_STAR: 0}
for note in all_notes:
if note.type in note_counts:
note_counts[note.type] += 1
draw_string_centered(TitleFont, Vector2(center.x-50, center.y+size+80), 'BPM:', Color(0.95, 0.95, 1.0))
draw_string_centered(TitleFont, Vector2(center.x+50, center.y+size+80), str(song_data.BPM), Color(0.95, 0.95, 1.0))
var notestrs = ['Taps:', 'Holds:', 'Slides:']
var notetypes = [0, 1, 2]
var note_counts = [meta.num_taps, meta.num_holds, meta.num_slides]
for i in len(notestrs):
draw_string_centered(TitleFont, Vector2(center.x-50, center.y+size+148+i*50), notestrs[i], Color(0.95, 0.95, 1.0))
draw_string_centered(TitleFont, Vector2(center.x+50, center.y+size+148+i*50), str(note_counts[notetypes[i]]), Color(0.95, 0.95, 1.0))
@ -206,11 +207,16 @@ func _draw_score_screen(center: Vector2) -> Array:
var touchrects = []
var songslist = genres[genres.keys()[selected_genre]]
var song_key = scorescreen_song_key
# var song_data = Library.all_songs[song_key]
var chart: Array = Library.get_song_charts(selected_song_key).values()[selected_difficulty]
var all_notes: Array = chart[1]
var meta: Dictionary = chart[0]
var x = center.x
var y = center.y - 200
var x_songtile = x - 120
var x_score = x + 120
var x2 = x - 370
var x2 = x - 360
var x_spacing = 124
var y_spacing = 42
var y1 = y
@ -223,7 +229,7 @@ func _draw_score_screen(center: Vector2) -> Array:
draw_songtile(song_key, Vector2(x_songtile-size/2.0, y), size, false, selected_difficulty, 3)
draw_string_centered(TitleFont, Vector2(x_songtile, y+size), Library.all_songs[song_key].title.n, Color(0.95, 0.95, 1.0))
var notestrs = ['Taps:', 'Holds Hit:', 'Released:', 'Stars:', 'Slides:']
var notestrs = ['Taps (%d):'%meta.num_taps, 'Holds (%d) Hit:'%meta.num_holds, 'Released:', 'Stars (%d):'%meta.num_slides, 'Slides:']
var notetypes = [0, 1, -1, 2, -2]
var note_spacing = [0.0, 1.25, 2.25, 3.5, 4.5]
var judgestrs = Array(Rules.JUDGEMENT_STRINGS + ['Miss'])
@ -248,7 +254,7 @@ func _draw_score_screen(center: Vector2) -> Array:
var note_count = 0
# var y_row = y2+y_spacing*(i+1)
var y_row = y2 + y_spacing * (note_spacing[i]+1)
draw_string_centered(TitleFont, Vector2(x2, y_row), notestrs[i], Color(0.95, 0.95, 1.0))
draw_string_centered(TitleFont, Vector2(x2-20, y_row), notestrs[i], Color(0.95, 0.95, 1.0))
for j in len(judgestrs):
var score
if j == 0:

View File

@ -518,9 +518,10 @@ func load_track(song_key: String, difficulty_idx: int):
active_notes = []
next_note_to_load = 0
all_notes = []
for note in Library.get_song_charts(song_key).values()[difficulty_idx]:
all_notes.append(Note.copy_note(note))
var data = Library.all_songs[song_key]
var chart = Library.get_song_charts(song_key).values()[difficulty_idx]
for note in chart[1]:
all_notes.append(Note.copy_note(note))
bpm = data.BPM
sync_offset_audio = data.audio_offsets[0]
sync_offset_video = data.video_offsets[0]