Exemple #1
0
    public virtual void Clear(NoteGrade grade)
    {
        if (IsCleared || grade == NoteGrade.Undetermined)
        {
            return;
        }

        IsCleared = true;
        Game.OnClear(this);
        View.OnClear(grade);

        if (!(Game.Instance is StoryboardGame))
        {
            StartCoroutine(DestroyLater());
        }

        if (TimeUntilEnd > -5) // Prevent storyboard seeking
        {
            EventKit.Broadcast("note clear", this);
        }

        // Hit sound
        if (grade != NoteGrade.Miss && (!(this is HoldNote) || !PlayerPrefsExt.GetBool("early hit sounds")))
        {
            PlayHitSound();
        }

        // gameObject.GetComponent<SpriteRenderer> ().material.SetFloat("_HRate", 1.0f);
        // Animation speed = 1.0f;
    }
Exemple #2
0
        public override void OnClear(NoteGrade grade)
        {
            base.OnClear(grade);

            // They still display
            Ring.enabled = true;
            Fill.enabled = true;
        }
Exemple #3
0
        public override void OnClear(NoteGrade grade)
        {
            base.OnClear(grade);

            if (!(Game is StoryboardGame))
            {
                Fill.enabled       = true; // Still render it
                SpriteMask.enabled = false;
            }
        }
Exemple #4
0
 public override void OnClear(NoteGrade grade)
 {
     base.OnClear(grade);
     Line.enabled          = false;
     CompletedLine.enabled = false;
     ProgressRing.Reset();
     ProgressRing.enabled = false;
     Triangle.Reset();
     Triangle.enabled   = false;
     SpriteMask.enabled = false;
 }
Exemple #5
0
        public override void OnClear(NoteGrade grade)
        {
            base.OnClear(grade);
            Line2.enabled          = false;
            CompletedLine2.enabled = false;

            if (!(Game is StoryboardGame))
            {
                Object.Destroy(Line2.gameObject);
                Object.Destroy(CompletedLine2.gameObject);
            }
        }
Exemple #6
0
    public static double GetScoreWeight(this NoteGrade grade, bool ranked)
    {
        if (!ranked)
        {
            switch (grade)
            {
            case NoteGrade.Perfect:
                return(1.0);

            case NoteGrade.Great:
                return(1.0);

            case NoteGrade.Good:
                return(0.7);

            case NoteGrade.Bad:
                return(0.3);

            case NoteGrade.Miss:
                return(0);
            }
        }
        else
        {
            switch (grade)
            {
            case NoteGrade.Perfect:
                return(1.0);

            case NoteGrade.Great:
                return(0.9);

            case NoteGrade.Good:
                return(0.5);

            case NoteGrade.Bad:
                return(0.1);

            case NoteGrade.Miss:
                return(0f);
            }
        }

        return(0f);
    }
Exemple #7
0
    public static float ScoreWeight(this NoteGrade grade, bool ranked)
    {
        if (!ranked)
        {
            switch (grade)
            {
            case NoteGrade.Perfect:
                return(1f);

            case NoteGrade.Great:
                return(1f);

            case NoteGrade.Good:
                return(0.7f);

            case NoteGrade.Bad:
                return(0.3f);

            case NoteGrade.Miss:
                return(0f);
            }
        }
        else
        {
            switch (grade)
            {
            case NoteGrade.Perfect:
                return(1f);

            case NoteGrade.Great:
                return(0.9f);

            case NoteGrade.Good:
                return(0.5f);

            case NoteGrade.Bad:
                return(0.1f);

            case NoteGrade.Miss:
                return(0f);
            }
        }

        return(0f);
    }
Exemple #8
0
        public override void OnClear(NoteGrade grade)
        {
            SimpleEffects.Instance.PlayClearFx(
                this,
                grade,
                Note.TimeUntilEnd,
                GameOptions.Instance.ShowEarlyLateIndicator
                );

            rendered = false;

            if (Ring != null)
            {
                Ring.enabled     = false;
                Fill.enabled     = false;
                Collider.enabled = false;
            }
        }
