Exemple #1
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;
        }
    }