From 447566dc7344f418ecf9b74c1dfd3538e7fb2e86 Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Wed, 20 Nov 2019 17:57:18 +1030 Subject: [PATCH] Judgement times are in realtime not gametime --- Note.gd | 2 +- NoteHandler.gd | 39 +++++++++++++++++++++++++++++---------- Rules.gd | 12 ++++++------ shaders/notemesh.shader | 2 +- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Note.gd b/Note.gd index 624e51e..9dfeb57 100644 --- a/Note.gd +++ b/Note.gd @@ -5,7 +5,7 @@ extends Node enum {NOTE_TAP, NOTE_HOLD, NOTE_SLIDE, NOTE_ARROW, NOTE_TOUCH, NOTE_TOUCH_HOLD} enum SlideType {CHORD, ARC_CW, ARC_ACW} -const DEATH_DELAY := 0.45 +const DEATH_DELAY := 1.0 # This is touchy with the judgement windows and variable bpm. class NoteBase: var time_hit: float diff --git a/NoteHandler.gd b/NoteHandler.gd index 2147fe5..18c658f 100644 --- a/NoteHandler.gd +++ b/NoteHandler.gd @@ -27,10 +27,13 @@ var t := 0.0 var bpm := 120.0 var sync_offset_video := 0.0 # Time in seconds to the first beat var sync_offset_audio := 0.0 # Time in seconds to the first beat + var active_notes := [] -var active_judgement_texts := [] var all_notes := [] var next_note_to_load := 0 +var active_judgement_texts := [] +var scores := {} + var slide_trail_meshes := {} var slide_trail_mesh_instances := {} @@ -76,8 +79,16 @@ const TextJudgement := { -2: TextWord.GOOD + TextStyle.ARC_EARLY, 3: TextWord.ALMOST + TextStyle.ARC_LATE, -3: TextWord.ALMOST + TextStyle.ARC_EARLY, + "MISS": TextWord.MISS + TextStyle.ARC } +func initialise_scores(): + scores = {} + for type in [Note.NOTE_TAP, Note.NOTE_HOLD, Note.NOTE_SLIDE]: + scores[type] = {} + for key in TextJudgement: + scores[type][key] = 0 + func make_text_mesh(mesh: ArrayMesh, text_id: int, pos: Vector2, angle: float, alpha:=1.0, scale:=1.0): var r := GameTheme.judge_text_size2 * scale var vertex_array := PoolVector2Array([ @@ -223,6 +234,7 @@ func make_slide_trail_mesh(note) -> ArrayMesh: #---------------------------------------------------------------------------------------------------------------------------------------------- func activate_note(note, judgement): active_judgement_texts.append({col=note.column, judgement=judgement, time=t}) + scores[note.type][judgement] += 1 note.time_activated = t match note.type: @@ -238,7 +250,7 @@ func button_pressed(col): continue if note.time_activated != INF: continue - var hit_delta = t - note.time_hit + var hit_delta = (t - note.time_hit) * 60.0/bpm # Judgement times are in seconds not gametime if hit_delta >= 0.0: if hit_delta > Rules.JUDGEMENT_TIMES_POST[-1]: continue # missed @@ -293,16 +305,16 @@ func _draw(): scale *= 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 color: PoolColorArray match note.type: Note.NOTE_TAP: - var color: PoolColorArray - if note.time_activated == INF: + if note.time_hit >= t: color = GameTheme.color_array_tap(1.0, note.double_hit) else: - color = GameTheme.color_array_tap(lerp(1.0, 0.0, (note.time_death-t)/Note.DEATH_DELAY), note.double_hit) + color = GameTheme.color_array_tap(clamp((note.time_death-t)/Note.DEATH_DELAY, 0.0, 1.0), note.double_hit) make_tap_mesh(mesh, note_center, scale, color) Note.NOTE_HOLD: - var color = GameTheme.COLOR_ARRAY_DOUBLE_8 if note.double_hit else GameTheme.COLOR_ARRAY_HOLD + color = GameTheme.COLOR_ARRAY_DOUBLE_8 if note.double_hit else GameTheme.COLOR_ARRAY_HOLD if note.is_held: color = GameTheme.COLOR_ARRAY_HOLD_HELD var position_rel : float = (t+GameTheme.note_forecast_beats-note.time_release)/GameTheme.note_forecast_beats @@ -315,7 +327,7 @@ func _draw(): var note_center_rel = (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position_rel * GameTheme.receptor_ring_radius) make_hold_mesh(mesh, note_center, note_center_rel, scale, GameTheme.RADIAL_COL_ANGLES[note.column], color) Note.NOTE_SLIDE: - var color = GameTheme.COLOR_ARRAY_DOUBLE_4 if note.double_hit else GameTheme.COLOR_ARRAY_STAR + color = GameTheme.COLOR_ARRAY_DOUBLE_4 if note.double_hit else GameTheme.COLOR_ARRAY_STAR var angle = fmod(t/note.duration, 1.0)*TAU make_star_mesh(mesh, note_center, scale, angle, color) var trail_alpha := 1.0 @@ -358,6 +370,7 @@ func _init(): Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN) GameTheme.init_radial_values() make_text_UVs() + initialise_scores() # Called when the node enters the scene tree for the first time. func _ready(): @@ -444,6 +457,7 @@ func _process(delta): get_node("/root/main/video").set_stream_position(vt_delta) # Clean out expired notes + var miss_time: float = Rules.JUDGEMENT_TIMES_POST[-1] * bpm/60.0 for i in range(len(active_notes)-1, -1, -1): var note = active_notes[i] if note.time_death < t: @@ -451,6 +465,11 @@ func _process(delta): $SlideTrailHandler.remove_child(slide_trail_mesh_instances[note.slide_id]) slide_trail_mesh_instances.erase(note.slide_id) active_notes.remove(i) + elif note.time_activated == INF: + if ((t-note.time_hit) > miss_time) and not note.missed: + active_judgement_texts.append({col=note.column, judgement="MISS", time=t}) + scores[note.type]["MISS"] += 1 + note.missed = true # Clean out expired judgement texts # By design they will always be in order so we can ignore anything past the first index @@ -480,9 +499,9 @@ func _process(delta): next_note_to_load += 1 # DEBUG: Reset after all notes are done - if (len(active_notes) < 1) and (next_note_to_load >= len(all_notes)) and (time > 10.0) and not get_node("/root/main/video").is_playing(): - time = -10.0 - next_note_to_load = 0 +# if (len(active_notes) < 1) and (next_note_to_load >= len(all_notes)) and (time > 10.0) and not get_node("/root/main/video").is_playing(): +# time = -10.0 +# next_note_to_load = 0 # Redraw $meshinstance.material.set_shader_param("screen_size", get_viewport().get_size()) diff --git a/Rules.gd b/Rules.gd index 2f586ba..913bc19 100644 --- a/Rules.gd +++ b/Rules.gd @@ -9,9 +9,9 @@ const COLS_TOUCH_ARC_DEG := 240.0/COLS const JUDGEMENT_STRINGS := ["Perfect", "Great", "Good", "Almost"] const JUDGEMENT_TIERS := 4 -const JUDGEMENT_TIMES_PRE := [0.040, 0.090, 0.135, 0.180] -const JUDGEMENT_TIMES_POST := [0.040, 0.090, 0.135, 0.180] -const JUDGEMENT_TIMES_RELEASE_PRE := [0.050, 0.090, 0.135, 0.180] -const JUDGEMENT_TIMES_RELEASE_POST := [0.100, 0.140, 0.155, 0.230] # Small grace period -const JUDGEMENT_TIMES_SLIDE_PRE := [0.090, 0.135, 0.180, 0.230] # Small grace period, sort-of -const JUDGEMENT_TIMES_SLIDE_POST := [0.090, 0.135, 0.180, 0.230] \ No newline at end of file +const JUDGEMENT_TIMES_PRE := [0.040, 0.090, 0.135, 0.175] +const JUDGEMENT_TIMES_POST := [0.040, 0.090, 0.135, 0.175] +const JUDGEMENT_TIMES_RELEASE_PRE := [0.050, 0.090, 0.135, 0.175] +const JUDGEMENT_TIMES_RELEASE_POST := [0.100, 0.140, 0.155, 0.225] # Small grace period +const JUDGEMENT_TIMES_SLIDE_PRE := [0.090, 0.135, 0.180, 0.225] # Small grace period, sort-of +const JUDGEMENT_TIMES_SLIDE_POST := [0.090, 0.135, 0.180, 0.225] \ No newline at end of file diff --git a/shaders/notemesh.shader b/shaders/notemesh.shader index 16ef3ae..3eca6db 100644 --- a/shaders/notemesh.shader +++ b/shaders/notemesh.shader @@ -42,5 +42,5 @@ void fragment() { COLOR.rgb = mix(COLOR.rgb, vec3(1.0), bright_scale); // Preserve white outlines } - COLOR.a = texture(TEXTURE, UV).a; + COLOR.a = clamp(COLOR.a*texture(TEXTURE, UV).a, 0.0, 1.0); } \ No newline at end of file