Esempio n. 1
0
 public void SetTickMethod(StateTick tick)
 {
     mTick = tick;
 }
Esempio n. 2
0
        protected override void AdvancePosition(time_t position)
        {
            time_t timeDelta = position - m_lastUpdatePosition;

            m_lastUpdatePosition = position;

            if (!HasStateTicks && !HasScoreTicks)
            {
                return;
            }

            switch (m_state)
            {
            case JudgeState.Idle:
            {
                var nextStateTick = NextStateTick;
                while (position - (nextStateTick.Position + JudgementOffset) >= 0)
                {
                    if (nextStateTick.State == JudgeState.CursorReset)
                    {
                        AdvanceStateTick();

                        OnShowCursor?.Invoke();

                        CursorPosition = m_desiredCursorPosition = nextStateTick.RootEntity.InitialValue;
                        LaserRange     = nextStateTick.RootEntity.RangeExtended ? 2 : 1;

                        m_direction = 0;
                    }
                    else if (nextStateTick.State == JudgeState.LaserBegin)
                    {
                        AdvanceStateTick();

                        //LastLockTime = position;
                        m_direction = 0;
                        m_state     = nextStateTick.RootEntity.IsInstant ?
                                      (IsBeingPlayed ? JudgeState.ActiveOn : JudgeState.ActiveOff) :
                                      JudgeState.ActiveOn;
                        m_currentStateTick = nextStateTick;

                        // The first score tick happens at the same time as the laser start event,
                        //  hop straight over to the other case explicitly and let it process the score tick.
                        goto case JudgeState.ActiveOn;
                    }
                    else
                    {
                        break;
                    }

                    if (HasStateTicks)
                    {
                        nextStateTick = NextStateTick;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            break;

            case JudgeState.ActiveOn:
            case JudgeState.ActiveOff:
            {
                var segmentCheck = m_currentStateTick.SegmentEntity;
                while (segmentCheck != null && segmentCheck.AbsoluteEndPosition < position && segmentCheck.NextConnected is AnalogEntity next)
                {
                    segmentCheck = next;
                }

                m_desiredCursorPosition = segmentCheck.SampleValue(position);

                if (m_direction != 0)
                {
                    m_lockTimer -= timeDelta * m_lockTimerSpeed;
                }
                if (m_lockTimer < 0)
                {
                    m_lockTimer = 0;
                }

                if (AutoPlay)
                {
                    CursorPosition = m_desiredCursorPosition;
                }

                var nextStateTick = NextStateTick;
                while (position - (nextStateTick.Position + JudgementOffset) >= 0)
                {
                    if (nextStateTick.State == JudgeState.LaserEnd)
                    {
                        AdvanceStateTick();

                        OnHideCursor?.Invoke();

                        if (AutoPlay)
                        {
                            CursorPosition = m_desiredCursorPosition = nextStateTick.SegmentEntity.FinalValue;
                        }

                        m_state            = JudgeState.Idle;
                        m_currentStateTick = null;
                    }
                    else if (nextStateTick.State == JudgeState.SwitchDirection)
                    {
                        if (position > (nextStateTick.Position + JudgementOffset))
                        {
                            if (position - (nextStateTick.Position + JudgementOffset) >= m_directionChangeRadius)
                            {
                                AdvanceStateTick();

                                m_direction        = nextStateTick.SegmentEntity.DirectionSign;
                                m_currentStateTick = nextStateTick;

                                //Logger.Log($"Direction Switch ({ (m_direction == 1 ? "->" : (m_direction == -1 ? "<-" : "|")) }) Missed (by { position - (nextStateTick.Position + JudgementOffset) }): { nextStateTick.SegmentEntity.Position } ({ nextStateTick.SegmentEntity.AbsolutePosition })");

                                m_lockTimer = 0.0;
                            }
                            else
                            {
                                m_canControlCursorMovement = false;
                                //Logger.Log($"Prevented automatic cursor moving while locked: direction switch origin passed without being played ({ nextStateTick.SegmentEntity.Position })");

                                break;
                            }
                        }
                    }
                    else if (nextStateTick.State == JudgeState.SameDirectionSlam && position - (nextStateTick.Position + JudgementOffset) >= m_directionChangeRadius)
                    {
                        AdvanceStateTick();
                    }
                    else
                    {
                        break;
                    }

                    if (HasStateTicks)
                    {
                        nextStateTick = NextStateTick;
                    }
                    else
                    {
                        break;
                    }
                }

                if (IsLocked && m_canControlCursorMovement)
                {
                    CursorPosition = m_desiredCursorPosition;
                }

                IsBeingPlayed = IsLocked || MathL.Abs(m_desiredCursorPosition - CursorPosition) <= m_cursorActiveRange;
                if (IsBeingPlayed && m_direction == 0)
                {
                    m_lockTimer = m_lockDuration;     // NOTE(local): don't SetLocked, keep the timer decay speed
                    if (m_canControlCursorMovement)
                    {
                        CursorPosition = m_desiredCursorPosition;
                    }
                }

                if (HasScoreTicks)
                {
                    var nextScoreTick = NextScoreTick;
                    if (position - (nextScoreTick.Position + JudgementOffset) >= 0)
                    {
                        var resultKind = IsBeingPlayed ? JudgeKind.Passive : JudgeKind.Miss;
                        OnTickProcessed?.Invoke(nextScoreTick.Entity, nextScoreTick.Position, new JudgeResult(0, resultKind));

                        AdvanceScoreTick();
                    }
                }
            }
            break;
            }

            if (HasStateTicks && position - (NextStateTick.Position + JudgementOffset) >= 0)
            {
                //Logger.Log($"{ NextStateTick.State } :: { NextStateTick.SegmentEntity.Position } or { NextStateTick.Position }");
            }
        }
Esempio n. 3
0
        public void UserInput(float amount, time_t position)
        {
            if (!HasStateTicks && !HasScoreTicks)
            {
                return;
            }

            if (m_state == JudgeState.Idle)
            {
                return;
            }
            int inputDir = MathL.Sign(amount);

            if (HasStateTicks)
            {
                var nextStateTick = NextStateTick;
                if (nextStateTick.State == JudgeState.SwitchDirection)
                {
                    time_t radius = MathL.Abs((double)(position - (NextStateTick.Position + JudgementOffset)));
                    if (radius < m_directionChangeRadius && (inputDir == nextStateTick.SegmentEntity.DirectionSign || nextStateTick.SegmentEntity.DirectionSign == 0))
                    {
                        if (m_lockTimer > 0.0 || IsBeingPlayed)
                        {
                            AdvanceStateTick();

                            m_direction        = nextStateTick.SegmentEntity.DirectionSign;
                            m_currentStateTick = nextStateTick;

                            //Logger.Log($"Direction Switch ({ (m_direction == 1 ? "->" : (m_direction == -1 ? "<-" : "|")) }) Hit: { nextStateTick.SegmentEntity.Position } ({ nextStateTick.SegmentEntity.AbsolutePosition })");

                            if (nextStateTick.IsSlam)
                            {
                                OnSlamHit?.Invoke(position, nextStateTick.SegmentEntity);
                                //Logger.Log($"  Direction Switch on Slam: { CursorPosition }, { nextStateTick.SegmentEntity.InitialValue } ({ MathL.Abs(CursorPosition - nextStateTick.SegmentEntity.InitialValue) } <? { m_cursorActiveRange })");

                                // If the cursor was near the head of the laser, we lock it regardless of previous locked status.
                                if (MathL.Abs(CursorPosition - nextStateTick.SegmentEntity.InitialValue) < m_cursorActiveRange)
                                {
                                    //Logger.Log($"  Direction Switch on Slam triggered Lock");
                                    SetLocked();
                                }
                            }
                            else if (IsLocked)
                            {
                                SetLocked();
                            }
                        }
                    }
                }
                else if (nextStateTick.State == JudgeState.SameDirectionSlam)
                {
                    time_t radius = MathL.Abs((double)(position - (NextStateTick.Position + JudgementOffset)));
                    if (radius < m_directionChangeRadius && inputDir == m_direction)
                    {
                        Debug.Assert(nextStateTick.SegmentEntity.IsInstant);

                        AdvanceStateTick();
                        OnSlamHit?.Invoke(position, nextStateTick.SegmentEntity);
                    }
                }
            }

            if (IsLocked)
            {
                if (inputDir == m_direction)
                {
                    SetLocked();
                }
                else
                {
                    m_lockTimerSpeed = 2.5;
                }
            }
            else
            {
                if (m_direction == 0)
                {
                    // If we input at all, that's an active role by the user.
                    // If the user inputs and the cursor happens to be really close, just consider it good!
                    // They shouldn't need to pay so close attention to the cursor, this value can be tweaked
                    //  so that a wider radius is accepted.
                    if (MathL.Abs(m_desiredCursorPosition - CursorPosition) < m_cursorActiveRange * 0.1f)
                    {
                        SetLocked();
                    }
                    else if (CursorPosition < m_desiredCursorPosition)
                    {
                        if (inputDir == 1)
                        {
                            CursorPosition = MathL.Min(CursorPosition + amount, m_desiredCursorPosition);
                            if (CursorPosition == m_desiredCursorPosition)
                            {
                                SetLocked();
                            }
                        }
                        else
                        {
                            CursorPosition = MathL.Max(0, CursorPosition + amount);
                        }
                    }
                    else if (CursorPosition > m_desiredCursorPosition)
                    {
                        if (inputDir == -1)
                        {
                            CursorPosition = MathL.Max(CursorPosition + amount, m_desiredCursorPosition);
                            if (CursorPosition == m_desiredCursorPosition)
                            {
                                SetLocked();
                            }
                        }
                        else
                        {
                            CursorPosition = MathL.Min(1, CursorPosition + amount);
                        }
                    }
                }
                else
                {
                    // Same as above for non-directional lasers, if the player is actively
                    //  trying to play in the correct direction and the cursor happens to be in about
                    //  the right location we let them lock and keep going.
                    if (inputDir == m_direction &&
                        MathL.Abs(m_desiredCursorPosition - CursorPosition) < m_cursorActiveRange * 0.1f)
                    {
                        SetLocked();
                    }
                    else if (m_direction == 1)
                    {
                        if (inputDir == 1)
                        {
                            if (CursorPosition < m_desiredCursorPosition)
                            {
                                CursorPosition = MathL.Min(CursorPosition + amount, m_desiredCursorPosition);
                            }
                            else if (CursorPosition > m_desiredCursorPosition)
                            {
                                CursorPosition = MathL.Min(1, CursorPosition + amount);
                            }

                            if (CursorPosition == m_desiredCursorPosition)
                            {
                                SetLocked();
                            }
                        }
                        else
                        {
                            CursorPosition = MathL.Max(0, CursorPosition + amount);
                        }
                    }
                    else if (m_direction == -1)
                    {
                        if (inputDir == -1)
                        {
                            if (CursorPosition > m_desiredCursorPosition)
                            {
                                CursorPosition = MathL.Max(CursorPosition + amount, m_desiredCursorPosition);
                            }
                            else if (CursorPosition < m_desiredCursorPosition)
                            {
                                CursorPosition = MathL.Max(0, CursorPosition + amount);
                            }

                            if (CursorPosition == m_desiredCursorPosition)
                            {
                                SetLocked();
                            }
                        }
                        else
                        {
                            CursorPosition = MathL.Min(1, CursorPosition + amount);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
 public void SetTickMethod(StateTick tick)
 {
     mTick = tick;
 }