Exemple #9
0
        public override void OnClear(NoteGrade grade)
        {
            base.OnClear(grade);
            Line.enabled          = false;
            CompletedLine.enabled = false;
            ProgressRing.Reset();
            ProgressRing.enabled = false;
            Triangle.Reset();
            Triangle.enabled   = false;
            SpriteMask.enabled = false;

            if (!(Game is StoryboardGame))
            {
                Object.Destroy(Line.gameObject);
                Object.Destroy(CompletedLine.gameObject);
                Object.Destroy(ProgressRing.gameObject);
                Object.Destroy(Triangle.gameObject);
                Object.Destroy(SpriteMask.gameObject);
            }
        }
Exemple #10
0
    public virtual void Clear(NoteGrade grade)
    {
        if (IsCleared)
        {
            return;
        }

        IsCleared = true;
        Renderer.OnClear(grade);
        Game.State.Judge(this, grade, -TimeUntilEnd, GreatGradeWeight);
        Game.onNoteJudged.Invoke(Game, this, new JudgeData(grade, -TimeUntilEnd, GreatGradeWeight));

        // Hit sound
        if (grade != NoteGrade.Miss && (!(this is HoldNote) || Context.Player.Settings.HoldHitSoundTiming.Let(it => it == HoldHitSoundTiming.End || it == HoldHitSoundTiming.Both)))
        {
            PlayHitSound();
        }

        Game.onNoteClear.Invoke(Game, this);
        AwaitAndCollect();
    }
Exemple #11
0
    public static float TpWeight(this NoteGrade grade)
    {
        switch (grade)
        {
        case NoteGrade.Perfect:
            return(1f);

        case NoteGrade.Great:
            return(0.7f);

        case NoteGrade.Good:
            return(0.3f);

        case NoteGrade.Bad:
            return(0f);

        case NoteGrade.Miss:
            return(0f);
        }

        return(0f);
    }
Exemple #12
0
    public static double GetAccuracyWeight(this NoteGrade grade)
    {
        switch (grade)
        {
        case NoteGrade.Perfect:
            return(1.0);

        case NoteGrade.Great:
            return(0.7);

        case NoteGrade.Good:
            return(0.3);

        case NoteGrade.Bad:
            return(0);

        case NoteGrade.Miss:
            return(0);
        }

        return(0f);
    }
Exemple #13
0
    public void PlayClearEffect(NoteRenderer noteRenderer, NoteGrade grade, float timeUntilEnd, bool earlyLateIndicator)
    {
        if (game.State.Mode == GameMode.GlobalCalibration)
        {
            return;
        }

        var color = game.Config.NoteGradeEffectColors[grade];
        var at    = noteRenderer.Note.transform.position;

        if (noteRenderer.Note.Type == NoteType.Hold || noteRenderer.Note.Type == NoteType.LongHold)
        {
            if (noteRenderer.Note.Model.style == 1)
            {
                at = new Vector3(at.x, Scanner.Instance.transform.position.y, at.z);
            }
        }

        var speed = 1f;

        switch (grade)
        {
        case NoteGrade.Great:
            speed = 0.9f;
            break;

        case NoteGrade.Good:
            speed = 0.7f;
            break;

        case NoteGrade.Bad:
            speed = 0.5f;
            break;

        case NoteGrade.Miss:
            speed = 0.3f;
            break;
        }

        var isDragType = noteRenderer.Note.Type == NoteType.DragHead || noteRenderer.Note.Type == NoteType.DragChild ||
                         noteRenderer.Note.Type == NoteType.CDragChild;

        var settings = flatFx.settings[1];

        settings.lifetime         = 0.4f / speed;
        settings.sectorCount      = noteRenderer.Note.Type == NoteType.Flick ? 4 : 24;
        settings.start.innerColor = settings.start.outerColor = color.WithAlpha(1);
        settings.end.innerColor   = settings.end.outerColor = color.WithAlpha(0);
        settings.end.size         = (isDragType ? 4f : 5f) * noteRenderer.Game.Config.GlobalNoteSizeMultiplier * (1 + clearEffectSizeMultiplier);
        settings.start.thickness  = 1.333f;
        settings.end.thickness    = 0.333f;
        flatFx.AddEffect(at, 1);

        if (grade == NoteGrade.Miss)
        {
            var fx = game.ObjectPool.SpawnEffect(Effect.Miss, at);
            fx.Stop();

            var mainModule = fx.main;
            mainModule.simulationSpeed = 0.3f;
            mainModule.duration       /= 0.3f;
            mainModule.startColor      = game.Config.NoteGradeEffectColors[grade];

            if (isDragType)
            {
                fx.transform.localScale = new Vector3(2, 2, 2);
            }

            fx.Play();
            AwaitAndCollect(Effect.Miss, fx);
        }
        else
        {
            var clearEffect = isDragType ? Effect.ClearDrag : Effect.Clear;

            var fx = game.ObjectPool.SpawnEffect(clearEffect, at);
            fx.Stop();

            if (!isDragType)
            {
                var t     = fx.transform.GetChild(0);
                var early = t.GetChild(0);
                var late  = t.GetChild(1);
                if (earlyLateIndicator)
                {
                    if (grade != NoteGrade.Perfect)
                    {
                        t.gameObject.SetActive(true);
                        if (timeUntilEnd > 0)
                        {
                            early.gameObject.SetActive(true);
                            late.gameObject.SetActive(false);
                        }
                        else
                        {
                            early.gameObject.SetActive(false);
                            late.gameObject.SetActive(true);
                        }
                    }
                    else
                    {
                        t.gameObject.SetActive(false);
                    }
                }
                else
                {
                    t.gameObject.SetActive(false);
                }
            }

            var mainModule = fx.main;
            mainModule.simulationSpeed = speed;
            mainModule.duration       /= speed;
            mainModule.startColor      = color.WithAlpha(1);

            if (isDragType)
            {
                fx.transform.localScale = new Vector3(3f, 3f, 3f);
            }

            fx.Play();
            AwaitAndCollect(clearEffect, fx);
        }
    }
