public List <HitFrame> findOverAimHits()
        {
            var result   = new List <HitFrame>();
            int keyIndex = 0;

            for (int i = 0; i < hits.Count; ++i)
            {
                CircleObject note = hits[i].note;
                //bool hover = false;

                //searches for init circle object hover
                for (int j = keyIndex; j < replay.ReplayFrames.Count; ++j)
                {
                    ReplayFrame frame = replay.ReplayFrames[j];
                    if (note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)) && Math.Abs(frame.Time - note.StartTime) <= hitTimeWindow)
                    {
                        while (note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)) && frame.Time < hits[i].frame.Time)
                        {
                            ++j;
                            frame = replay.ReplayFrames[j];
                        }
                        if (!note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)))
                        {
                            result.Add(hits[i]);
                        }
                    }
                }
            }
            return(result);
        }
        private void associateHits()
        {
            int        keyIndex = 0;
            Keys       lastKey;
            KeyCounter keyCounter = new KeyCounter();

            if ((replay.Mods & Mods.HardRock) > 0)
            {
                applyHardrock();
            }

            int breakIndex = 0;
            int combo      = 0;

            for (int i = 0; i < beatmap.HitObjects.Count; ++i)
            {
                CircleObject note                 = beatmap.HitObjects[i];
                bool         noteHitFlag          = false;
                bool         noteAttemptedHitFlag = false;

                if ((note.Type.HasFlag(HitObjectType.Spinner)))
                {
                    continue;
                }

                for (int j = keyIndex; j < replay.ReplayFrames.Count; ++j)
                {
                    ReplayFrame frame = replay.ReplayFrames[j];
                    lastKey = j > 0 ? replay.ReplayFrames[j - 1].Keys : Keys.None;

                    Keys pressedKey = Utils.getKey(lastKey, frame.Keys);

                    if (breakIndex < breaks.Count && frame.Time > breaks[breakIndex].EndTime)
                    {
                        ++breakIndex;
                    }

                    if (frame.Time >= beatmap.HitObjects[0].StartTime - hitTimeWindow && (breakIndex >= breaks.Count || frame.Time < this.breaks[breakIndex].StartTime - hitTimeWindow))
                    {
                        keyCounter.Update(lastKey, frame.Keys);
                    }

                    frame.keyCounter = new KeyCounter(keyCounter);

                    if (frame.Time - note.StartTime > hitTimeWindow)
                    {
                        break;
                    }

                    if (pressedKey > 0 && Math.Abs(frame.Time - note.StartTime) <= hitTimeWindow)
                    {
                        if (note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)))
                        {
                            noteAttemptedHitFlag = true;
                            ++combo;
                            frame.combo = combo;
                            noteHitFlag = true;
                            HitFrame hitFrame = new HitFrame(note, frame, pressedKey);
                            hits.Add(hitFrame);
                            lastKey  = frame.Keys;
                            keyIndex = j + 1;
                            break;
                        }
                        else
                        {
                            if (Utils.dist(note.Location.X, note.Location.Y, frame.X, frame.Y) > 150)
                            {
                                extraHits.Add(new ClickFrame(frame, Utils.getKey(lastKey, frame.Keys)));
                            }
                            else
                            {
                                noteAttemptedHitFlag = true;
                                attemptedHits.Add(new HitFrame(note, frame, pressedKey));
                            }
                        }
                    }
                    if (pressedKey > 0 && Math.Abs(frame.Time - note.StartTime) <= 3 * hitTimeWindow && note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)))
                    {
                        noteAttemptedHitFlag = true;
                        attemptedHits.Add(new HitFrame(note, frame, pressedKey));
                    }

                    lastKey = frame.Keys;

                    frame.combo = combo;
                }

                if (!noteHitFlag)
                {
                    misses.Add(new ReplayMissFrame(replay.ReplayFrames[keyIndex], keyIndex, note));
                }
                if (!noteAttemptedHitFlag)
                {
                    effortlessMisses.Add(note);
                }
            }
        }