osu!tp's difficulty calculator ported to the osu! sdk as far as so far possible.
Inheritance: osu.GameModes.Edit.AiMod.AiModRuleset
        private void CalculateSpecificStrain(tpHitObject PreviousHitObject, AiModtpDifficulty.DifficultyType Type)
        {
            double Addition = 0;
            double TimeElapsed = BaseHitObject.StartTime - PreviousHitObject.BaseHitObject.StartTime;
            double Decay = Math.Pow(DECAY_BASE[(int)Type], TimeElapsed / 1000);

            if ((BaseHitObject.Type & HitObjectType.Spinner) > 0)
            {
                // Do nothing for spinners
            }
            else if ((BaseHitObject.Type & HitObjectType.Slider) > 0)
            {
                switch(Type)
                {
                    case AiModtpDifficulty.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 * (PreviousHitObject.BaseHitObject.SegmentCount - 1) +
                                          DistanceTo(PreviousHitObject), Type) *
                            SPACING_WEIGHT_SCALING[(int)Type];
                        break;

                    case AiModtpDifficulty.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) * (PreviousHitObject.BaseHitObject.SegmentCount - 1) +
                                SpacingWeight(DistanceTo(PreviousHitObject), Type)
                            ) *
                            SPACING_WEIGHT_SCALING[(int)Type];
                        break;
                }

            }
            else if ((BaseHitObject.Type & HitObjectType.Normal) > 0)
            {
                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;
        }
        // Caution: The subjective values are strong with this one
        private static double SpacingWeight(double distance, AiModtpDifficulty.DifficultyType Type)
        {
            switch(Type)
            {
                case AiModtpDifficulty.DifficultyType.Speed:

                    {
                        double Weight;

                        if (distance > SINGLE_SPACING_TRESHOLD)
                        {
                            Weight = 2.5;
                        }
                        else if (distance > STREAM_SPACING_TRESHOLD)
                        {
                            Weight = 1.6 + 0.9 * (distance - STREAM_SPACING_TRESHOLD) / (SINGLE_SPACING_TRESHOLD - STREAM_SPACING_TRESHOLD);
                        }
                        else if (distance > ALMOST_DIAMETER)
                        {
                            Weight = 1.2 + 0.4 * (distance - ALMOST_DIAMETER) / (STREAM_SPACING_TRESHOLD - ALMOST_DIAMETER);
                        }
                        else if (distance > ALMOST_DIAMETER / 2)
                        {
                            Weight = 0.95 + 0.25 * (distance - (ALMOST_DIAMETER / 2)) / (ALMOST_DIAMETER / 2);
                        }
                        else
                        {
                            Weight = 0.95;
                        }

                        return Weight;
                    }

                case AiModtpDifficulty.DifficultyType.Aim:

                    return Math.Pow(distance, 0.99);

                    // Should never happen.
                default:
                    return 0;
            }
        }