예제 #1
0
        internal void CalcStrain(CatchDifficultyHitObject lastHitObject, double timeRate)
        {
            var time  = (HitObject.Offset - lastHitObject.HitObject.Offset) / timeRate;
            var decay = Math.Pow(Constants.DecayBase, time / 1000d);

            Offset = MathUtlity.Clamp(
                lastHitObject.ScaledPosition + lastHitObject.Offset,
                ScaledPosition - (Constants.NormalizedHitobjectRadius - _errorMargin),
                ScaledPosition + (Constants.NormalizedHitobjectRadius - _errorMargin)) - ScaledPosition;
            LastMovement = Math.Abs(ScaledPosition - lastHitObject.ScaledPosition + Offset - lastHitObject.Offset);
            var addition = Math.Pow(LastMovement, 1.3) / 500;

            if (ScaledPosition < lastHitObject.ScaledPosition)
            {
                LastMovement *= -1;
            }

            var additionBonus = 0d;
            var sqrtTime      = Math.Sqrt(Math.Max(time, 25));

            if (Math.Abs(LastMovement) > 0.1)
            {
                if (Math.Abs(lastHitObject.LastMovement) > 0.1 &&
                    MathUtlity.Sign(LastMovement) != MathUtlity.Sign(lastHitObject.LastMovement))
                {
                    var bonus       = Constants.DirectionChangeBonus / sqrtTime;
                    var bonusFactor = Math.Min(_errorMargin, Math.Abs(LastMovement)) / _errorMargin;
                    addition += bonus * bonusFactor;
                    if (lastHitObject.HyperdashDistance <= 10)
                    {
                        additionBonus += 0.3 * bonusFactor;
                    }
                }
                addition += 7.5 * Math.Min(Math.Abs(LastMovement), Constants.NormalizedHitobjectRadius * 2) / (Constants.NormalizedHitobjectRadius * 6) / sqrtTime;
            }
            if (lastHitObject.HyperdashDistance <= 10)
            {
                if (!lastHitObject.HyperDash)
                {
                    additionBonus += 1;
                }
                else
                {
                    Offset = 0;
                }
                addition *= 1 + additionBonus * ((10 - lastHitObject.HyperdashDistance) / 10);
            }
            addition *= 850.0 / Math.Max(time, 25);
            Strain    = lastHitObject.Strain * decay + addition;
        }
예제 #2
0
        double CalcDifficulty()
        {
            double                   strainStep    = Constants.StrainStep * TimeRate;
            List <double>            highestStrain = new List <double>();
            double                   interval      = strainStep;
            double                   maxStrain     = 0;
            CatchDifficultyHitObject last          = null;

            foreach (var difficultyHitObject in DifficultyHitObjects)
            {
                while (difficultyHitObject.HitObject.Offset > interval)
                {
                    highestStrain.Add(maxStrain);
                    if (last is null)
                    {
                        maxStrain = 0;
                    }
                    else
                    {
                        double decay = Math.Pow(Constants.DecayBase, (interval - last.HitObject.Offset) / 1000);
                        maxStrain = last.Strain * decay;
                    }
                    interval += strainStep;
                }
                if (difficultyHitObject.Strain > maxStrain)
                {
                    maxStrain = difficultyHitObject.Strain;
                }
                last = difficultyHitObject;
            }
            double difficulty = 0, weight = 1;
            var    revserSortedList = from l in highestStrain orderby(int) l descending select l;

            foreach (var strain in revserSortedList)
            {
                difficulty += weight * strain;
                weight     *= Constants.DecayWeight;
            }
            return(difficulty);
        }