Properly clone notes from charts so that songs can be played more than once per session
This commit is contained in:
parent
c76b49fe8d
commit
f29d50b6dd
|
@ -0,0 +1,63 @@
|
||||||
|
[gd_scene load_steps=10 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://shaders/notelines.shader" type="Shader" id=1]
|
||||||
|
[ext_resource path="res://shaders/notemesh.shader" type="Shader" id=2]
|
||||||
|
[ext_resource path="res://scripts/NoteHandler.gd" type="Script" id=3]
|
||||||
|
[ext_resource path="res://assets/text-4k.png" type="Texture" id=4]
|
||||||
|
[ext_resource path="res://scripts/NotePainter.gd" type="Script" id=5]
|
||||||
|
[ext_resource path="res://scripts/NoteViewport.gd" type="Script" id=6]
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id=3]
|
||||||
|
shader = ExtResource( 2 )
|
||||||
|
shader_param/bps = null
|
||||||
|
shader_param/star_color = null
|
||||||
|
shader_param/held_color = null
|
||||||
|
shader_param/screen_size = null
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id=4]
|
||||||
|
shader = ExtResource( 1 )
|
||||||
|
shader_param/line_color = Color( 0.8, 0.8, 1, 0.8 )
|
||||||
|
shader_param/line_color_double = Color( 1, 1, 0.6, 0.9 )
|
||||||
|
shader_param/dot_color = Color( 1, 1, 1, 0.8 )
|
||||||
|
shader_param/bps = 1.0
|
||||||
|
shader_param/line_thickness = 0.012
|
||||||
|
shader_param/line_thickness_min = 0.0
|
||||||
|
shader_param/dot_thickness = 0.033
|
||||||
|
shader_param/dot_fullbright_thickness = 0.013
|
||||||
|
shader_param/max_angle = 1.0708
|
||||||
|
shader_param/max_dist = 1.25
|
||||||
|
shader_param/array_postmul = Vector3( 1, 1, 1 )
|
||||||
|
shader_param/array_sidelen = 16
|
||||||
|
shader_param/array_size = 256
|
||||||
|
|
||||||
|
[sub_resource type="CanvasItemMaterial" id=5]
|
||||||
|
blend_mode = 4
|
||||||
|
|
||||||
|
[node name="NoteHandler" type="Node2D"]
|
||||||
|
script = ExtResource( 3 )
|
||||||
|
|
||||||
|
[node name="Viewport" type="Viewport" parent="."]
|
||||||
|
size = Vector2( 540, 540 )
|
||||||
|
transparent_bg = true
|
||||||
|
usage = 1
|
||||||
|
render_target_v_flip = true
|
||||||
|
script = ExtResource( 6 )
|
||||||
|
|
||||||
|
[node name="Center" type="Node2D" parent="Viewport"]
|
||||||
|
position = Vector2( 270, 270 )
|
||||||
|
scale = Vector2( 0.5, 0.5 )
|
||||||
|
|
||||||
|
[node name="SlideTrailHandler" type="Node2D" parent="Viewport/Center"]
|
||||||
|
|
||||||
|
[node name="JudgeText" type="MeshInstance2D" parent="Viewport/Center"]
|
||||||
|
texture = ExtResource( 4 )
|
||||||
|
|
||||||
|
[node name="meshinstance" type="MeshInstance2D" parent="Viewport/Center"]
|
||||||
|
material = SubResource( 3 )
|
||||||
|
|
||||||
|
[node name="notelines" type="MeshInstance2D" parent="Viewport/Center"]
|
||||||
|
material = SubResource( 4 )
|
||||||
|
|
||||||
|
[node name="Painter" type="Node2D" parent="."]
|
||||||
|
material = SubResource( 5 )
|
||||||
|
script = ExtResource( 5 )
|
|
@ -127,7 +127,6 @@ func _input(event):
|
||||||
# write how many fingers are tapping the screen
|
# write how many fingers are tapping the screen
|
||||||
func set_fingers(value):
|
func set_fingers(value):
|
||||||
fingers = max(value, 0)
|
fingers = max(value, 0)
|
||||||
# set_text("Fingers: %d" % fingers)
|
|
||||||
|
|
||||||
func set_button_state(index: int, state: bool):
|
func set_button_state(index: int, state: bool):
|
||||||
var new_state = int(state)
|
var new_state = int(state)
|
||||||
|
|
|
@ -267,7 +267,7 @@ func _draw_score_screen(center: Vector2) -> Array:
|
||||||
total_score += note_score * notetype_weights[i]
|
total_score += note_score * notetype_weights[i]
|
||||||
total_scoremax += note_count * notetype_weights[i]
|
total_scoremax += note_count * notetype_weights[i]
|
||||||
|
|
||||||
var overall_score = total_score/total_scoremax
|
var overall_score = total_score/max(total_scoremax, 1.0)
|
||||||
var score_idx = 0
|
var score_idx = 0
|
||||||
for cutoff in Rules.SCORE_CUTOFFS:
|
for cutoff in Rules.SCORE_CUTOFFS:
|
||||||
if overall_score >= cutoff:
|
if overall_score >= cutoff:
|
||||||
|
@ -313,6 +313,7 @@ func _draw_gameplay(center: Vector2) -> Array:
|
||||||
|
|
||||||
func _draw():
|
func _draw():
|
||||||
var songs = len(Library.all_songs)
|
var songs = len(Library.all_songs)
|
||||||
|
var score_screen_filter_alpha := 0.65
|
||||||
var size = 216
|
var size = 216
|
||||||
var outline_px = 3
|
var outline_px = 3
|
||||||
var center = Vector2(540.0, 540.0-160.0) # Vector2(0.0, -160.0)
|
var center = Vector2(540.0, 540.0-160.0) # Vector2(0.0, -160.0)
|
||||||
|
@ -333,7 +334,7 @@ func _draw():
|
||||||
MenuMode.OPTIONS:
|
MenuMode.OPTIONS:
|
||||||
pass
|
pass
|
||||||
MenuMode.GAMEPLAY:
|
MenuMode.GAMEPLAY:
|
||||||
GameTheme.set_screen_filter_alpha(progress)
|
GameTheme.set_screen_filter_alpha(lerp(0.0, score_screen_filter_alpha, progress))
|
||||||
MenuMode.SCORE_SCREEN:
|
MenuMode.SCORE_SCREEN:
|
||||||
_draw_score_screen(center_prev)
|
_draw_score_screen(center_prev)
|
||||||
match menu_mode:
|
match menu_mode:
|
||||||
|
@ -362,7 +363,7 @@ func _draw():
|
||||||
GameTheme.set_screen_filter_alpha(0.0)
|
GameTheme.set_screen_filter_alpha(0.0)
|
||||||
touch_rects[menu_mode] = _draw_gameplay(center)
|
touch_rects[menu_mode] = _draw_gameplay(center)
|
||||||
MenuMode.SCORE_SCREEN:
|
MenuMode.SCORE_SCREEN:
|
||||||
GameTheme.set_screen_filter_alpha(1.0)
|
GameTheme.set_screen_filter_alpha(score_screen_filter_alpha)
|
||||||
touch_rects[menu_mode] = _draw_score_screen(center)
|
touch_rects[menu_mode] = _draw_score_screen(center)
|
||||||
ScoreText.show()
|
ScoreText.show()
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ const RELEASE_SCORE_TYPES := {
|
||||||
NOTE_ROLL: -NOTE_ROLL
|
NOTE_ROLL: -NOTE_ROLL
|
||||||
}
|
}
|
||||||
|
|
||||||
class NoteBase:
|
class NoteBase extends Resource:
|
||||||
var time_hit: float setget set_time_hit
|
var time_hit: float setget set_time_hit
|
||||||
var time_death: float
|
var time_death: float
|
||||||
var column: int
|
var column: int
|
||||||
|
@ -172,6 +172,22 @@ class NoteSlide extends NoteBase: # Fancy charts have naked slides which necess
|
||||||
return fposmod(GameTheme.RADIAL_COL_ANGLES[column] - GameTheme.RADIAL_COL_ANGLES[column_release], TAU)
|
return fposmod(GameTheme.RADIAL_COL_ANGLES[column] - GameTheme.RADIAL_COL_ANGLES[column_release], TAU)
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
|
static func copy_note(note: NoteBase):
|
||||||
|
# Honestly disappointed I couldn't find a better, more OOP solution for this.
|
||||||
|
var newnote: NoteBase
|
||||||
|
match note.type:
|
||||||
|
NOTE_TAP:
|
||||||
|
newnote = NoteTap.new(note.time_hit, note.column, note.is_break)
|
||||||
|
NOTE_STAR:
|
||||||
|
newnote = NoteStar.new(note.time_hit, note.column, note.is_break)
|
||||||
|
NOTE_HOLD:
|
||||||
|
newnote = NoteHold.new(note.time_hit, note.column, note.duration)
|
||||||
|
NOTE_SLIDE:
|
||||||
|
newnote = NoteSlide.new(note.time_hit, note.column, note.duration, note.column_release, note.slide_type)
|
||||||
|
NOTE_ROLL:
|
||||||
|
newnote = NoteRoll.new(note.time_hit, note.column, note.duration)
|
||||||
|
newnote.double_hit = note.double_hit
|
||||||
|
return newnote
|
||||||
|
|
||||||
static func make_slide(time_hit: float, duration: float, column: int, column_release: int, slide_type:=SlideType.CHORD) -> NoteSlide:
|
static func make_slide(time_hit: float, duration: float, column: int, column_release: int, slide_type:=SlideType.CHORD) -> NoteSlide:
|
||||||
return NoteSlide.new(time_hit, column, duration, column_release, slide_type)
|
return NoteSlide.new(time_hit, column, duration, column_release, slide_type)
|
||||||
|
|
|
@ -296,10 +296,6 @@ func activate_note(note, judgement):
|
||||||
match note.type:
|
match note.type:
|
||||||
Note.NOTE_HOLD:
|
Note.NOTE_HOLD:
|
||||||
note.is_held = true
|
note.is_held = true
|
||||||
Note.NOTE_SLIDE:
|
|
||||||
# Set up slide trail?
|
|
||||||
active_slide_trails.append(note)
|
|
||||||
note.progress = 0.0
|
|
||||||
|
|
||||||
func activate_note_release(note, judgement):
|
func activate_note_release(note, judgement):
|
||||||
# Only for Hold, Slide
|
# Only for Hold, Slide
|
||||||
|
@ -398,17 +394,21 @@ func _draw():
|
||||||
for note in active_notes:
|
for note in active_notes:
|
||||||
var position : float = (t+GameTheme.note_forecast_beats-note.time_hit)/GameTheme.note_forecast_beats
|
var position : float = (t+GameTheme.note_forecast_beats-note.time_hit)/GameTheme.note_forecast_beats
|
||||||
var scale := 1.0
|
var scale := 1.0
|
||||||
noteline_data.set_pixel(
|
|
||||||
i%16, i/16, Color(
|
if note.hittable:
|
||||||
position/arr_div.x,
|
noteline_data.set_pixel(
|
||||||
note.column/arr_div.y,
|
i%16, i/16, Color(
|
||||||
GameTheme.RADIAL_COL_ANGLES[note.column]/arr_div.z
|
position/arr_div.x,
|
||||||
|
note.column/arr_div.y,
|
||||||
|
GameTheme.RADIAL_COL_ANGLES[note.column]/arr_div.z
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
i += 1
|
||||||
i += 1
|
|
||||||
if position < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
if position < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
||||||
scale *= position/GameTheme.INNER_NOTE_CIRCLE_RATIO
|
scale *= position/GameTheme.INNER_NOTE_CIRCLE_RATIO
|
||||||
position = GameTheme.INNER_NOTE_CIRCLE_RATIO
|
position = GameTheme.INNER_NOTE_CIRCLE_RATIO
|
||||||
|
|
||||||
var note_center = (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position * GameTheme.receptor_ring_radius)
|
var note_center = (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position * GameTheme.receptor_ring_radius)
|
||||||
var color: PoolColorArray
|
var color: PoolColorArray
|
||||||
match note.type:
|
match note.type:
|
||||||
|
@ -491,7 +491,7 @@ func _input(event):
|
||||||
for i in range(len(active_slide_trails)-1, -1, -1):
|
for i in range(len(active_slide_trails)-1, -1, -1):
|
||||||
var note = active_slide_trails[i]
|
var note = active_slide_trails[i]
|
||||||
var center = note.get_position(note.progress)
|
var center = note.get_position(note.progress)
|
||||||
if (pos - center).length_squared() < 10000.0:
|
if (pos - center).length_squared() < Rules.SLIDE_RADIUS2:
|
||||||
note.progress += 0.09
|
note.progress += 0.09
|
||||||
if note.progress >= 1.0:
|
if note.progress >= 1.0:
|
||||||
do_slide_release(note)
|
do_slide_release(note)
|
||||||
|
@ -569,9 +569,10 @@ func load_track(song_key: String, difficulty_idx: int):
|
||||||
self.song_key = song_key
|
self.song_key = song_key
|
||||||
set_time(-3.0)
|
set_time(-3.0)
|
||||||
active_notes = []
|
active_notes = []
|
||||||
all_notes = []
|
|
||||||
next_note_to_load = 0
|
next_note_to_load = 0
|
||||||
all_notes = Library.get_song_charts(song_key).values()[difficulty_idx]
|
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 data = Library.all_songs[song_key]
|
||||||
bpm = data.BPM
|
bpm = data.BPM
|
||||||
sync_offset_audio = data.audio_offsets[0]
|
sync_offset_audio = data.audio_offsets[0]
|
||||||
|
@ -582,7 +583,7 @@ func load_track(song_key: String, difficulty_idx: int):
|
||||||
VideoPlayer.update_aspect_ratio(data.video_dimensions[0]/data.video_dimensions[1])
|
VideoPlayer.update_aspect_ratio(data.video_dimensions[0]/data.video_dimensions[1])
|
||||||
# all_notes = FileLoader.Test.stress_pattern()
|
# all_notes = FileLoader.Test.stress_pattern()
|
||||||
|
|
||||||
Note.process_note_list(all_notes)
|
Note.process_note_list(all_notes, false)
|
||||||
for note in all_notes:
|
for note in all_notes:
|
||||||
if note.type == Note.NOTE_SLIDE:
|
if note.type == Note.NOTE_SLIDE:
|
||||||
slide_trail_meshes[note.slide_id] = make_slide_trail_mesh(note)
|
slide_trail_meshes[note.slide_id] = make_slide_trail_mesh(note)
|
||||||
|
@ -670,7 +671,7 @@ func _process(delta):
|
||||||
SlideTrailHandler.remove_child(slide_trail_mesh_instances[note.slide_id])
|
SlideTrailHandler.remove_child(slide_trail_mesh_instances[note.slide_id])
|
||||||
slide_trail_mesh_instances.erase(note.slide_id)
|
slide_trail_mesh_instances.erase(note.slide_id)
|
||||||
var idx = active_slide_trails.find(note)
|
var idx = active_slide_trails.find(note)
|
||||||
if idx >= 0:
|
if idx > -1:
|
||||||
active_slide_trails.remove(idx)
|
active_slide_trails.remove(idx)
|
||||||
make_judgement_column('MISS', note.column_release)
|
make_judgement_column('MISS', note.column_release)
|
||||||
scores[Note.NOTE_SLIDE]['MISS'] += 1
|
scores[Note.NOTE_SLIDE]['MISS'] += 1
|
||||||
|
|
|
@ -13,8 +13,10 @@ const JUDGEMENT_TIMES_PRE := [0.040, 0.090, 0.125, 0.150]
|
||||||
const JUDGEMENT_TIMES_POST := [0.040, 0.090, 0.125, 0.150]
|
const JUDGEMENT_TIMES_POST := [0.040, 0.090, 0.125, 0.150]
|
||||||
const JUDGEMENT_TIMES_RELEASE_PRE := [0.040, 0.090, 0.125, 0.150]
|
const JUDGEMENT_TIMES_RELEASE_PRE := [0.040, 0.090, 0.125, 0.150]
|
||||||
const JUDGEMENT_TIMES_RELEASE_POST := [0.090, 0.140, 0.175, 0.200] # Small grace period
|
const JUDGEMENT_TIMES_RELEASE_POST := [0.090, 0.140, 0.175, 0.200] # Small grace period
|
||||||
const JUDGEMENT_TIMES_SLIDE_PRE := [0.090, 0.240, 0.375, 60.000] # Small grace period, sort-of. Just be generous, really.
|
const JUDGEMENT_TIMES_SLIDE_PRE := [0.090, 0.240, 0.4, 60.000] # Small grace period, sort-of. Just be generous, really.
|
||||||
const JUDGEMENT_TIMES_SLIDE_POST := [0.090, 0.140, 0.175, 0.200]
|
const JUDGEMENT_TIMES_SLIDE_POST := [0.090, 0.140, 0.175, 0.200]
|
||||||
|
|
||||||
const SCORE_STRINGS = ["SSS", "SS", "S", "A⁺", "A", "B⁺", "B", "C⁺", "C", "F"]
|
const SCORE_STRINGS = ["SSS", "SS", "S", "A⁺", "A", "B⁺", "B", "C⁺", "C", "F"]
|
||||||
const SCORE_CUTOFFS = [1.0, 0.975, 0.95, 0.9, 0.85, 0.8, 0.7, 0.6, 0.5]
|
const SCORE_CUTOFFS = [1.0, 0.975, 0.95, 0.9, 0.85, 0.8, 0.7, 0.6, 0.5]
|
||||||
|
|
||||||
|
const SLIDE_RADIUS2 = 10000.0 # Radius of 100px
|
||||||
|
|
Loading…
Reference in New Issue