Exemple #14
0
    public void Judge(Note note, NoteGrade grade, double error, double greatGradeWeight)
    {
        if (IsCompleted || IsFailed)
        {
            return;
        }

        if (Judgements[note.Model.id].IsJudged)
        {
            return;

            Debug.LogWarning($"Trying to judge note {note.Model.id} which is already judged.");
        }

        ClearCount++;
        Judgements[note.Model.id].Apply(it =>
        {
            it.IsJudged = true;
            it.Grade    = grade;
            it.Error    = error;
        });

        if (Mode == GameMode.Practice)
        {
            if (grade != NoteGrade.Perfect && grade != NoteGrade.Great)
            {
                isFullScorePossible = false;
            }
        }
        else
        {
            if (grade != NoteGrade.Perfect)
            {
                isFullScorePossible = false;
            }
        }

        // Combo
        var miss = grade == NoteGrade.Bad || grade == NoteGrade.Miss;

        if (miss)
        {
            Combo = 0;
        }
        else
        {
            Combo++;
        }
        if (Combo > MaxCombo)
        {
            MaxCombo = Combo;
        }

        if (Mode == GameMode.Tier)
        {
            if (miss)
            {
                Context.TierState.Combo = 0;
            }
            else
            {
                Context.TierState.Combo++;
            }
            if (Context.TierState.Combo > Context.TierState.MaxCombo)
            {
                Context.TierState.MaxCombo = Context.TierState.Combo;
            }
        }

        // Score multiplier
        if (Mode != GameMode.Practice)
        {
            switch (grade)
            {
            case NoteGrade.Perfect:
                NoteScoreMultiplier += 0.004D * noteScoreMultiplierFactor;
                break;

            case NoteGrade.Great:
                NoteScoreMultiplier += 0.002D * noteScoreMultiplierFactor;
                break;

            case NoteGrade.Good:
                NoteScoreMultiplier += 0.001D * noteScoreMultiplierFactor;
                break;

            case NoteGrade.Bad:
                NoteScoreMultiplier -= 0.025D * noteScoreMultiplierFactor;
                break;

            case NoteGrade.Miss:
                NoteScoreMultiplier -= 0.05D * noteScoreMultiplierFactor;
                break;
            }

            if (NoteScoreMultiplier > 1)
            {
                NoteScoreMultiplier = 1;
            }
            if (NoteScoreMultiplier < 0)
            {
                NoteScoreMultiplier = 0;
            }
        }

        // Score
        if (Mode == GameMode.Practice)
        {
            Score += 900000.0 / NoteCount * grade.GetScoreWeight(false) +
                     100000.0 / (NoteCount * (NoteCount + 1) / 2.0) * Combo;
        }
        else
        {
            var maxNoteScore = 1000000.0 / NoteCount;

            double noteScore;
            if (grade == NoteGrade.Great)
            {
                noteScore = maxNoteScore * (NoteGrade.Great.GetScoreWeight(true) +
                                            (NoteGrade.Perfect.GetScoreWeight(true) -
                                             NoteGrade.Great.GetScoreWeight(true)) *
                                            greatGradeWeight);
            }
            else
            {
                noteScore = maxNoteScore * grade.GetScoreWeight(true);
            }

            noteScore *= NoteScoreMultiplier;
            Score     += noteScore;
        }

        if (Score > 999500)
        {
            if (ClearCount == NoteCount && isFullScorePossible)
            {
                Score = 1000000;
            }
        }

        if (Score > 1000000)
        {
            Score = 1000000;
        }
        if (Score == 1000000 && !isFullScorePossible)
        {
            Score = 999999;                                           // In case of double inaccuracy
        }
        // Accuracy
        if (Mode == GameMode.Practice || grade != NoteGrade.Great)
        {
            accumulatedAccuracy += 1.0 * grade.GetAccuracyWeight();
        }
        else
        {
            accumulatedAccuracy += 1.0 * (NoteGrade.Great.GetAccuracyWeight() +
                                          (NoteGrade.Perfect.GetAccuracyWeight() -
                                           NoteGrade.Great.GetAccuracyWeight()) *
                                          greatGradeWeight);
        }

        Accuracy = accumulatedAccuracy / ClearCount;

        // Health mods
        if (UseHealthSystem)
        {
            var mods = Mods.Contains(Mod.ExHard) ? exHardHpMods : hardHpMods;
            if (Mode == GameMode.Tier)
            {
                mods = tierHpMods;
            }

            var mod = mods
                      .Select[note.Type]
                      .Select[Mode == GameMode.Practice ? unrankedGradingIndex[grade] : rankedGradingIndex[grade]];

            double change = 0;

            switch (mod.Type)
            {
            case HpModType.Absolute:
                change = mod.Value;
                break;

            case HpModType.Percentage:
                change = mod.Value / 100f * MaxHealth;
                break;

            case HpModType.DivideByNoteCount:
                change = mod.Value / NoteCount / 100f * MaxHealth;
                break;
            }

            if (change < 0 && mod.UseHealthBuffer)
            {
                double a;
                if (HealthPercentage > 0.3)
                {
                    a = 1;
                }
                else
                {
                    a = 0.25 + 2.5 * HealthPercentage;
                }
                change *= a;
            }

            Health += change;
            Health  = Math.Min(Math.Max(Health, 0), MaxHealth);
            if (Health <= 0)
            {
                ShouldFail = true;
            }

            if (Mode == GameMode.Tier)
            {
                Context.TierState.Health = Health;
            }
        }

        if (
            Mods.Contains(Mod.AP) && grade != NoteGrade.Perfect
            ||
            Mods.Contains(Mod.FC) && (grade == NoteGrade.Bad || grade == NoteGrade.Miss)
            )
        {
            ShouldFail = true;
        }
    }
