Example #1
0
        private void addAction(bool hitting, bool hardhit = false)
        {
            if (wasHit == hitting)
            {
                return;
            }

            wasHit = hitting;

            var state = new ReplayState <TauAction>
            {
                PressedActions = new List <TauAction>()
            };

            if (hitting)
            {
                if (hardhit)
                {
                    state.PressedActions.Add(TauAction.HardButton);
                }
                else
                {
                    state.PressedActions.Add(wasLeft ? TauAction.LeftButton : TauAction.RightButton);
                    wasLeft = !wasLeft;
                }
            }

            state.Apply(tauInputManager.CurrentState, tauInputManager);
        }
Example #2
0
        private void addAction(bool hitting)
        {
            if (wasHit == hitting)
            {
                return;
            }

            wasHit = hitting;

            var state = new ReplayState <OsuAction>
            {
                PressedActions = new List <OsuAction>()
            };

            if (hitting)
            {
                state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton);
                wasLeft = !wasLeft;
            }

            state.Apply(osuInputManager.CurrentState, osuInputManager);
        }
Example #3
0
        public void Update(Playfield playfield)
        {
            if (hasReplay)
            {
                return;
            }

            bool requiresHold = false;
            bool requiresHit  = false;

            double time = playfield.Clock.CurrentTime;

            foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType <DrawableOsuHitObject>())
            {
                // we are not yet close enough to the object.
                if (time < h.HitObject.StartTime - relax_leniency)
                {
                    break;
                }

                // already hit or beyond the hittable end time.
                if (h.IsHit || (h.HitObject is IHasDuration hasEnd && time > hasEnd.EndTime))
                {
                    continue;
                }

                switch (h)
                {
                case DrawableHitCircle circle:
                    handleHitCircle(circle);
                    break;

                case DrawableSlider slider:
                    // Handles cases like "2B" beatmaps, where sliders may be overlapping and simply holding is not enough.
                    if (!slider.HeadCircle.IsHit)
                    {
                        handleHitCircle(slider.HeadCircle);
                    }

                    requiresHold |= slider.Ball.IsHovered || h.IsHovered;
                    break;

                case DrawableSpinner _:
                    requiresHold = true;
                    break;
                }
            }

            if (requiresHit)
            {
                changeState(false);
                changeState(true);
            }

            if (requiresHold)
            {
                changeState(true);
            }
            else if (isDownState && time - lastStateChangeTime > AutoGenerator.KEY_UP_DELAY)
            {
                changeState(false);
            }

            void handleHitCircle(DrawableHitCircle circle)
            {
                if (!circle.HitArea.IsHovered)
                {
                    return;
                }

                Debug.Assert(circle.HitObject.HitWindows != null);
                requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime);
            }

            void changeState(bool down)
            {
                if (isDownState == down)
                {
                    return;
                }

                isDownState         = down;
                lastStateChangeTime = time;

                state = new ReplayState <OsuAction>
                {
                    PressedActions = new List <OsuAction>()
                };

                if (down)
                {
                    state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton);
                    wasLeft = !wasLeft;
                }

                state?.Apply(osuInputManager.CurrentState, osuInputManager);
            }
        }
Example #4
0
        public void Update(Playfield playfield)
        {
            if (hasReplay)
            {
                return;
            }

            bool requiresHold = false;
            bool requiresHit  = false;

            double time = playfield.Clock.CurrentTime;

            foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType <DrawableSentakkiHitObject>())
            {
                // we are not yet close enough to the object.
                if (time < h.HitObject.StartTime - relax_leniency)
                {
                    break;
                }

                // already hit or beyond the hittable end time.
                if (h.IsHit || (h.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime))
                {
                    continue;
                }

                switch (h)
                {
                case DrawableTap tap:
                    if (tap.HitArea.IsHovered)
                    {
                        Debug.Assert(tap.HitObject.HitWindows != null);
                        requiresHit |= tap.HitObject.HitWindows.CanBeHit(time - tap.HitObject.StartTime);
                    }
                    break;

                case DrawableHold hold:
                    requiresHold |= hold.HitArea.IsHovered || h.IsHovered;
                    break;

                case DrawableTouchHold _:
                    requiresHold = true;
                    break;
                }
            }

            if (requiresHit)
            {
                changeState(false);
                changeState(true);
            }

            if (requiresHold)
            {
                changeState(true);
            }
            else if (isDownState && time - lastStateChangeTime > AutoGenerator.KEY_UP_DELAY)
            {
                changeState(false);
            }

            void changeState(bool down)
            {
                if (isDownState == down)
                {
                    return;
                }

                isDownState         = down;
                lastStateChangeTime = time;

                state = new ReplayState <SentakkiAction>
                {
                    PressedActions = new List <SentakkiAction>()
                };

                if (down)
                {
                    state.PressedActions.Add(wasLeft ? SentakkiAction.Button1 : SentakkiAction.Button2);
                    wasLeft = !wasLeft;
                }

                state?.Apply(sentakkiInputManager.CurrentState, sentakkiInputManager);
            }
        }