Example #1
0
        /// <summary>
        /// Computes the progress along the curve relative to how much of the <see cref="HitObject"/> has been completed.
        /// </summary>
        /// <param name="obj">The curve.</param>
        /// <param name="progress">[0, 1] where 0 is the start time of the <see cref="HitObject"/> and 1 is the end time of the <see cref="HitObject"/>.</param>
        /// <returns>[0, 1] where 0 is the beginning of the curve and 1 is the end of the curve.</returns>
        public static double ProgressAt(this IHasPathWithRepeats obj, double progress)
        {
            double p = progress * obj.SpanCount() % 1;

            if (obj.SpanAt(progress) % 2 == 1)
            {
                p = 1 - p;
            }
            return(p);
        }
Example #2
0
 /// <summary>
 /// Determines which span of the curve the progress point is on.
 /// </summary>
 /// <param name="obj">The curve.</param>
 /// <param name="progress">[0, 1] where 0 is the beginning of the curve and 1 is the end of the curve.</param>
 /// <returns>[0, SpanCount) where 0 is the first run.</returns>
 public static int SpanAt(this IHasPathWithRepeats obj, double progress)
 => (int)(progress * obj.SpanCount());
Example #3
0
 /// <summary>
 /// Computes the position on the curve relative to how much of the <see cref="HitObject"/> has been completed.
 /// </summary>
 /// <param name="obj">The curve.</param>
 /// <param name="progress">[0, 1] where 0 is the start time of the <see cref="HitObject"/> and 1 is the end time of the <see cref="HitObject"/>.</param>
 /// <returns>The position on the curve.</returns>
 public static Vector2 CurvePositionAt(this IHasPathWithRepeats obj, double progress)
 => obj.Path.PositionAt(obj.ProgressAt(progress));
        public static IEnumerable <BosuHitObject> ConvertBuzzSlider(HitObject obj, Vector2 originalPosition, IBeatmap beatmap, IHasPathWithRepeats curve, double spanDuration)
        {
            List <BosuHitObject> converted = new List <BosuHitObject>();

            var difficulty = beatmap.BeatmapInfo.BaseDifficulty;

            var controlPointInfo = beatmap.ControlPointInfo;
            TimingControlPoint     timingPoint     = controlPointInfo.TimingPointAt(obj.StartTime);
            DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(obj.StartTime);

            double scoringDistance = 100 * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier;

            var velocity     = scoringDistance / timingPoint.BeatLength;
            var tickDistance = scoringDistance / difficulty.SliderTickRate;

            double legacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0;

            foreach (var e in SliderEventGenerator.Generate(obj.StartTime, spanDuration, velocity, tickDistance, curve.Path.Distance, curve.RepeatCount + 1, legacyLastTickOffset, new CancellationToken()))
            {
                var sliderEventPosition = toPlayfieldSpace(originalPosition) * new Vector2(1, 0.4f);

                switch (e.Type)
                {
                case SliderEventType.Head:
                    converted.AddRange(generateExplosion(e.Time, bullets_per_slider_reverse, sliderEventPosition));
                    break;

                case SliderEventType.Repeat:
                    converted.AddRange(generateExplosion(e.Time, bullets_per_slider_reverse, sliderEventPosition, slider_angle_per_span * (e.SpanIndex + 1)));
                    break;

                case SliderEventType.Tail:
                    converted.AddRange(generateExplosion(e.Time, bullets_per_slider_reverse, sliderEventPosition, slider_angle_per_span * (curve.RepeatCount + 1)));
                    break;
                }
            }

            return(converted);
        }
        public static IEnumerable <BosuHitObject> ConvertDefaultSlider(HitObject obj, Vector2 originalPosition, IBeatmap beatmap, IHasPathWithRepeats curve, double spanDuration)
        {
            List <BosuHitObject> converted = new List <BosuHitObject>();

            var difficulty = beatmap.BeatmapInfo.BaseDifficulty;

            var controlPointInfo = beatmap.ControlPointInfo;
            TimingControlPoint     timingPoint     = controlPointInfo.TimingPointAt(obj.StartTime);
            DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(obj.StartTime);

            double scoringDistance = 100 * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier;

            var velocity     = scoringDistance / timingPoint.BeatLength;
            var tickDistance = scoringDistance / difficulty.SliderTickRate;

            double legacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0;

            foreach (var e in SliderEventGenerator.Generate(obj.StartTime, spanDuration, velocity, tickDistance, curve.Path.Distance, curve.RepeatCount + 1, legacyLastTickOffset, new CancellationToken()))
            {
                var curvePosition       = curve.CurvePositionAt(e.PathProgress / (curve.RepeatCount + 1)) + originalPosition;
                var sliderEventPosition = toPlayfieldSpace(curvePosition) * new Vector2(1, 0.4f);

                switch (e.Type)
                {
                case SliderEventType.Repeat:
                    converted.AddRange(generateExplosion(e.Time, Math.Clamp((int)curve.Distance / 15, 3, 15), sliderEventPosition, MathExtensions.GetRandomTimedAngleOffset(e.Time)));
                    break;

                case SliderEventType.Tail:
                    converted.AddRange(generateExplosion(e.Time, Math.Clamp((int)curve.Distance * (curve.RepeatCount + 1) / 15, 5, 20), sliderEventPosition, MathExtensions.GetRandomTimedAngleOffset(e.Time)));
                    break;
                }
            }

            return(converted);
        }
        public static IEnumerable <BosuHitObject> GenerateSliderBody(double startTime, IHasPathWithRepeats curve, Vector2 originalPosition)
        {
            var bodyCherriesCount = Math.Min(curve.Distance * (curve.RepeatCount + 1) / 10, max_visuals_per_slider_span * (curve.RepeatCount + 1));

            for (int i = 0; i < bodyCherriesCount; i++)
            {
                var progress = (float)i / bodyCherriesCount;
                var position = curve.CurvePositionAt(progress) + originalPosition;
                position = toPlayfieldSpace(position) * new Vector2(1, 0.4f);

                yield return(new InstantCherry
                {
                    StartTime = startTime + curve.Duration * progress,
                    Position = position
                });
            }
        }