Exemple #15
0
 public void PlayClearEffect(NoteRenderer noteRenderer, NoteGrade grade, float timeUntilEnd)
 {
     PlayClearEffect(noteRenderer, grade, timeUntilEnd, Context.Player.Settings.DisplayEarlyLateIndicators);
 }
Exemple #16
0
 public virtual void OnClear(NoteGrade grade)
 {
 }
Exemple #17
0
 public JudgeData(NoteGrade grade, double error, double greatGradeWeight)
 {
     Grade            = grade;
     Error            = error;
     GreatGradeWeight = greatGradeWeight;
 }
Exemple #18
0
 public override void OnClear(NoteGrade grade)
 {
     base.OnClear(grade);
     leftArrow.enabled  = false;
     rightArrow.enabled = false;
 }
Exemple #19
0
        public void OnClear(GameNote note, NoteGrade grade, float timeUntilEnd, double greatGradeWeight)
        {
            if (grade == NoteGrade.Undetermined)
            {
                return;
            }
            if (NoteRankings[note.Note.id] != NoteGrade.Undetermined)
            {
                return;
            }

            if (!IsRanked)
            {
                if (grade != NoteGrade.Perfect && grade != NoteGrade.Great)
                {
                    isMillionMasterPossible = false;
                }
            }
            else
            {
                if (grade != NoteGrade.Perfect)
                {
                    isMillionMasterPossible = false;
                }
            }

            NoteCleared++;
            NoteRankings[note.Note.id] = grade;

            if (grade != NoteGrade.Perfect && grade != NoteGrade.Miss)
            {
                if (timeUntilEnd > 0)
                {
                    Early++;
                }
                else
                {
                    Late++;
                }
            }

            timeOffs.Add(timeUntilEnd);

            // Combo
            if (grade == NoteGrade.Bad || grade == NoteGrade.Miss)
            {
                Combo = 0;
            }
            else
            {
                Combo++;
                if (MaxCombo < Combo)
                {
                    MaxCombo = Combo;
                }
            }

            if (IsRanked)
            {
                switch (grade)
                {
                case NoteGrade.Perfect:
                    ComboMultiplier += 0.002D * magicNumber;
                    break;

                case NoteGrade.Great:
                    ComboMultiplier += 0.0005D * magicNumber;
                    break;

                case NoteGrade.Good:
                    ComboMultiplier -= -0.005D * magicNumber;
                    break;

                case NoteGrade.Bad:
                    ComboMultiplier -= 0.025D * magicNumber;
                    break;

                case NoteGrade.Miss:
                    ComboMultiplier -= 0.05D * magicNumber;
                    break;
                }

                if (ComboMultiplier > 1)
                {
                    ComboMultiplier = 1;
                }
                if (ComboMultiplier < 0)
                {
                    ComboMultiplier = 0;
                }
            }

            // Score
            if (!IsRanked)
            {
                Score += 900000f / NoteCount * grade.ScoreWeight(ranked: false) +
                         100000f / (NoteCount * (double)(NoteCount + 1) / 2f) * Combo;
            }
            else
            {
                var maxNoteScore = 1000000.0 / NoteCount;

                double noteScore;

                if (grade == NoteGrade.Great)
                {
                    noteScore = maxNoteScore * (NoteGrade.Great.ScoreWeight(ranked: true) +
                                                (NoteGrade.Perfect.ScoreWeight(ranked: true) -
                                                 NoteGrade.Great.ScoreWeight(ranked: true)) *
                                                greatGradeWeight);
                }
                else
                {
                    noteScore = maxNoteScore * grade.ScoreWeight(ranked: true);
                }

                noteScore *= ComboMultiplier;

                Score += noteScore;
            }

            if (Score > 999500)
            {
                if (NoteCleared == NoteCount && isMillionMasterPossible)
                {
                    Score = 1000000;
                }
            }

            if (Score > 1000000)
            {
                Score = 1000000;
            }

            // TP
            if (!IsRanked || grade != NoteGrade.Great)
            {
                currentTp += 100f * grade.TpWeight();
            }
            else
            {
                currentTp += 100f * (NoteGrade.Great.TpWeight() +
                                     (NoteGrade.Perfect.TpWeight() - NoteGrade.Great.TpWeight()) * greatGradeWeight);
            }
            Tp = currentTp / NoteCleared;

            // HP
            if (Mods.Contains(Mod.Hard) || Mods.Contains(Mod.ExHard))
            {
                var mods = Mods.Contains(Mod.ExHard) ? ExHardHpMods : HardHpMods;

                var mod = mods.Select[note.Note.type]
                          .Select[IsRanked ? RankedGradingIndices[grade] : UnrankedGradingIndices[grade]];

                switch (mod.Type)
                {
                case HpModType.Absolute:
                    Hp += mod.Value;
                    break;

                case HpModType.Percentage:
                    Hp += mod.Value / 100f * MaxHp;
                    break;

                case HpModType.DivideByNoteCount:
                    Hp += (mod.Value / NoteCount) / 100f * MaxHp;
                    break;
                }

                if (Hp > MaxHp)
                {
                    Hp = MaxHp;
                }
                if (Hp < 0)
                {
                    Game.Instance.Fail();
                }
            }

            if (
                (Mods.Contains(Mod.AP) && grade != NoteGrade.Perfect)
                ||
                (Mods.Contains(Mod.FC) && (grade == NoteGrade.Bad || grade == NoteGrade.Miss))
                )
            {
                Game.Instance.Fail();
            }
        }
