public virtual void NotePlayed(double hitTimestamp, NoteScore noteScore) { noteScore.hitOffset = hitTimestamp - noteScore.timestamp; pendingNoteScores.Remove(noteScore); noteScores.Add(noteScore); }
private NoteScore GetClosestNote(double hitTimestamp, int lane, NoteJudgeType judgeType) { NoteScore closestNote = null; double closestDiff = double.MaxValue; foreach (NoteScore noteScore in pendingNoteScores) { if (!judgeType.HasFlag(noteScore.judgeType)) { continue; } if (noteScore.noteEvent.lane != lane) { continue; } double diff = Math.Abs(noteScore.timestamp - hitTimestamp); if (diff >= closestDiff) { continue; } closestNote = noteScore; closestDiff = diff; } return(closestNote); }
public void OnKeyPress(int lane, NoteEvent pressNote = null) { double hitTimestamp = judgeTime; NoteScore closestNote = GetClosestNote(hitTimestamp, lane, NoteJudgeType.JudgePress | NoteJudgeType.JudgeHold); if (closestNote == null) { return; } JudgeNote(hitTimestamp, closestNote); }
public override void UpdateSong() { base.UpdateSong(); for (int i = 0; i < pendingNoteScores.Count; i++) { NoteScore noteScore = pendingNoteScores[i]; if (judgeTime > noteScore.timestamp + missWindow) { JudgeNote(judgeTime, noteScore); } else { break; } } }
public void OnKeyRelease(int lane, NoteEvent pressNote = null) { double hitTimestamp = judgeTime; NoteScore closestNote = GetClosestNote(hitTimestamp, lane, NoteJudgeType.JudgeRelease); if (closestNote == null) { return; } if (!HasJudged((closestNote.noteEvent as LongNoteEndEvent).startNote)) { // ignore key releases before long note starting point return; } JudgeNote(hitTimestamp, closestNote); }
public abstract void JudgeNote(double hitTimestamp, NoteScore noteScore);
public override void JudgeNote(double hitTimestamp, NoteScore noteScore) { double difference; if (truncateTiming) // truncate to 1ms accuracy { difference = ((int)(hitTimestamp * 1000) - (int)(noteScore.timestamp * 1000)) / 1000.0; } else { difference = hitTimestamp - noteScore.timestamp; } bool fast = difference < 0; bool judged = true; bool release = false; if (Math.Abs(difference) <= timingWindow[0]) { // P.Great combo++; scorePGreatCount++; } else if (Math.Abs(difference) <= timingWindow[1]) { // Great if (fast) { delayFastCount++; } else { delaySlowCount++; } combo++; scoreGreatCount++; } else if (Math.Abs(difference) <= timingWindow[2]) { // Good if (fast) { delayFastCount2++; } else { delaySlowCount2++; } combo++; scoreGoodCount++; } else if (Math.Abs(difference) <= timingWindow[3]) { // Bad if (fast) { delayFastCount2++; } else { delaySlowCount2++; } combo = 0; scoreBadCount++; } else { if (noteScore.judgeType != NoteJudgeType.JudgeRelease) { if (difference > timingWindow[4]) { // Poor, late miss combo = 0; scorePoorCount++; release = true; } else if (difference > -timingWindow[5] && difference <= -timingWindow[4]) { // Poor, early miss, apply penalty but no combo reset and judge scorePoorCount++; judged = false; } } else { // Long note early release combo = 0; scorePoorCount++; } } if (combo > scoreLargestCombo) { scoreLargestCombo = combo; } if (Math.Abs(difference) <= timingWindow[3]) { // ignore missed notes from delay calculations totalDifference += difference; judgedKeyCount++; } if (judged) { NotePlayed(hitTimestamp, noteScore); } if (release && noteScore.judgeType == NoteJudgeType.JudgeHold) { // judge endpoint after early release LongNoteEndEvent endEvent = (noteScore.noteEvent as LongNoteEvent).endNote; for (int i = 0; i < pendingNoteScores.Count; i++) { if (pendingNoteScores[i].noteEvent != endEvent) { continue; } JudgeNote(hitTimestamp, pendingNoteScores[i]); break; } } if (OnNoteJudged != null) { OnNoteJudged(noteScore); } AdjustGauge(difference); }