Пример #1
0
        public virtual void NotePlayed(double hitTimestamp, NoteScore noteScore)
        {
            noteScore.hitOffset = hitTimestamp - noteScore.timestamp;

            pendingNoteScores.Remove(noteScore);
            noteScores.Add(noteScore);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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;
                }
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
 public abstract void JudgeNote(double hitTimestamp, NoteScore noteScore);
Пример #7
0
        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);
        }