Exemple #20
0
 public override void OnClear(NoteGrade grade)
 {
     base.OnClear(grade);
     Game.effectController.PlayClearEffect(this, grade, Note.TimeUntilEnd + Note.JudgmentOffset);
 }
Exemple #21
0
        public void PlayClearFx(SimpleNoteView noteView, NoteGrade grade, float timeUntilEnd,
                                bool earlyLateIndicator)
        {
            if (grade == NoteGrade.Undetermined)
            {
                return;
            }

            var at      = noteView.Note.Note.position;
            var clearFx = ClearFx;

            if (noteView is DragChildNoteView || noteView is DragHeadNoteView)
            {
                clearFx = ClearDragFx;
            }

            if (noteView.Note.Note.type == NoteType.Hold)
            {
                at = new Vector3(at.x, ScanlineView.Instance.transform.position.y, at.z);
            }

            if (grade == NoteGrade.Miss)
            {
                var fx = Instantiate(MissFx, at, Quaternion.identity);
                fx.Stop();

                var mainModule = fx.main;
                mainModule.simulationSpeed = 0.3f;
                mainModule.duration        = mainModule.duration / 0.3f;
                mainModule.startColor      = options.MissColor;

                if (noteView.Note.Note.type == NoteType.DragHead || noteView.Note.Note.type == NoteType.DragChild)
                {
                    fx.transform.localScale = new Vector3(2, 2, 2);
                }

                fx.Play();
                Destroy(fx.gameObject, fx.main.duration);
            }
            else
            {
                var fx = Instantiate(clearFx, at, Quaternion.identity);
                fx.Stop();

                if (!(noteView is DragChildNoteView) && !(noteView is DragHeadNoteView))
                {
                    if (earlyLateIndicator)
                    {
                        if (grade != NoteGrade.Perfect)
                        {
                            fx.transform.GetChild(0).GetChild(timeUntilEnd > 0 ? 1 : 0).gameObject
                            .SetActive(false);
                        }
                        else
                        {
                            fx.transform.GetChild(0).GetChild(0).gameObject.SetActive(false);
                            fx.transform.GetChild(0).GetChild(1).gameObject.SetActive(false);
                        }
                    }
                    else
                    {
                        fx.transform.GetChild(0).GetChild(0).gameObject.SetActive(false);
                        fx.transform.GetChild(0).GetChild(1).gameObject.SetActive(false);
                    }
                }

                var speed = 1f;
                var color = options.PerfectColor;
                switch (grade)
                {
                case NoteGrade.Great:
                    speed = 0.9f;
                    color = options.GreatColor;
                    break;

                case NoteGrade.Good:
                    speed = 0.7f;
                    color = options.GoodColor;
                    break;

                case NoteGrade.Bad:
                    speed = 0.5f;
                    color = options.BadColor;
                    break;
                }

                var mainModule = fx.main;
                mainModule.simulationSpeed = speed;
                mainModule.duration        = mainModule.duration / speed;
                mainModule.startColor      = color.WithAlpha(1);

                if (noteView.Note.Note.type == NoteType.DragHead || noteView.Note.Note.type == NoteType.DragChild)
                {
                    fx.transform.localScale = new Vector3(3f, 3f, 3f);
                }

                fx.Play();
                Destroy(fx.gameObject, fx.main.duration);
            }
        }
Exemple #22
0
 public virtual void OnClear(NoteGrade grade) => Expression.Empty();