WIP: Complex slide support

Zigzags and Vs work perfectly, though might need some visual work
All of the curvy types and the triple/fan still need logic work
This commit is contained in:
Luke Hubmayer-Werner 2021-01-16 02:56:32 +10:30
parent 2c1905c850
commit 6ec02b767d
3 changed files with 59 additions and 23 deletions

View File

@ -202,14 +202,7 @@ func make_slide_trail_mesh(note) -> ArrayMesh:
vertices[i*3] = offset + uv1o vertices[i*3] = offset + uv1o
vertices[i*3+1] = offset + uv2o vertices[i*3+1] = offset + uv2o
vertices[i*3+2] = offset + uv3o vertices[i*3+2] = offset + uv3o
Note.SlideType.ARC_CW: _:
for i in trail_length:
var angle : float = note.get_angle((i+1)/float(trail_length))
var offset : Vector2 = note.get_position((i+1)/float(trail_length))
vertices[i*3] = offset + polar2cartesian(size, angle)
vertices[i*3+1] = offset + polar2cartesian(size, angle+PI/2.0)
vertices[i*3+2] = offset + polar2cartesian(size, angle-PI/2.0)
Note.SlideType.ARC_ACW:
for i in trail_length: for i in trail_length:
var angle : float = note.get_angle((i+1)/float(trail_length)) var angle : float = note.get_angle((i+1)/float(trail_length))
var offset : Vector2 = note.get_position((i+1)/float(trail_length)) var offset : Vector2 = note.get_position((i+1)/float(trail_length))

View File

