diff --git a/source/funkin/modding/events/ScriptEvent.hx b/source/funkin/modding/events/ScriptEvent.hx index 8d625290d..ece7870fd 100644 --- a/source/funkin/modding/events/ScriptEvent.hx +++ b/source/funkin/modding/events/ScriptEvent.hx @@ -140,16 +140,29 @@ class HitNoteScriptEvent extends NoteScriptEvent */ public var score:Int; - public function new(note:NoteSprite, healthChange:Float, score:Int, judgement:String, comboCount:Int = 0):Void + /** + * Whether the judgement caused a combo break. + */ + public var isComboBreak:Bool = false; + + /** + * The time difference when the player hit the note + */ + public var hitDiff:Float = 0; + + public function new(note:NoteSprite, healthChange:Float, score:Int, judgement:String, isComboBreak:Bool, comboCount:Int = 0, hitDiff:Float = 0):Void { super(NOTE_HIT, note, healthChange, comboCount, true); this.score = score; this.judgement = judgement; + this.isComboBreak = isComboBreak; + this.hitDiff = hitDiff; } public override function toString():String { - return 'HitNoteScriptEvent(note=' + note + ', comboCount=' + comboCount + ', judgement=' + judgement + ', score=' + score + ')'; + return 'HitNoteScriptEvent(note=' + note + ', comboCount=' + comboCount + ', judgement=' + judgement + ', score=' + score + ', isComboBreak=' + + isComboBreak + ', hitDiff=' + hitDiff + ')'; } } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 0ba4e17ec..8ba48a1b5 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2080,7 +2080,8 @@ class PlayState extends MusicBeatSubState // Call an event to allow canceling the note hit. // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', 0); + + var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', false, 0); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! @@ -2176,7 +2177,7 @@ class PlayState extends MusicBeatSubState // Call an event to allow canceling the note hit. // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', 0); + var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', false, 0); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! @@ -2381,27 +2382,40 @@ class PlayState extends MusicBeatSubState var daRating = Scoring.judgeNote(noteDiff, PBOT1); var healthChange = 0.0; + var isComboBreak = false; switch (daRating) { case 'sick': healthChange = Constants.HEALTH_SICK_BONUS; + isComboBreak = Constants.JUDGEMENT_SICK_COMBO_BREAK; case 'good': healthChange = Constants.HEALTH_GOOD_BONUS; + isComboBreak = Constants.JUDGEMENT_GOOD_COMBO_BREAK; case 'bad': healthChange = Constants.HEALTH_BAD_BONUS; + isComboBreak = Constants.JUDGEMENT_BAD_COMBO_BREAK; case 'shit': + isComboBreak = Constants.JUDGEMENT_SHIT_COMBO_BREAK; healthChange = Constants.HEALTH_SHIT_BONUS; } // Send the note hit event. - var event:HitNoteScriptEvent = new HitNoteScriptEvent(note, healthChange, score, daRating, Highscore.tallies.combo + 1); + var event:HitNoteScriptEvent = new HitNoteScriptEvent(note, healthChange, score, daRating, isComboBreak, Highscore.tallies.combo + 1, noteDiff); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! if (event.eventCanceled) return; + Highscore.tallies.totalNotesHit++; + // Display the hit on the strums + playerStrumline.hitNote(note, !isComboBreak); + if (daRating == 'sick') playerStrumline.playNoteSplash(note.noteData.getDirection()); + if (note.isHoldNote && note.holdNoteSprite != null) playerStrumline.playNoteHoldCover(note.holdNoteSprite); + vocals.playerVolume = 1; + // Display the combo meter and add the calculation to the score. - popUpScore(note, event.score, event.judgement, event.healthChange); + applyScore(event.score, event.judgement, event.healthChange, event.isComboBreak); + popUpScore(event.judgement); } /** @@ -2412,9 +2426,6 @@ class PlayState extends MusicBeatSubState { // If we are here, we already CALLED the onNoteMiss script hook! - health += healthChange; - songScore -= 10; - if (!isPracticeMode) { // messy copy paste rn lol @@ -2454,14 +2465,9 @@ class PlayState extends MusicBeatSubState } vocals.playerVolume = 0; - Highscore.tallies.missed++; + if (Highscore.tallies.combo != 0) if (Highscore.tallies.combo >= 10) comboPopUps.displayCombo(0); - if (Highscore.tallies.combo != 0) - { - // Break the combo. - if (Highscore.tallies.combo >= 10) comboPopUps.displayCombo(0); - Highscore.tallies.combo = 0; - } + applyScore(-10, 'miss', healthChange, true); if (playSound) { @@ -2593,46 +2599,24 @@ class PlayState extends MusicBeatSubState } /** - * Handles health, score, and rating popups when a note is hit. + * Handles applying health, score, and ratings. */ - function popUpScore(daNote:NoteSprite, score:Int, daRating:String, healthChange:Float):Void + function applyScore(score:Int, daRating:String, healthChange:Float, isComboBreak:Bool) { - if (daRating == 'miss') - { - // If daRating is 'miss', that means we made a mistake and should not continue. - FlxG.log.warn('popUpScore judged a note as a miss!'); - // TODO: Remove this. - // comboPopUps.displayRating('miss'); - return; - } - - vocals.playerVolume = 1; - - var isComboBreak = false; switch (daRating) { case 'sick': Highscore.tallies.sick += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_SICK_COMBO_BREAK; case 'good': Highscore.tallies.good += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_GOOD_COMBO_BREAK; case 'bad': Highscore.tallies.bad += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_BAD_COMBO_BREAK; case 'shit': Highscore.tallies.shit += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_SHIT_COMBO_BREAK; - default: - FlxG.log.error('Wuh? Buh? Guh? Note hit judgement was $daRating!'); + case 'miss': + Highscore.tallies.missed += 1; } - health += healthChange; - if (isComboBreak) { // Break the combo, but don't increment tallies.misses. @@ -2644,15 +2628,23 @@ class PlayState extends MusicBeatSubState Highscore.tallies.combo++; if (Highscore.tallies.combo > Highscore.tallies.maxCombo) Highscore.tallies.maxCombo = Highscore.tallies.combo; } - - playerStrumline.hitNote(daNote, !isComboBreak); - - if (daRating == 'sick') - { - playerStrumline.playNoteSplash(daNote.noteData.getDirection()); - } - songScore += score; + } + + /** + * Handles rating popups when a note is hit. + */ + function popUpScore(daRating:String, ?combo:Int):Void + { + if (daRating == 'miss') + { + // If daRating is 'miss', that means we made a mistake and should not continue. + FlxG.log.warn('popUpScore judged a note as a miss!'); + // TODO: Remove this. + // comboPopUps.displayRating('miss'); + return; + } + if (combo == null) combo = Highscore.tallies.combo; if (!isPracticeMode) { @@ -2692,12 +2684,7 @@ class PlayState extends MusicBeatSubState } } comboPopUps.displayRating(daRating); - if (Highscore.tallies.combo >= 10 || Highscore.tallies.combo == 0) comboPopUps.displayCombo(Highscore.tallies.combo); - - if (daNote.isHoldNote && daNote.holdNoteSprite != null) - { - playerStrumline.playNoteHoldCover(daNote.holdNoteSprite); - } + if (combo >= 10 || combo == 0) comboPopUps.displayCombo(combo); vocals.playerVolume = 1; } diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index b75cd8bf1..d28ca87d5 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -6304,7 +6304,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var tempNote:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault()); tempNote.noteData = noteData; tempNote.scrollFactor.set(0, 0); - var event:NoteScriptEvent = new HitNoteScriptEvent(tempNote, 0.0, 0, 'perfect', 0); + var event:NoteScriptEvent = new HitNoteScriptEvent(tempNote, 0.0, 0, 'perfect', false, 0); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat!