// Update is called once per frame
    void Update()
    {
        if (Globals.applicationMode == Globals.ApplicationMode.Playing && !GameSettings.bot)
        {
            ChartEditor    editor   = ChartEditor.Instance;
            GamepadInput   input    = editor.inputManager.mainGamepad;
            Chart.GameMode gameMode = editor.currentChart.gameMode;
            LaneInfo       laneInfo = editor.laneInfo;

            if (gameMode == Chart.GameMode.Drums)
            {
                foreach (Note.DrumPad drumPad in System.Enum.GetValues(typeof(Note.DrumPad)))
                {
                    if (bannedDrumPadInputs.ContainsKey(drumPad))
                    {
                        continue;
                    }

                    if (input.GetPadInputControllerOrKeyboard(drumPad, laneInfo))
                    {
                        animations[(int)drumPad].Press();
                    }
                    else
                    {
                        animations[(int)drumPad].Release();
                    }
                }
            }
            else
            {
                foreach (Note.GuitarFret fret in System.Enum.GetValues(typeof(Note.GuitarFret)))
                {
                    if (bannedFretInputs.ContainsKey(fret))
                    {
                        continue;
                    }

                    if (input.GetFretInputControllerOrKeyboard(fret))
                    {
                        animations[(int)fret].Press();
                    }
                    else
                    {
                        animations[(int)fret].Release();
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i < animations.Length; ++i)
            {
                if (!animations[i].running)
                {
                    animations[i].Release();
                }
            }
        }
    }
    public void Update(float time, HitWindow <DrumsNoteHitKnowledge> hitWindow, GamepadInput drumsInput, uint noteStreak, LaneInfo laneInfo)
    {
        DrumsNoteHitKnowledge nextNoteToHit = hitWindow.oldestUnhitNote;
        int inputMask = drumsInput.GetPadPressedInputMaskControllerOrKeyboard(laneInfo);

        if (nextNoteToHit != null)
        {
            int noteMask = nextNoteToHit.note.mask;
            int laneMask = laneInfo.laneMask;

            // Cull notes from the notemask by lanes that are being used
            foreach (Note.DrumPad pad in System.Enum.GetValues(typeof(Note.DrumPad)))
            {
                if (pad == Note.DrumPad.Kick)
                {
                    continue;
                }

                int padBitInput = (int)pad;
                int padMask     = 1 << padBitInput;

                bool includeLane = (padMask & laneMask) != 0;
                if (!includeLane)
                {
                    noteMask &= ~padMask;
                }
            }

            bool badHit = false;

            if ((inputMask | noteMask) != noteMask)
            {
                badHit = true;
            }
            else
            {
                foreach (Note.DrumPad drumPad in System.Enum.GetValues(typeof(Note.DrumPad)))
                {
                    bool hitPad = drumsInput.GetPadInputControllerOrKeyboard(drumPad, laneInfo);
                    if (hitPad)
                    {
                        if (nextNoteToHit.GetHitTime(drumPad) == NoteHitKnowledge.NULL_TIME)
                        {
                            nextNoteToHit.SetHitTime(drumPad, time);
                        }
                        else
                        {
                            badHit = true;
                        }
                    }
                }
            }

            if (badHit)
            {
                // Bad input
                Debug.Log("Missed due to bad input");
                MissNote(time, MissSubType.Overhit);

                foreach (Note.DrumPad drumPad in System.Enum.GetValues(typeof(Note.DrumPad)))
                {
                    nextNoteToHit.SetHitTime(drumPad, NoteHitKnowledge.NULL_TIME);
                }
            }
            else
            {
                float min = float.MaxValue, max = float.MinValue;
                int   totalHitsMask = 0;

                foreach (Note.DrumPad drumPad in System.Enum.GetValues(typeof(Note.DrumPad)))
                {
                    if (nextNoteToHit.GetHitTime(drumPad) != NoteHitKnowledge.NULL_TIME)
                    {
                        float hitTime = nextNoteToHit.GetHitTime(drumPad);
                        min = Mathf.Min(min, hitTime);
                        max = Mathf.Max(max, hitTime);

                        totalHitsMask |= 1 << (int)drumPad;
                    }
                }

                float totalSlop = max - min;

                if (min != float.MaxValue && time - min > DrumsTiming.slopBufferTime)
                {
                    // Technically an underhit
                    Debug.Log("Missed due to underhit");
                    MissNote(time, MissSubType.Overhit);
                }
                else if (totalHitsMask == noteMask && totalSlop < DrumsTiming.slopBufferTime)
                {
                    HitNote(time, nextNoteToHit);
                }
            }
        }
        else if (inputMask != 0)
        {
            Debug.Log("Missed due to hitting pad when there was no hit in window");
            MissNote(time, MissSubType.Overhit);
        }
    }