private void CalculateSpecificStrain(tpHitObject PreviousHitObject, DifficultyType Type) { double Addition = 0; double TimeElapsed = BaseHitObject.StartTime - PreviousHitObject.BaseHitObject.StartTime; double Decay = Math.Pow(DECAY_BASE[(int)Type], TimeElapsed / 1000); if (BaseHitObject.GetType() == typeof(SpinnerObject)) { // Do nothing for spinners } else if (BaseHitObject.GetType() == typeof(SliderObject)) { switch(Type) { case DifficultyType.Speed: // For speed strain we treat the whole slider as a single spacing entity, since "Speed" is about how hard it is to click buttons fast. // The spacing weight exists to differentiate between being able to easily alternate or having to single. Addition = SpacingWeight(PreviousHitObject.LazySliderLengthFirst + PreviousHitObject.LazySliderLengthSubsequent * (((SliderObject)BaseHitObject).RepeatCount - 1) + DistanceTo(PreviousHitObject), Type) * SPACING_WEIGHT_SCALING[(int)Type]; break; case DifficultyType.Aim: // For Aim strain we treat each slider segment and the jump after the end of the slider as separate jumps, since movement-wise there is no difference // to multiple jumps. Addition = ( SpacingWeight(PreviousHitObject.LazySliderLengthFirst, Type) + SpacingWeight(PreviousHitObject.LazySliderLengthSubsequent, Type) * (((SliderObject)BaseHitObject).RepeatCount - 1) + SpacingWeight(DistanceTo(PreviousHitObject), Type) ) * SPACING_WEIGHT_SCALING[(int)Type]; break; } } else if (BaseHitObject.GetType() == typeof(CircleObject)) { Addition = SpacingWeight(DistanceTo(PreviousHitObject), Type) * SPACING_WEIGHT_SCALING[(int)Type]; } // Scale addition by the time, that elapsed. Filter out HitObjects that are too close to be played anyway to avoid crazy values by division through close to zero. // You will never find maps that require this amongst ranked maps. Addition /= Math.Max(TimeElapsed, 50); Strains[(int)Type] = PreviousHitObject.Strains[(int)Type] * Decay + Addition; }
public double DistanceTo(tpHitObject other) { // Scale the distance by circle size. return (NormalizedStartPosition - (other.NormalizedEndPosition ?? other.NormalizedStartPosition)).Length; }
public void CalculateStrains(tpHitObject PreviousHitObject) { CalculateSpecificStrain(PreviousHitObject, DifficultyType.Speed); CalculateSpecificStrain(PreviousHitObject, DifficultyType.Aim); }