@ -231,26 +231,28 @@ class RGT:
'h': Note.NOTE_HOLD, 'h': Note.NOTE_HOLD,
's': Note.NOTE_STAR, 's': Note.NOTE_STAR,
'e': Note.NOTE_SLIDE, 'e': Note.NOTE_SLIDE,
'b': Note.NOTE_TAP # Break 'b': Note.NOTE_TAP, # Break
'x': Note.NOTE_STAR # Break star
} }
const SLIDE_TYPES = { const SLIDE_TYPES = {
'0': null, # Seems to be used for stars without slides attached '0': null, # Seems to be used for stars without slides attached
'1': Note.SlideType.CHORD, '1': Note.SlideType.CHORD,
'2': Note.SlideType.ARC_ACW, # From Cirno master '2': Note.SlideType.ARC_ACW,
'3': Note.SlideType.ARC_CW, # From Cirno master '3': Note.SlideType.ARC_CW,
'4': Note.SlideType.CHORD, # Probably some weird loop etc. '4': Note.SlideType.COMPLEX, # From nekomatsuri master - Loop ACW around center. Size of loop is roughly inscribed in chords of 0-3, 1-4, 2-5... NB: doesn't loop if directly opposite col
'5': Note.SlideType.CHORD, # Probably some weird loop etc. '5': Note.SlideType.COMPLEX, # CW of above
'6': Note.SlideType.CHORD, # Probably some weird loop etc. '6': Note.SlideType.COMPLEX, # S zigzag through center
'7': Note.SlideType.CHORD, # Probably some weird loop etc. '7': Note.SlideType.COMPLEX, # Z zigzag through center
'8': Note.SlideType.CHORD, # Probably some weird loop etc. '8': Note.SlideType.COMPLEX, # V into center
'9': Note.SlideType.CHORD, # Probably some weird loop etc. '9': Note.SlideType.COMPLEX, # From nekomatsuri master - Seems to loop around to center ACW to make a + to the end
'a': Note.SlideType.CHORD, # Probably some weird loop etc. 'a': Note.SlideType.COMPLEX, # CW of above
'b': Note.SlideType.CHORD, # Probably some weird loop etc. 'b': Note.SlideType.COMPLEX, # V into column 2 places ACW
'c': Note.SlideType.CHORD, # Probably some weird loop etc. 'c': Note.SlideType.COMPLEX, # V into column 2 places CW
'd': Note.SlideType.CHORD_TRIPLE, # Triple cone. Spreads out to the adjacent receptors of the target. 'd': Note.SlideType.CHORD_TRIPLE, # Triple cone. Spreads out to the adjacent receptors of the target.
'e': Note.SlideType.CHORD, # Probably some weird loop etc. 'e': Note.SlideType.CHORD, # Not used in any of our charts
'f': Note.SlideType.CHORD, # Probably some weird loop etc. 'f': Note.SlideType.CHORD, # Not used in any of our charts
} }
const SLIDE_IN_R := sin(PI/8) # Circle radius circumscribed by chords 0-3, 1-4, 2-5 etc.
static func load_file(filename: String): static func load_file(filename: String):
var extension = filename.rsplit('.', false, 1)[1] var extension = filename.rsplit('.', false, 1)[1]
@ -353,6 +355,32 @@ class RGT:
slide_ids[slide_id].column_release = column slide_ids[slide_id].column_release = column
slide_ids[slide_id].slide_type = SLIDE_TYPES[slide_type] slide_ids[slide_id].slide_type = SLIDE_TYPES[slide_type]
slide_ids[slide_id].update_slide_variables() slide_ids[slide_id].update_slide_variables()
if SLIDE_TYPES[slide_type] == Note.SlideType.COMPLEX:
var col_hit = slide_ids[slide_id].column
var RUV = GameTheme.RADIAL_UNIT_VECTORS
slide_ids[slide_id].values.curve2d.add_point(RUV[col_hit]) # Start col
match slide_type:
'4': # TODO: Loop ACW around center. Size of loop is roughly inscribed in chords of 0-3, 1-4, 2-5... NB: doesn't loop if directly opposite col
slide_ids[slide_id].values.curve2d.add_point((RUV[posmod(col_hit-3, Rules.COLS)] + RUV[col_hit]) * 0.5)
'5': # TODO: CW of above
slide_ids[slide_id].values.curve2d.add_point((RUV[posmod(col_hit+3, Rules.COLS)] + RUV[col_hit]) * 0.5)
'6': # S zigzag through center
slide_ids[slide_id].values.curve2d.add_point(RUV[posmod(col_hit-2, Rules.COLS)] * SLIDE_IN_R)
slide_ids[slide_id].values.curve2d.add_point(RUV[posmod(col_hit+2, Rules.COLS)] * SLIDE_IN_R)
'7': # Z zigzag through center
slide_ids[slide_id].values.curve2d.add_point(RUV[posmod(col_hit+2, Rules.COLS)] * SLIDE_IN_R)
slide_ids[slide_id].values.curve2d.add_point(RUV[posmod(col_hit-2, Rules.COLS)] * SLIDE_IN_R)
'8': # V into center
slide_ids[slide_id].values.curve2d.add_point(Vector2.ZERO)
'9': # TODO: From nekomatsuri master - Seems to loop around to center ACW to make a + to the end
slide_ids[slide_id].values.curve2d.add_point(Vector2.ZERO)
'a': # TODO: CW of above
slide_ids[slide_id].values.curve2d.add_point(Vector2.ZERO)
'b': # V into column 2 places ACW
slide_ids[slide_id].values.curve2d.add_point(GameTheme.RADIAL_UNIT_VECTORS[posmod(col_hit-2, Rules.COLS)])
'c': # V into column 2 places CW
slide_ids[slide_id].values.curve2d.add_point(GameTheme.RADIAL_UNIT_VECTORS[posmod(col_hit+2, Rules.COLS)])
slide_ids[slide_id].values.curve2d.add_point(GameTheme.RADIAL_UNIT_VECTORS[column]) # End col
else: # Naked slide start else: # Naked slide start
if last_star[column] != null: if last_star[column] != null:
slide_stars[slide_id] = last_star[column] slide_stars[slide_id] = last_star[column]

View File

