@rian8337/osu-base 4.0.0-beta.61 → 4.0.0-beta.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -310,6 +310,29 @@ exports.Anchor = void 0;
310
310
  Anchor["bottomRight"] = "BottomRight";
311
311
  })(exports.Anchor || (exports.Anchor = {}));
312
312
 
313
+ /**
314
+ * Defines available axes.
315
+ */
316
+ exports.Axes = void 0;
317
+ (function (Axes) {
318
+ /**
319
+ * No axis.
320
+ */
321
+ Axes[Axes["none"] = 0] = "none";
322
+ /**
323
+ * The X axis.
324
+ */
325
+ Axes[Axes["x"] = 1] = "x";
326
+ /**
327
+ * The Y axis.
328
+ */
329
+ Axes[Axes["y"] = 2] = "y";
330
+ /**
331
+ * The X and Y axes.
332
+ */
333
+ Axes[Axes["both"] = 3] = "both";
334
+ })(exports.Axes || (exports.Axes = {}));
335
+
313
336
  /**
314
337
  * The loop type of storyboard animations.
315
338
  */
@@ -1836,16 +1859,6 @@ class Slider extends HitObject {
1836
1859
  * This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991).
1837
1860
  */
1838
1861
  this.generateTicks = true;
1839
- /**
1840
- * The distance travelled by the cursor upon completion of this slider if it was hit
1841
- * with as few movements as possible. This is set and used by difficulty calculation.
1842
- */
1843
- this.lazyTravelDistance = 0;
1844
- /**
1845
- * The time taken by the cursor upon completion of this slider if it was hit with
1846
- * as few movements as possible. This is set and used by difficulty calculation.
1847
- */
1848
- this.lazyTravelTime = 0;
1849
1862
  this._path = values.path;
1850
1863
  this.nodeSamples = values.nodeSamples;
1851
1864
  this._repeatCount = values.repeatCount;
@@ -2216,6 +2229,9 @@ class ModDifficultyAdjust extends Mod {
2216
2229
  return rate;
2217
2230
  }