@ -4,7 +4,7 @@ extends Node
#class_name Note #class_name Note
enum {NOTE_TAP, NOTE_HOLD, NOTE_STAR=2, NOTE_SLIDE=-2, NOTE_TOUCH=3, NOTE_TOUCH_HOLD=4, NOTE_ARROW, NOTE_ROLL} enum {NOTE_TAP, NOTE_HOLD, NOTE_STAR=2, NOTE_SLIDE=-2, NOTE_TOUCH=3, NOTE_TOUCH_HOLD=4, NOTE_ARROW, NOTE_ROLL}
enum SlideType {CHORD, ARC_CW, ARC_ACW, CHORD_TRIPLE} enum SlideType {CHORD, ARC_CW, ARC_ACW, CHORD_TRIPLE, COMPLEX}
const DEATH_DELAY := 1.0 # This is touchy with the judgement windows and variable bpm. const DEATH_DELAY := 1.0 # This is touchy with the judgement windows and variable bpm.
const RELEASE_SCORE_TYPES := { const RELEASE_SCORE_TYPES := {
NOTE_HOLD: -NOTE_HOLD, NOTE_HOLD: -NOTE_HOLD,
@ -136,6 +136,9 @@ class NoteSlide extends NoteBase: # Fancy charts have naked slides which necess
values.end_a = GameTheme.RADIAL_COL_ANGLES[column_release] values.end_a = GameTheme.RADIAL_COL_ANGLES[column_release]
if values.end_a > values.start_a: if values.end_a > values.start_a:
values.end_a -= TAU values.end_a -= TAU
Note.SlideType.COMPLEX:
values.curve2d = Curve2D.new()
values.curve2d.bake_interval = 0.005 # TODO: play around with this
func get_position(progress: float) -> Vector2: func get_position(progress: float) -> Vector2:
match slide_type: match slide_type:
@ -147,6 +150,9 @@ class NoteSlide extends NoteBase: # Fancy charts have naked slides which necess
Note.SlideType.ARC_ACW: Note.SlideType.ARC_ACW:
var circle_angle : float = lerp(values.start_a, values.end_a, progress) var circle_angle : float = lerp(values.start_a, values.end_a, progress)
return polar2cartesian(GameTheme.receptor_ring_radius, circle_angle) return polar2cartesian(GameTheme.receptor_ring_radius, circle_angle)
Note.SlideType.COMPLEX:
progress *= values.curve2d.get_baked_length()
return values.curve2d.interpolate_baked(progress) * GameTheme.receptor_ring_radius
return Vector2(0.0, 0.0) return Vector2(0.0, 0.0)
func get_angle(progress: float) -> float: func get_angle(progress: float) -> float:
@ -159,6 +165,11 @@ class NoteSlide extends NoteBase: # Fancy charts have naked slides which necess
Note.SlideType.ARC_ACW: Note.SlideType.ARC_ACW:
var circle_angle : float = lerp(values.start_a, values.end_a, progress) var circle_angle : float = lerp(values.start_a, values.end_a, progress)
return circle_angle - PI/2.0 return circle_angle - PI/2.0
Note.SlideType.COMPLEX:
# TODO: get a better tangent maybe?
progress = clamp(progress, 0.001, 0.999) # Yes this is scuffed
var l = values.curve2d.get_baked_length()
return (values.curve2d.interpolate_baked((progress+0.001)*l) - values.curve2d.interpolate_baked((progress-0.001)*l)).angle()
return 0.0 return 0.0
func get_slide_length() -> float: func get_slide_length() -> float:
@ -170,6 +181,8 @@ class NoteSlide extends NoteBase: # Fancy charts have naked slides which necess
return fposmod(GameTheme.RADIAL_COL_ANGLES[column_release] - GameTheme.RADIAL_COL_ANGLES[column], TAU) return fposmod(GameTheme.RADIAL_COL_ANGLES[column_release] - GameTheme.RADIAL_COL_ANGLES[column], TAU)
Note.SlideType.ARC_ACW: Note.SlideType.ARC_ACW:
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)
Note.SlideType.COMPLEX:
return values.curve2d.get_baked_length()
return 0.0 return 0.0
static func copy_note(note: NoteBase): static func copy_note(note: NoteBase):
@ -184,6 +197,8 @@ static func copy_note(note: NoteBase):
newnote = NoteHold.new(note.time_hit, note.column, note.duration) newnote = NoteHold.new(note.time_hit, note.column, note.duration)
NOTE_SLIDE: NOTE_SLIDE:
newnote = NoteSlide.new(note.time_hit, note.column, note.duration, note.column_release, note.slide_type) newnote = NoteSlide.new(note.time_hit, note.column, note.duration, note.column_release, note.slide_type)
if note.slide_type == Note.SlideType.COMPLEX:
newnote.values.curve2d = note.values.curve2d
NOTE_ROLL: NOTE_ROLL:
newnote = NoteRoll.new(note.time_hit, note.column, note.duration) newnote = NoteRoll.new(note.time_hit, note.column, note.duration)
newnote.double_hit = note.double_hit newnote.double_hit = note.double_hit