2218
2231
  toString() {
2232
+ if (!this.isRelevant) {
2233
+ return super.toString();
2234
+ }
2219
2235
  const settings = [];
2220
2236
  if (this.cs !== undefined) {
2221
2237
  settings.push(`CS${this.cs.toFixed(1)}`);
@@ -2869,6 +2885,134 @@ class SliderPath {
2869
2885
  }
2870
2886
  }
2871
2887
 
2888
+ /**
2889
+ * Utilities for {@link HitObject} generation.
2890
+ */
2891
+ class HitObjectGenerationUtils {
2892
+ /**
2893
+ * Reflects the position of a {@link HitObject} horizontally along the playfield.
2894
+ *
2895
+ * @param hitObject The {@link HitObject} to reflect.
2896
+ */
2897
+ static reflectHorizontallyAlongPlayfield(hitObject) {
2898
+ // Reflect the position of the hit object.
2899
+ hitObject.position = this.reflectVectorHorizontallyAlongPlayfield(hitObject.position);
2900
+ if (!(hitObject instanceof Slider)) {
2901
+ return;
2902
+ }
2903
+ // Reflect the control points of the slider. This will reflect the positions of head and tail circles.
2904
+ hitObject.path = new SliderPath({
2905
+ pathType: hitObject.path.pathType,
2906
+ controlPoints: hitObject.path.controlPoints.map((v) => new Vector2(-v.x, v.y)),
2907
+ expectedDistance: hitObject.path.expectedDistance,
2908
+ });
2909
+ // Reflect the position of slider ticks and repeats.
2910
+ hitObject.nestedHitObjects.slice(1, -1).forEach((obj) => {
2911
+ obj.position = this.reflectVectorHorizontallyAlongPlayfield(obj.position);
2912
+ });
2913
+ }
2914
+ /**
2915
+ * Reflects the position of a {@link HitObject} vertically along the playfield.
2916
+ *
2917
+ * @param hitObject The {@link HitObject} to reflect.
2918
+ */
2919
+ static reflectVerticallyAlongPlayfield(hitObject) {
2920
+ // Reflect the position of the hit object.
2921
+ hitObject.position = this.reflectVectorVerticallyAlongPlayfield(hitObject.position);
2922
+ if (!(hitObject instanceof Slider)) {
2923
+ return;
2924
+ }
2925
+ // Reflect the control points of the slider. This will reflect the positions of head and tail circles.
2926
+ hitObject.path = new SliderPath({
2927
+ pathType: hitObject.path.pathType,
2928
+ controlPoints: hitObject.path.controlPoints.map((v) => new Vector2(v.x, -v.y)),
2929
+ expectedDistance: hitObject.path.expectedDistance,
2930
+ });
2931
+ // Reflect the position of slider ticks and repeats.
2932
+ hitObject.nestedHitObjects.slice(1, -1).forEach((obj) => {
2933
+ obj.position = this.reflectVectorVerticallyAlongPlayfield(obj.position);
2934
+ });
2935
+ }
2936
+ static reflectVectorHorizontallyAlongPlayfield(vector) {
2937
+ return new Vector2(Playfield.baseSize.x - vector.x, vector.y);
2938
+ }
2939
+ static reflectVectorVerticallyAlongPlayfield(vector) {
2940
+ return new Vector2(vector.x, Playfield.baseSize.y - vector.y);
2941
+ }
2942
+ }
2943
+
2944
+ /**
2945
+ * Represents the Mirror mod.
2946
+ */
2947
+ class ModMirror extends Mod {
2948
+ constructor() {
2949
+ super();
2950
+ this.name = "Mirror";
2951
+ this.acronym = "MR";
2952
+ this.droidRanked = false;
2953
+ this.osuRanked = false;
2954
+ /**
2955
+ * The axes to reflect the `HitObject`s along.
2956
+ */
2957
+ this.flippedAxes = exports.Axes.x;
2958
+ this.incompatibleMods.add(ModHardRock);
2959
+ }
2960
+ get isDroidRelevant() {
2961
+ return true;
2962
+ }
2963
+ calculateDroidScoreMultiplier() {
2964
+ return 1;
2965
+ }
2966
+ get isOsuRelevant() {
2967
+ return true;
2968
+ }
2969
+ get osuScoreMultiplier() {
2970
+ return 1;
2971
+ }
2972
+ copySettings(mod) {
2973
+ var _a;
2974
+ super.copySettings(mod);
2975
+ switch ((_a = mod.settings) === null || _a === void 0 ? void 0 : _a.flippedAxes) {
2976
+ case 0:
2977
+ this.flippedAxes = exports.Axes.x;
2978
+ break;
2979
+ case 1:
2980
+ this.flippedAxes = exports.Axes.y;
2981
+ break;
2982
+ case 2:
2983
+ this.flippedAxes = exports.Axes.both;
2984
+ break;
2985
+ }
2986
+ }
2987
+ applyToHitObject(_, hitObject) {
2988
+ switch (this.flippedAxes) {
2989
+ case exports.Axes.x:
2990
+ HitObjectGenerationUtils.reflectHorizontallyAlongPlayfield(hitObject);
2991
+ break;
2992
+ case exports.Axes.y:
2993
+ HitObjectGenerationUtils.reflectVerticallyAlongPlayfield(hitObject);
2994
+ break;
2995
+ case exports.Axes.both:
2996
+ HitObjectGenerationUtils.reflectHorizontallyAlongPlayfield(hitObject);
2997
+ HitObjectGenerationUtils.reflectVerticallyAlongPlayfield(hitObject);
2998
+ break;
2999
+ }
3000
+ }
3001
+ serializeSettings() {
3002
+ return { flippedAxes: this.flippedAxes - 1 };
3003
+ }
3004
+ toString() {
3005
+ const settings = [];
3006
+ if (this.flippedAxes === exports.Axes.x || this.flippedAxes === exports.Axes.both) {
3007
+ settings.push("↔");
3008
+ }
3009
+ if (this.flippedAxes === exports.Axes.y || this.flippedAxes === exports.Axes.both) {
3010
+ settings.push("↕");
3011
+ }
3012
+ return `${super.toString()} (${settings.join(", ")})`;
3013
+ }
3014
+ }
3015
+
2872
3016
  /**
2873
3017
  * Represents the HardRock mod.
2874
3018
  */
@@ -2881,6 +3025,7 @@ class ModHardRock extends Mod {
2881
3025
  this.osuRanked = true;
2882
3026
  this.bitwise = 1 << 4;
2883
3027
  this.incompatibleMods.add(ModEasy);
3028
+ this.incompatibleMods.add(ModMirror);
2884
3029
  }
2885
3030
  get isDroidRelevant() {
2886
3031
  return true;
@@ -2911,21 +3056,7 @@ class ModHardRock extends Mod {
2911
3056
  difficulty.hp = this.applySetting(difficulty.hp);
2912
3057
  }
2913
3058
  applyToHitObject(_, hitObject) {
2914
- // Reflect the position of the hit object.
2915
- hitObject.position = this.reflectVector(hitObject.position);
2916
- if (!(hitObject instanceof Slider)) {
2917
- return;
2918
- }
2919
- // Reflect the control points of the slider. This will reflect the positions of head and tail circles.
2920
- hitObject.path = new SliderPath({
2921
- pathType: hitObject.path.pathType,
2922
- controlPoints: hitObject.path.controlPoints.map((v) => this.reflectControlPoint(v)),
2923
- expectedDistance: hitObject.path.expectedDistance,
2924
- });
2925
- // Reflect the position of slider ticks and repeats.
2926
- hitObject.nestedHitObjects.slice(1, -1).forEach((obj) => {
2927
- obj.position = this.reflectVector(obj.position);
2928
- });
3059
+ HitObjectGenerationUtils.reflectVerticallyAlongPlayfield(hitObject);
2929
3060
  }
2930
3061
  reflectVector(vector) {
2931
3062
  return new Vector2(vector.x, Playfield.baseSize.y - vector.y);
@@ -3365,20 +3496,394 @@ class ModSpunOut extends Mod {
3365
3496
  return true;
3366
3497
  }
3367
3498
  get osuScoreMultiplier() {
3368
- return 0.9;
3499
+ return 0.9;
3500
+ }
3501
+ }
3502
+
3503
+ /**
3504
+ * Represents the Synesthesia mod in osu! and osu!droid.
3505
+ */
3506
+ class ModSynesthesia extends Mod {
3507
+ constructor() {
3508
+ super(...arguments);
3509
+ this.name = "Synesthesia";
3510
+ this.acronym = "SY";
3511
+ this.droidRanked = false;
3512
+ this.osuRanked = false;
3513
+ }
3514
+ get isDroidRelevant() {
3515
+ return true;
3516
+ }
3517
+ calculateDroidScoreMultiplier() {
3518
+ return 0.8;
3519
+ }
3520
+ get isOsuRelevant() {
3521
+ return true;
3522
+ }
3523
+ get osuScoreMultiplier() {
3524
+ return 0.8;
3525
+ }
3526
+ }
3527
+
3528
+ /**
3529
+ * Represents the TouchDevice mod.
3530
+ */
3531
+ class ModTouchDevice extends Mod {
3532
+ constructor() {
3533
+ super(...arguments);
3534
+ this.acronym = "TD";
3535
+ this.name = "TouchDevice";
3536
+ this.osuRanked = true;
3537
+ this.bitwise = 1 << 2;
3538
+ }
3539
+ get isOsuRelevant() {
3540
+ return true;
3541
+ }
3542
+ get osuScoreMultiplier() {
3543
+ return 1;
3544
+ }
3545
+ }
3546
+
3547
+ /**
3548
+ * Types of easing.
3549
+ *
3550
+ * See {@link http://easings.net/ this} page for more samples.
3551
+ */
3552
+ exports.Easing = void 0;
3553
+ (function (Easing) {
3554
+ Easing[Easing["none"] = 0] = "none";
3555
+ Easing[Easing["out"] = 1] = "out";
3556
+ Easing[Easing["in"] = 2] = "in";
3557
+ Easing[Easing["inQuad"] = 3] = "inQuad";
3558
+ Easing[Easing["outQuad"] = 4] = "outQuad";
3559
+ Easing[Easing["inOutQuad"] = 5] = "inOutQuad";
3560
+ Easing[Easing["inCubic"] = 6] = "inCubic";
3561
+ Easing[Easing["outCubic"] = 7] = "outCubic";
3562
+ Easing[Easing["inOutCubic"] = 8] = "inOutCubic";
3563
+ Easing[Easing["inQuart"] = 9] = "inQuart";
3564
+ Easing[Easing["outQuart"] = 10] = "outQuart";
3565
+ Easing[Easing["inOutQuart"] = 11] = "inOutQuart";
3566
+ Easing[Easing["inQuint"] = 12] = "inQuint";
3567
+ Easing[Easing["outQuint"] = 13] = "outQuint";
3568
+ Easing[Easing["inOutQuint"] = 14] = "inOutQuint";
3569
+ Easing[Easing["inSine"] = 15] = "inSine";
3570
+ Easing[Easing["outSine"] = 16] = "outSine";
3571
+ Easing[Easing["inOutSine"] = 17] = "inOutSine";
3572
+ Easing[Easing["inExpo"] = 18] = "inExpo";
3573
+ Easing[Easing["outExpo"] = 19] = "outExpo";
3574
+ Easing[Easing["inOutExpo"] = 20] = "inOutExpo";
3575
+ Easing[Easing["inCirc"] = 21] = "inCirc";
3576
+ Easing[Easing["outCirc"] = 22] = "outCirc";
3577
+ Easing[Easing["inOutCirc"] = 23] = "inOutCirc";
3578
+ Easing[Easing["inElastic"] = 24] = "inElastic";
3579
+ Easing[Easing["outElastic"] = 25] = "outElastic";
3580
+ Easing[Easing["outElasticHalf"] = 26] = "outElasticHalf";
3581
+ Easing[Easing["outElasticQuarter"] = 27] = "outElasticQuarter";
3582
+ Easing[Easing["inOutElastic"] = 28] = "inOutElastic";
3583
+ Easing[Easing["inBack"] = 29] = "inBack";
3584
+ Easing[Easing["outBack"] = 30] = "outBack";
3585
+ Easing[Easing["inOutBack"] = 31] = "inOutBack";
3586
+ Easing[Easing["inBounce"] = 32] = "inBounce";
3587
+ Easing[Easing["outBounce"] = 33] = "outBounce";
3588
+ Easing[Easing["inOutBounce"] = 34] = "inOutBounce";
3589
+ Easing[Easing["outPow10"] = 35] = "outPow10";
3590
+ })(exports.Easing || (exports.Easing = {}));
3591
+
3592
+ /**
3593
+ * Holds interpolation methods for numbers and vectors.
3594
+ */
3595
+ class Interpolation {
3596
+ static lerp(start, final, amount) {
3597
+ if (start instanceof Vector2 && final instanceof Vector2) {
3598
+ return new Vector2(this.lerp(start.x, final.x, amount), this.lerp(start.y, final.y, amount));
3599
+ }
3600
+ else {
3601
+ return (start +
3602
+ (final - start) * amount);
3603
+ }
3604
+ }
3605
+ /**
3606
+ * Calculates the reverse [linear interpolation](https://en.wikipedia.org/wiki/Linear_interpolation)
3607
+ * function at `x`.
3608
+ *
3609
+ * @param x The value to calculate the function for.
3610
+ * @param start The `x` value at which the function returns 0.
3611
+ * @param end The `x` value at which the function returns 1.
3612
+ * @return The output of the reverse linear interpolation function calculated at `x`.
3613
+ */
3614
+ static reverseLerp(x, start, end) {
3615
+ return MathUtils.clamp((x - start) / (end - start), 0, 1);
3616
+ }
3617
+ /**
3618
+ * Interpolates a value using an easing function.
3619
+ *
3620
+ * @param easing The easing function to use.
3621
+ * @param t The progress of the interpolation, from 0 to 1.
3622
+ * @returns The interpolated value.
3623
+ */
3624
+ static easing(easing, t) {
3625
+ switch (easing) {
3626
+ case exports.Easing.none:
3627
+ return t;
3628
+ case exports.Easing.out:
3629
+ case exports.Easing.outQuad:
3630
+ return t * (2 - t);
3631
+ case exports.Easing.in:
3632
+ case exports.Easing.inQuad:
3633
+ return t * t;
3634
+ case exports.Easing.inOutQuad:
3635
+ return t < 0.5 ? t * t * 2 : --t * t * -2 + 1;
3636
+ case exports.Easing.inCubic:
3637
+ return t * t * t;
3638
+ case exports.Easing.outCubic:
3639
+ return --t * t * t + 1;
3640
+ case exports.Easing.inOutCubic:
3641
+ return t < 0.5 ? t * t * t * 4 : --t * t * t * 4 + 1;
3642
+ case exports.Easing.inQuart:
3643
+ return t * t * t * t;
3644
+ case exports.Easing.outQuart:
3645
+ return 1 - --t * t * t * t;
3646
+ case exports.Easing.inOutQuart:
3647
+ return t < 0.5 ? t * t * t * t * 8 : --t * t * t * t * -8 + 1;
3648
+ case exports.Easing.inQuint:
3649
+ return t * t * t * t * t;
3650
+ case exports.Easing.outQuint:
3651
+ return --t * t * t * t * t + 1;
3652
+ case exports.Easing.inOutQuint:
3653
+ return t < 0.5
3654
+ ? t * t * t * t * t * 16
3655
+ : --t * t * t * t * t * 16 + 1;
3656
+ case exports.Easing.inSine:
3657
+ return 1 - Math.cos((t * Math.PI) / 2);
3658
+ case exports.Easing.outSine:
3659
+ return Math.sin((t * Math.PI) / 2);
3660
+ case exports.Easing.inOutSine:
3661
+ return 0.5 - 0.5 * Math.cos(Math.PI * t);
3662
+ case exports.Easing.inExpo:
3663
+ return t === 0 ? 0 : Math.pow(2, 10 * t - 10);
3664
+ case exports.Easing.outExpo:
3665
+ return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
3666
+ case exports.Easing.inOutExpo:
3667
+ if (t === 0) {
3668
+ return 0;
3669
+ }
3670
+ if (t === 1) {
3671
+ return 1;
3672
+ }
3673
+ if ((t *= 2) < 1) {
3674
+ return 0.5 * Math.pow(2, 10 * t - 10);
3675
+ }
3676
+ return 0.5 * (2 - Math.pow(2, -10 * --t));
3677
+ case exports.Easing.inCirc:
3678
+ return 1 - Math.sqrt(1 - t * t);
3679
+ case exports.Easing.outCirc:
3680
+ return Math.sqrt(1 - --t * t);
3681
+ case exports.Easing.inOutCirc:
3682
+ return (t *= 2) < 1
3683
+ ? 0.5 - 0.5 * Math.sqrt(1 - t * t)
3684
+ : 0.5 * Math.sqrt(1 - (t -= 2) * t) + 0.5;
3685
+ case exports.Easing.inElastic:
3686
+ return (-Math.pow(2, -10 + 10 * t) *
3687
+ Math.sin((1 - 0.3 / 4 - t) * ((2 * Math.PI) / 0.3)));
3688
+ case exports.Easing.outElastic:
3689
+ return (Math.pow(2, -10 * t) *
3690
+ Math.sin((t - 0.3 / 4) * ((2 * Math.PI) / 0.3)) +
3691
+ 1);
3692
+ case exports.Easing.outElasticHalf:
3693
+ return (Math.pow(2, -10 * t) *
3694
+ Math.sin((0.5 * t - 0.3 / 4) * ((2 * Math.PI) / 0.3)) +
3695
+ 1);
3696
+ case exports.Easing.outElasticQuarter:
3697
+ return (Math.pow(2, -10 * t) *
3698
+ Math.sin((0.25 * t - 0.3 / 4) * ((2 * Math.PI) / 0.3)) +
3699
+ 1);
3700
+ case exports.Easing.inOutElastic:
3701
+ if (t === 0) {
3702
+ return 0;
3703
+ }
3704
+ if (t === 1) {
3705
+ return 1;
3706
+ }
3707
+ if ((t *= 2) < 1) {
3708
+ return (-0.5 *
3709
+ Math.pow(2, -10 + 10 * t) *
3710
+ Math.sin(((1 - (0.3 / 4) * 1.5 - t) *
3711
+ ((2 * Math.PI) / 0.3)) /
3712
+ 1.5));
3713
+ }
3714
+ return (0.5 *
3715
+ Math.pow(2, -10 * --t) *
3716
+ Math.sin(((t - (0.3 / 4) * 1.5) * ((2 * Math.PI) / 0.3)) /
3717
+ 1.5) +
3718
+ 1);
3719
+ case exports.Easing.inBack:
3720
+ return t * t * ((1.70158 + 1) * t - 1.70158);
3721
+ case exports.Easing.outBack:
3722
+ return --t * t * ((1.70158 + 1) * t + 1.70158) + 1;
3723
+ case exports.Easing.inOutBack:
3724
+ return (t *= 2) < 1
3725
+ ? 0.5 *
3726
+ t *
3727
+ t *
3728
+ ((1.70158 * 1.525 + 1) * t - 1.70158 * 1.525)
3729
+ : 0.5 *
3730
+ ((t -= 2) *
3731
+ t *
3732
+ ((1.70158 * 1.525 + 1) * t + 1.70158 * 1.525) +
3733
+ 2);
3734
+ case exports.Easing.inBounce:
3735
+ t = 1 - t;
3736
+ if (t < 1 / 2.75) {
3737
+ return 1 - 7.5625 * t * t;
3738
+ }
3739
+ if (t < 2 / 2.75) {
3740
+ return 1 - (7.5625 * (t -= 1.5 / 2.75) * t + 0.75);
3741
+ }
3742
+ if (t < 2.5 / 2.75) {
3743
+ return 1 - (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375);
3744
+ }
3745
+ return 1 - (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375);
3746
+ case exports.Easing.outBounce:
3747
+ if (t < 1 / 2.75) {
3748
+ return 7.5625 * t * t;
3749
+ }
3750
+ if (t < 2 / 2.75) {
3751
+ return 7.5625 * (t -= 1.5 / 2.75) * t + 0.75;
3752
+ }
3753
+ if (t < 2.5 / 2.75) {
3754
+ return 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375;
3755
+ }
3756
+ return 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375;
3757
+ case exports.Easing.inOutBounce:
3758
+ return t < 0.5
3759
+ ? 0.5 - 0.5 * this.easing(exports.Easing.outBounce, 1 - t * 2)
3760
+ : 0.5 * this.easing(exports.Easing.outBounce, (t - 0.5) * 2) + 0.5;
3761
+ case exports.Easing.outPow10:
3762
+ return --t * Math.pow(t, 10) + 1;
3763
+ }
3764
+ }
3765
+ }
3766
+
3767
+ /**
3768
+ * Represents a mod that gradually adjusts the track's playback rate over time.
3769
+ */
3770
+ class ModTimeRamp extends Mod {
3771
+ constructor() {
3772
+ super();
3773
+ this.initialRateTime = 0;
3774
+ this.finalRateTime = 0;
3775
+ this.incompatibleMods.add(ModTimeRamp);
3776
+ }
3777
+ copySettings(mod) {
3778
+ var _a, _b;
3779
+ super.copySettings(mod);
3780
+ const { settings } = mod;
3781
+ this.initialRate = (_a = settings === null || settings === void 0 ? void 0 : settings.initialRate) !== null && _a !== void 0 ? _a : 1;
3782
+ this.finalRate = (_b = settings === null || settings === void 0 ? void 0 : settings.finalRate) !== null && _b !== void 0 ? _b : 1;
3783
+ }
3784
+ applyToBeatmap(beatmap) {
3785
+ var _a, _b, _c, _d;
3786
+ this.initialRateTime = (_b = (_a = beatmap.hitObjects.objects.at(0)) === null || _a === void 0 ? void 0 : _a.startTime) !== null && _b !== void 0 ? _b : 0;
3787
+ this.finalRateTime = Interpolation.lerp(this.initialRateTime, (_d = (_c = beatmap.hitObjects.objects.at(-1)) === null || _c === void 0 ? void 0 : _c.endTime) !== null && _d !== void 0 ? _d : 0, ModTimeRamp.finalRateProgress);
3788
+ }
3789
+ applyToRate(time, rate) {
3790
+ const amount = (time - this.initialRateTime) /
3791
+ (this.finalRateTime - this.initialRateTime);
3792
+ return (rate * Interpolation.lerp(this.initialRate, this.finalRate, amount));
3793
+ }
3794
+ serializeSettings() {
3795
+ return { initialRate: this.initialRate, finalRate: this.finalRate };
3796
+ }
3797
+ toString() {
3798
+ return `${super.toString()} (${this.initialRate.toFixed(2)}x - ${this.finalRate.toFixed(2)}x)`;
3799
+ }
3800
+ }
3801
+ /**
3802
+ * The point in the beatmap at which the final rate should be reached.
3803
+ */
3804
+ ModTimeRamp.finalRateProgress = 0.75;
3805
+
3806
+ /**
3807
+ * Represents the Wind Down mod.
3808
+ */
3809
+ class ModWindDown extends ModTimeRamp {
3810
+ constructor() {
3811
+ super(...arguments);
3812
+ this.name = "Wind Down";
3813
+ this.acronym = "WD";
3814
+ this._initialRate = 1;
3815
+ this._finalRate = 0.75;
3816
+ this.droidRanked = false;
3817
+ this.osuRanked = false;
3818
+ }
3819
+ get initialRate() {
3820
+ return this._initialRate;
3821
+ }
3822
+ set initialRate(value) {
3823
+ this._initialRate = value;
3824
+ if (value <= this.finalRate) {
3825
+ this.finalRate = value - 0.01;
3826
+ }
3827
+ }
3828
+ get finalRate() {
3829
+ return this._finalRate;
3830
+ }
3831
+ set finalRate(value) {
3832
+ this._finalRate = value;
3833
+ if (value >= this.initialRate) {
3834
+ this.initialRate = value + 0.01;
3835
+ }
3836
+ }
3837
+ get isDroidRelevant() {
3838
+ return true;
3839
+ }
3840
+ calculateDroidScoreMultiplier() {
3841
+ return 1;
3842
+ }
3843
+ get isOsuRelevant() {
3844
+ return true;
3845
+ }
3846
+ get osuScoreMultiplier() {
3847
+ return 1;
3369
3848
  }
3370
3849
  }
3371
3850
 
3372
3851
  /**
3373
- * Represents the TouchDevice mod.
3852
+ * Represents the Wind Up mod.
3374
3853
  */
3375
- class ModTouchDevice extends Mod {
3854
+ class ModWindUp extends ModTimeRamp {
3376
3855
  constructor() {
3377
3856
  super(...arguments);
3378
- this.acronym = "TD";
3379
- this.name = "TouchDevice";
3380
- this.osuRanked = true;
3381
- this.bitwise = 1 << 2;
3857
+ this.acronym = "Wind Up";
3858
+ this.name = "WU";
3859
+ this._initialRate = 1;
3860
+ this._finalRate = 1;
3861
+ this.droidRanked = false;
3862
+ this.osuRanked = false;
3863
+ }
3864
+ get initialRate() {
3865
+ return this._initialRate;
3866
+ }
3867
+ set initialRate(value) {
3868
+ this._initialRate = value;
3869
+ if (value >= this.finalRate) {
3870
+ this.finalRate = value + 0.01;
3871
+ }
3872
+ }
3873
+ get finalRate() {
3874
+ return this._finalRate;
3875
+ }
3876
+ set finalRate(value) {
3877
+ this._finalRate = value;
3878
+ if (value <= this.initialRate) {
3879
+ this.initialRate = value - 0.01;
3880
+ }
3881
+ }
3882
+ get isDroidRelevant() {
3883
+ return true;
3884
+ }
3885
+ calculateDroidScoreMultiplier() {
3886
+ return 1;
3382
3887
  }
3383
3888
  get isOsuRelevant() {
3384
3889
  return true;
@@ -3597,13 +4102,17 @@ ModUtil.allMods = (() => {
3597
4102
  ModNightCore,
3598
4103
  ModHalfTime,
3599
4104
  ModCustomSpeed,
4105
+ ModWindDown,
4106
+ ModWindUp,
3600
4107
  ModHardRock,
4108
+ ModMirror,
3601
4109
  ModDifficultyAdjust,
3602
4110
  ModFlashlight,
3603
4111
  ModSuddenDeath,
3604
4112
  ModPerfect,
3605
4113
  ModPrecise,
3606
4114
  ModReallyEasy,
4115
+ ModSynesthesia,
3607
4116
  ModScoreV2,
3608
4117
  ModSmallCircle,
3609
4118
  ModSpunOut,
@@ -8249,9 +8758,6 @@ class DroidLegacyModConverter {
8249
8758
  return map;
8250
8759
  }
8251
8760
  const data = str.split("|");
8252
- if (!data[0]) {
8253
- return map;
8254
- }
8255
8761
  for (const c of data[0]) {
8256
8762
  const modType = this.legacyStorableMods.get(c);
8257
8763
  if (!modType) {
@@ -8355,51 +8861,6 @@ DroidLegacyModConverter.legacyStorableMods = new Map([
8355
8861
  ["x", ModRelax],
8356
8862
  ]);
8357
8863
 
8358
- /**
8359
- * Types of easing.
8360
- *
8361
- * See {@link http://easings.net/ this} page for more samples.
8362
- */
8363
- exports.Easing = void 0;
8364
- (function (Easing) {
8365
- Easing[Easing["none"] = 0] = "none";
8366
- Easing[Easing["out"] = 1] = "out";
8367
- Easing[Easing["in"] = 2] = "in";
8368
- Easing[Easing["inQuad"] = 3] = "inQuad";
8369
- Easing[Easing["outQuad"] = 4] = "outQuad";
8370
- Easing[Easing["inOutQuad"] = 5] = "inOutQuad";
8371
- Easing[Easing["inCubic"] = 6] = "inCubic";
8372
- Easing[Easing["outCubic"] = 7] = "outCubic";
8373
- Easing[Easing["inOutCubic"] = 8] = "inOutCubic";
8374
- Easing[Easing["inQuart"] = 9] = "inQuart";
8375
- Easing[Easing["outQuart"] = 10] = "outQuart";
8376
- Easing[Easing["inOutQuart"] = 11] = "inOutQuart";
8377
- Easing[Easing["inQuint"] = 12] = "inQuint";
8378
- Easing[Easing["outQuint"] = 13] = "outQuint";
8379
- Easing[Easing["inOutQuint"] = 14] = "inOutQuint";
8380
- Easing[Easing["inSine"] = 15] = "inSine";
8381
- Easing[Easing["outSine"] = 16] = "outSine";
8382
- Easing[Easing["inOutSine"] = 17] = "inOutSine";
8383
- Easing[Easing["inExpo"] = 18] = "inExpo";
8384
- Easing[Easing["outExpo"] = 19] = "outExpo";
8385
- Easing[Easing["inOutExpo"] = 20] = "inOutExpo";
8386
- Easing[Easing["inCirc"] = 21] = "inCirc";
8387
- Easing[Easing["outCirc"] = 22] = "outCirc";
8388
- Easing[Easing["inOutCirc"] = 23] = "inOutCirc";
8389
- Easing[Easing["inElastic"] = 24] = "inElastic";
8390
- Easing[Easing["outElastic"] = 25] = "outElastic";
8391
- Easing[Easing["outElasticHalf"] = 26] = "outElasticHalf";
8392
- Easing[Easing["outElasticQuarter"] = 27] = "outElasticQuarter";
8393
- Easing[Easing["inOutElastic"] = 28] = "inOutElastic";
8394
- Easing[Easing["inBack"] = 29] = "inBack";
8395
- Easing[Easing["outBack"] = 30] = "outBack";
8396
- Easing[Easing["inOutBack"] = 31] = "inOutBack";
8397
- Easing[Easing["inBounce"] = 32] = "inBounce";
8398
- Easing[Easing["outBounce"] = 33] = "outBounce";
8399
- Easing[Easing["inOutBounce"] = 34] = "inOutBounce";
8400
- Easing[Easing["outPow10"] = 35] = "outPow10";
8401
- })(exports.Easing || (exports.Easing = {}));
8402
-
8403
8864
  /**
8404
8865
  * A single-variable polynomial with real-valued coefficients and non-negative exponents.
8405
8866
  *
@@ -9177,181 +9638,6 @@ ErrorFunction.ervInvImpGd = [
9177
9638
  0.3999688121938621e-6, 0.1618092908879045e-8, 0.2315586083102596e-11,
9178
9639
  ];
9179
9640
 
9180
- /**
9181
- * Holds interpolation methods for numbers and vectors.
9182
- */
9183
- class Interpolation {
9184
- static lerp(start, final, amount) {
9185
- if (start instanceof Vector2 && final instanceof Vector2) {
9186
- return new Vector2(this.lerp(start.x, final.x, amount), this.lerp(start.y, final.y, amount));
9187
- }
9188
- else {
9189
- return (start +
9190
- (final - start) * amount);
9191
- }
9192
- }
9193
- /**
9194
- * Calculates the reverse [linear interpolation](https://en.wikipedia.org/wiki/Linear_interpolation)
9195
- * function at `x`.
9196
- *
9197
- * @param x The value to calculate the function for.
9198
- * @param start The `x` value at which the function returns 0.
9199
- * @param end The `x` value at which the function returns 1.
9200
- * @return The output of the reverse linear interpolation function calculated at `x`.
9201
- */
9202
- static reverseLerp(x, start, end) {
9203
- return MathUtils.clamp((x - start) / (end - start), 0, 1);
9204
- }
9205
- /**
9206
- * Interpolates a value using an easing function.
9207
- *
9208
- * @param easing The easing function to use.
9209
- * @param t The progress of the interpolation, from 0 to 1.
9210
- * @returns The interpolated value.
9211
- */
9212
- static easing(easing, t) {
9213
- switch (easing) {
9214
- case exports.Easing.none:
9215
- return t;
9216
- case exports.Easing.out:
9217
- case exports.Easing.outQuad:
9218
- return t * (2 - t);
9219
- case exports.Easing.in:
9220
- case exports.Easing.inQuad:
9221
- return t * t;
9222
- case exports.Easing.inOutQuad:
9223
- return t < 0.5 ? t * t * 2 : --t * t * -2 + 1;
9224
- case exports.Easing.inCubic:
9225
- return t * t * t;
9226
- case exports.Easing.outCubic:
9227
- return --t * t * t + 1;
9228
- case exports.Easing.inOutCubic:
9229
- return t < 0.5 ? t * t * t * 4 : --t * t * t * 4 + 1;
9230
- case exports.Easing.inQuart:
9231
- return t * t * t * t;
9232
- case exports.Easing.outQuart:
9233
- return 1 - --t * t * t * t;
9234
- case exports.Easing.inOutQuart:
9235
- return t < 0.5 ? t * t * t * t * 8 : --t * t * t * t * -8 + 1;
9236
- case exports.Easing.inQuint:
9237
- return t * t * t * t * t;
9238
- case exports.Easing.outQuint:
9239
- return --t * t * t * t * t + 1;
9240
- case exports.Easing.inOutQuint:
9241
- return t < 0.5
9242
- ? t * t * t * t * t * 16
9243
- : --t * t * t * t * t * 16 + 1;
9244
- case exports.Easing.inSine:
9245
- return 1 - Math.cos((t * Math.PI) / 2);
9246
- case exports.Easing.outSine:
9247
- return Math.sin((t * Math.PI) / 2);
9248
- case exports.Easing.inOutSine:
9249
- return 0.5 - 0.5 * Math.cos(Math.PI * t);
9250
- case exports.Easing.inExpo:
9251
- return t === 0 ? 0 : Math.pow(2, 10 * t - 10);
9252
- case exports.Easing.outExpo:
9253
- return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
9254
- case exports.Easing.inOutExpo:
9255
- if (t === 0) {
9256
- return 0;
9257
- }
9258
- if (t === 1) {
9259
- return 1;
9260
- }
9261
- if ((t *= 2) < 1) {
9262
- return 0.5 * Math.pow(2, 10 * t - 10);
9263
- }
9264
- return 0.5 * (2 - Math.pow(2, -10 * --t));
9265
- case exports.Easing.inCirc:
9266
- return 1 - Math.sqrt(1 - t * t);
9267
- case exports.Easing.outCirc:
9268
- return Math.sqrt(1 - --t * t);
9269
- case exports.Easing.inOutCirc:
9270
- return (t *= 2) < 1
9271
- ? 0.5 - 0.5 * Math.sqrt(1 - t * t)
9272
- : 0.5 * Math.sqrt(1 - (t -= 2) * t) + 0.5;
9273
- case exports.Easing.inElastic:
9274
- return (-Math.pow(2, -10 + 10 * t) *
9275
- Math.sin((1 - 0.3 / 4 - t) * ((2 * Math.PI) / 0.3)));
9276
- case exports.Easing.outElastic:
9277
- return (Math.pow(2, -10 * t) *
9278
- Math.sin((t - 0.3 / 4) * ((2 * Math.PI) / 0.3)) +
9279
- 1);
9280
- case exports.Easing.outElasticHalf:
9281
- return (Math.pow(2, -10 * t) *
9282
- Math.sin((0.5 * t - 0.3 / 4) * ((2 * Math.PI) / 0.3)) +
9283
- 1);
9284
- case exports.Easing.outElasticQuarter:
9285
- return (Math.pow(2, -10 * t) *
9286
- Math.sin((0.25 * t - 0.3 / 4) * ((2 * Math.PI) / 0.3)) +
9287
- 1);
9288
- case exports.Easing.inOutElastic:
9289
- if (t === 0) {
9290
- return 0;
9291
- }
9292
- if (t === 1) {
9293
- return 1;
9294
- }
9295
- if ((t *= 2) < 1) {
9296
- return (-0.5 *
9297
- Math.pow(2, -10 + 10 * t) *
9298
- Math.sin(((1 - (0.3 / 4) * 1.5 - t) *
9299
- ((2 * Math.PI) / 0.3)) /
9300
- 1.5));
9301
- }
9302
- return (0.5 *
9303
- Math.pow(2, -10 * --t) *
9304
- Math.sin(((t - (0.3 / 4) * 1.5) * ((2 * Math.PI) / 0.3)) /
9305
- 1.5) +
9306
- 1);
9307
- case exports.Easing.inBack:
9308
- return t * t * ((1.70158 + 1) * t - 1.70158);
9309
- case exports.Easing.outBack:
9310
- return --t * t * ((1.70158 + 1) * t + 1.70158) + 1;
9311
- case exports.Easing.inOutBack:
9312
- return (t *= 2) < 1
9313
- ? 0.5 *
9314
- t *
9315
- t *
9316
- ((1.70158 * 1.525 + 1) * t - 1.70158 * 1.525)
9317
- : 0.5 *
9318
- ((t -= 2) *
9319
- t *
9320
- ((1.70158 * 1.525 + 1) * t + 1.70158 * 1.525) +
9321
- 2);
9322
- case exports.Easing.inBounce:
9323
- t = 1 - t;
9324
- if (t < 1 / 2.75) {
9325
- return 1 - 7.5625 * t * t;
9326
- }
9327
- if (t < 2 / 2.75) {
9328
- return 1 - (7.5625 * (t -= 1.5 / 2.75) * t + 0.75);
9329
- }
9330
- if (t < 2.5 / 2.75) {
9331
- return 1 - (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375);
9332
- }
9333
- return 1 - (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375);
9334
- case exports.Easing.outBounce:
9335
- if (t < 1 / 2.75) {
9336
- return 7.5625 * t * t;
9337
- }
9338
- if (t < 2 / 2.75) {
9339
- return 7.5625 * (t -= 1.5 / 2.75) * t + 0.75;
9340
- }
9341
- if (t < 2.5 / 2.75) {
9342
- return 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375;
9343
- }
9344
- return 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375;
9345
- case exports.Easing.inOutBounce:
9346
- return t < 0.5
9347
- ? 0.5 - 0.5 * this.easing(exports.Easing.outBounce, 1 - t * 2)
9348
- : 0.5 * this.easing(exports.Easing.outBounce, (t - 0.5) * 2) + 0.5;
9349
- case exports.Easing.outPow10:
9350
- return --t * Math.pow(t, 10) + 1;
9351
- }
9352
- }
9353
- }
9354
-
9355
9641
  /**
9356
9642
  * Ranking status of a beatmap.
9357
9643
  */
@@ -9859,6 +10145,7 @@ exports.EmptyHitWindow = EmptyHitWindow;
9859
10145
  exports.ErrorFunction = ErrorFunction;
9860
10146
  exports.FileHitSampleInfo = FileHitSampleInfo;
9861
10147
  exports.HitObject = HitObject;
10148
+ exports.HitObjectGenerationUtils = HitObjectGenerationUtils;
9862
10149
  exports.HitSampleInfo = HitSampleInfo;
9863
10150
  exports.HitWindow = HitWindow;
9864
10151
  exports.Interpolation = Interpolation;
@@ -9876,6 +10163,7 @@ exports.ModHalfTime = ModHalfTime;
9876
10163
  exports.ModHardRock = ModHardRock;
9877
10164
  exports.ModHidden = ModHidden;
9878
10165
  exports.ModMap = ModMap;
10166
+ exports.ModMirror = ModMirror;
9879
10167
  exports.ModNightCore = ModNightCore;
9880
10168
  exports.ModNoFail = ModNoFail;
9881
10169
  exports.ModOldNightCore = ModOldNightCore;
@@ -9888,9 +10176,12 @@ exports.ModScoreV2 = ModScoreV2;
9888
10176
  exports.ModSmallCircle = ModSmallCircle;
9889
10177
  exports.ModSpunOut = ModSpunOut;
9890
10178
  exports.ModSuddenDeath = ModSuddenDeath;
10179
+ exports.ModTimeRamp = ModTimeRamp;
9891
10180
  exports.ModTouchDevice = ModTouchDevice;
9892
10181
  exports.ModTraceable = ModTraceable;
9893
10182
  exports.ModUtil = ModUtil;
10183
+ exports.ModWindDown = ModWindDown;
10184
+ exports.ModWindUp = ModWindUp;
9894
10185
  exports.NormalDistribution = NormalDistribution;
9895
10186
  exports.OsuAPIRequestBuilder = OsuAPIRequestBuilder;
9896
10187
  exports.OsuHitWindow = OsuHitWindow;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rian8337/osu-base",
3
- "version": "4.0.0-beta.61",
3
+ "version": "4.0.0-beta.64",
4
4
  "description": "Base module for all osu! related modules.",
5
5
  "keywords": [
6
6
  "osu",
@@ -35,5 +35,5 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "f3eee1da0bdacc6c143d820d5506c6c0e9a57995"
38
+ "gitHead": "94b205d8882d39d3436d93fb4de19871dea8a4b8"
39
39
  }
@@ -76,6 +76,28 @@ declare enum Anchor {
76
76
  bottomRight = "BottomRight"
77
77
  }
78
78
 
79
+ /**
80
+ * Defines available axes.
81
+ */
82
+ declare enum Axes {
83
+ /**
84
+ * No axis.
85
+ */
86
+ none = 0,
87
+ /**
88
+ * The X axis.
89
+ */
90
+ x = 1,
91
+ /**
92
+ * The Y axis.
93
+ */
94
+ y = 2,
95
+ /**
96
+ * The X and Y axes.
97
+ */
98
+ both = 3
99
+ }
100
+
79
101
  /**
80
102
  * The loop type of storyboard animations.
81
103
  */
@@ -1827,21 +1849,6 @@ declare class Slider extends HitObject {
1827
1849
  * This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991).
1828
1850
  */
1829
1851
  generateTicks: boolean;
1830
- /**
1831
- * The position of the cursor at the point of completion of this slider if it was hit
1832
- * with as few movements as possible. This is set and used by difficulty calculation.
1833
- */
1834
- lazyEndPosition?: Vector2;
1835
- /**
1836
- * The distance travelled by the cursor upon completion of this slider if it was hit
1837
- * with as few movements as possible. This is set and used by difficulty calculation.
1838
- */
1839
- lazyTravelDistance: number;
1840
- /**
1841
- * The time taken by the cursor upon completion of this slider if it was hit with
1842
- * as few movements as possible. This is set and used by difficulty calculation.
1843
- */
1844
- lazyTravelTime: number;
1845
1852
  /**
1846
1853
  * The length of one span of this slider.
1847
1854
  */
@@ -3641,6 +3648,26 @@ declare class FileHitSampleInfo extends HitSampleInfo {
3641
3648
  constructor(filename: string, volume?: number);
3642
3649
  }
3643
3650
 
3651
+ /**
3652
+ * Utilities for {@link HitObject} generation.
3653
+ */
3654
+ declare abstract class HitObjectGenerationUtils {
3655
+ /**
3656
+ * Reflects the position of a {@link HitObject} horizontally along the playfield.
3657
+ *
3658
+ * @param hitObject The {@link HitObject} to reflect.
3659
+ */
3660
+ static reflectHorizontallyAlongPlayfield(hitObject: HitObject): void;
3661
+ /**
3662
+ * Reflects the position of a {@link HitObject} vertically along the playfield.
3663
+ *
3664
+ * @param hitObject The {@link HitObject} to reflect.
3665
+ */
3666
+ static reflectVerticallyAlongPlayfield(hitObject: HitObject): void;
3667
+ private static reflectVectorHorizontallyAlongPlayfield;
3668
+ private static reflectVectorVerticallyAlongPlayfield;
3669
+ }
3670
+
3644
3671
  /**
3645
3672
  * Represents available hitsound types.
3646
3673
  */
@@ -4355,6 +4382,29 @@ declare class ModHidden extends Mod implements IModApplicableToDroid, IModApplic
4355
4382
  applyToBeatmap(beatmap: Beatmap): void;
4356
4383
  }
4357
4384
 
4385
+ /**
4386
+ * Represents the Mirror mod.
4387
+ */
4388
+ declare class ModMirror extends Mod implements IModApplicableToDroid, IModApplicableToOsu, IModApplicableToHitObject {
4389
+ readonly name = "Mirror";
4390
+ readonly acronym = "MR";
4391
+ readonly droidRanked = false;
4392
+ readonly osuRanked = false;
4393
+ /**
4394
+ * The axes to reflect the `HitObject`s along.
4395
+ */
4396
+ flippedAxes: Exclude<Axes, Axes.none>;
4397
+ constructor();
4398
+ get isDroidRelevant(): boolean;
4399
+ calculateDroidScoreMultiplier(): number;
4400
+ get isOsuRelevant(): boolean;
4401
+ get osuScoreMultiplier(): number;
4402
+ copySettings(mod: SerializedMod): void;
4403
+ applyToHitObject(_: Modes, hitObject: HitObject): void;
4404
+ protected serializeSettings(): Record<string, unknown> | null;
4405
+ toString(): string;
4406
+ }
4407
+
4358
4408
  /**
4359
4409
  * Represents the NightCore mod.
4360
4410
  */
@@ -4516,6 +4566,32 @@ declare class ModSuddenDeath extends Mod implements IModApplicableToDroid, IModA
4516
4566
  get osuScoreMultiplier(): number;
4517
4567
  }
4518
4568
 
4569
+ /**
4570
+ * Represents a mod that gradually adjusts the track's playback rate over time.
4571
+ */
4572
+ declare abstract class ModTimeRamp extends Mod implements IModApplicableToBeatmap, IModApplicableToTrackRate {
4573
+ /**
4574
+ * The point in the beatmap at which the final rate should be reached.
4575
+ */
4576
+ static readonly finalRateProgress = 0.75;
4577
+ /**
4578
+ * The starting speed of the track.
4579
+ */
4580
+ abstract initialRate: number;
4581
+ /**
4582
+ * The final speed to ramp to.
4583
+ */
4584
+ abstract finalRate: number;
4585
+ private initialRateTime;
4586
+ private finalRateTime;
4587
+ constructor();
4588
+ copySettings(mod: SerializedMod): void;
4589
+ applyToBeatmap(beatmap: Beatmap): void;
4590
+ applyToRate(time: number, rate: number): number;
4591
+ protected serializeSettings(): Record<string, unknown> | null;
4592
+ toString(): string;
4593
+ }
4594
+
4519
4595
  /**
4520
4596
  * Represents the TouchDevice mod.
4521
4597
  */
@@ -4543,6 +4619,46 @@ declare class ModTraceable extends Mod implements IModApplicableToDroid, IModApp
4543
4619
  get osuScoreMultiplier(): number;
4544
4620
  }
4545
4621
 
4622
+ /**
4623
+ * Represents the Wind Down mod.
4624
+ */
4625
+ declare class ModWindDown extends ModTimeRamp implements IModApplicableToDroid, IModApplicableToOsu {
4626
+ readonly name = "Wind Down";
4627
+ readonly acronym = "WD";
4628
+ private _initialRate;
4629
+ get initialRate(): number;
4630
+ set initialRate(value: number);
4631
+ private _finalRate;
4632
+ get finalRate(): number;
4633
+ set finalRate(value: number);
4634
+ readonly droidRanked = false;
4635
+ readonly osuRanked = false;
4636
+ get isDroidRelevant(): boolean;
4637
+ calculateDroidScoreMultiplier(): number;
4638
+ get isOsuRelevant(): boolean;
4639
+ get osuScoreMultiplier(): number;
4640
+ }
4641
+
4642
+ /**
4643
+ * Represents the Wind Up mod.
4644
+ */
4645
+ declare class ModWindUp extends ModTimeRamp implements IModApplicableToDroid, IModApplicableToOsu {
4646
+ readonly acronym = "Wind Up";
4647
+ readonly name = "WU";
4648
+ private _initialRate;
4649
+ get initialRate(): number;
4650
+ set initialRate(value: number);
4651
+ private _finalRate;
4652
+ get finalRate(): number;
4653
+ set finalRate(value: number);
4654
+ readonly droidRanked = false;
4655
+ readonly osuRanked = false;
4656
+ get isDroidRelevant(): boolean;
4657
+ calculateDroidScoreMultiplier(): number;
4658
+ get isOsuRelevant(): boolean;
4659
+ get osuScoreMultiplier(): number;
4660
+ }
4661
+
4546
4662
  /**
4547
4663
  * Utilities for mods.
4548
4664
  */
@@ -5118,4 +5234,4 @@ declare abstract class ZeroCrossingBracketing {
5118
5234
  static expandReduce(f: (x: number) => number, bounds: RootBounds, expansionFactor?: number, expansionMaxIterations?: number, reduceSubdivisions?: number): boolean;
5119
5235
  }
5120
5236
 
5121
- export { Accuracy, Anchor, AnimationLoopType, BankHitSampleInfo, Beatmap, BeatmapBackground, BeatmapColor, BeatmapControlPoints, BeatmapConverter, BeatmapCountdown, BeatmapDecoder, BeatmapDifficulty, BeatmapEditor, BeatmapEncoder, BeatmapEvents, BeatmapGeneral, BeatmapGenre, BeatmapHitObjects, BeatmapLanguage, BeatmapMetadata, BeatmapOverlayPosition, BeatmapProcessor, BeatmapVideo, BlendingEquation, BlendingParameters, BlendingType, BreakPoint, Brent, Circle, CircleSizeCalculator, Command, CommandLoop, CommandTimeline, CommandTimelineGroup, type CommandTimelineSelector, CommandTrigger, ControlPointManager, DifficultyControlPoint, DifficultyControlPointManager, type DroidAPIEndpoint, DroidAPIRequestBuilder, DroidHitWindow, DroidLegacyModConverter, DroidPlayableBeatmap, Easing, EditorGridSize, EffectControlPoint, EffectControlPointManager, EmptyHitWindow, ErrorFunction, FileHitSampleInfo, GameMode, HitObject, HitSampleInfo, HitSoundType, HitWindow, type IBeatmap, type ICommandTimeline, type IMigratableDroidMod, type IModApplicableToBeatmap, type IModApplicableToDifficulty, type IModApplicableToDifficultyWithSettings, type IModApplicableToDroid, type IModApplicableToHitObject, type IModApplicableToOsu, type IModApplicableToOsuStable, type IModApplicableToTrackRate, type If, Interpolation, MapInfo, MathUtils, Mod, ModAuto, ModAutopilot, ModCustomSpeed, ModDifficultyAdjust, ModDoubleTime, ModEasy, ModFlashlight, ModHalfTime, ModHardRock, ModHidden, ModMap, ModNightCore, ModNoFail, ModOldNightCore, ModPerfect, ModPrecise, ModRateAdjust, ModReallyEasy, ModRelax, ModScoreV2, ModSmallCircle, ModSpunOut, ModSuddenDeath, ModTouchDevice, ModTraceable, ModUtil, Modes, NormalDistribution, ObjectTypes, type OmitType, type OsuAPIEndpoint, OsuAPIRequestBuilder, type OsuAPIResponse, OsuHitWindow, OsuPlayableBeatmap, PathApproximator, PathType, type PlaceableHitObject, PlayableBeatmap, Playfield, Polynomial, PreciseDroidHitWindow, Precision, RGBColor, RankedStatus, type RequestResponse, type RootBounds, SampleBank, SampleBankInfo, SampleControlPoint, SampleControlPointManager, type ScoreRank, SequenceHitSampleInfo, type SerializedMod, Slider, SliderHead, SliderNestedHitObject, SliderPath, SliderRepeat, SliderTail, SliderTick, Spinner, Storyboard, StoryboardAnimation, StoryboardCommandType, StoryboardDecoder, StoryboardElement, StoryboardEncoder, StoryboardEventType, StoryboardLayer, StoryboardLayerType, StoryboardParameterCommandType, StoryboardSample, StoryboardSprite, TimedHitSampleInfo, TimingControlPoint, TimingControlPointManager, Utils, Vector2, ZeroCrossingBracketing };
5237
+ export { Accuracy, Anchor, AnimationLoopType, Axes, BankHitSampleInfo, Beatmap, BeatmapBackground, BeatmapColor, BeatmapControlPoints, BeatmapConverter, BeatmapCountdown, BeatmapDecoder, BeatmapDifficulty, BeatmapEditor, BeatmapEncoder, BeatmapEvents, BeatmapGeneral, BeatmapGenre, BeatmapHitObjects, BeatmapLanguage, BeatmapMetadata, BeatmapOverlayPosition, BeatmapProcessor, BeatmapVideo, BlendingEquation, BlendingParameters, BlendingType, BreakPoint, Brent, Circle, CircleSizeCalculator, Command, CommandLoop, CommandTimeline, CommandTimelineGroup, type CommandTimelineSelector, CommandTrigger, ControlPointManager, DifficultyControlPoint, DifficultyControlPointManager, type DroidAPIEndpoint, DroidAPIRequestBuilder, DroidHitWindow, DroidLegacyModConverter, DroidPlayableBeatmap, Easing, EditorGridSize, EffectControlPoint, EffectControlPointManager, EmptyHitWindow, ErrorFunction, FileHitSampleInfo, GameMode, HitObject, HitObjectGenerationUtils, HitSampleInfo, HitSoundType, HitWindow, type IBeatmap, type ICommandTimeline, type IMigratableDroidMod, type IModApplicableToBeatmap, type IModApplicableToDifficulty, type IModApplicableToDifficultyWithSettings, type IModApplicableToDroid, type IModApplicableToHitObject, type IModApplicableToOsu, type IModApplicableToOsuStable, type IModApplicableToTrackRate, type If, Interpolation, MapInfo, MathUtils, Mod, ModAuto, ModAutopilot, ModCustomSpeed, ModDifficultyAdjust, ModDoubleTime, ModEasy, ModFlashlight, ModHalfTime, ModHardRock, ModHidden, ModMap, ModMirror, ModNightCore, ModNoFail, ModOldNightCore, ModPerfect, ModPrecise, ModRateAdjust, ModReallyEasy, ModRelax, ModScoreV2, ModSmallCircle, ModSpunOut, ModSuddenDeath, ModTimeRamp, ModTouchDevice, ModTraceable, ModUtil, ModWindDown, ModWindUp, Modes, NormalDistribution, ObjectTypes, type OmitType, type OsuAPIEndpoint, OsuAPIRequestBuilder, type OsuAPIResponse, OsuHitWindow, OsuPlayableBeatmap, PathApproximator, PathType, type PlaceableHitObject, PlayableBeatmap, Playfield, Polynomial, PreciseDroidHitWindow, Precision, RGBColor, RankedStatus, type RequestResponse, type RootBounds, SampleBank, SampleBankInfo, SampleControlPoint, SampleControlPointManager, type ScoreRank, SequenceHitSampleInfo, type SerializedMod, Slider, SliderHead, SliderNestedHitObject, SliderPath, SliderRepeat, SliderTail, SliderTick, Spinner, Storyboard, StoryboardAnimation, StoryboardCommandType, StoryboardDecoder, StoryboardElement, StoryboardEncoder, StoryboardEventType, StoryboardLayer, StoryboardLayerType, StoryboardParameterCommandType, StoryboardSample, StoryboardSprite, TimedHitSampleInfo, TimingControlPoint, TimingControlPointManager, Utils, Vector2, ZeroCrossingBracketing };