@rian8337/osu-base 4.0.0-beta.85 → 4.0.0-beta.86
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 +284 -229
- package/package.json +5 -5
- package/typings/index.d.ts +1258 -1231
package/dist/index.js
CHANGED
|
@@ -132,6 +132,16 @@ class MathUtils {
|
|
|
132
132
|
static logistic(exponent, maxValue = 1) {
|
|
133
133
|
return maxValue / (1 + Math.exp(exponent));
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Calculates the p-norm of an n-dimensional vector.
|
|
137
|
+
*
|
|
138
|
+
* @param p The order of the norm.
|
|
139
|
+
* @param coefficients The coefficients of the vector.
|
|
140
|
+
* @returns The p-norm of the vector.
|
|
141
|
+
*/
|
|
142
|
+
static norm(p, ...coefficients) {
|
|
143
|
+
return Math.pow(coefficients.reduce((a, v) => a + Math.pow(v, p), 0), 1 / p);
|
|
144
|
+
}
|
|
135
145
|
/**
|
|
136
146
|
* Calculates an S-shaped {@link https://en.wikipedia.org/wiki/Logistic_function logistic function}
|
|
137
147
|
* with offset at `x`.
|
|
@@ -404,7 +414,7 @@ class BankHitSampleInfo extends HitSampleInfo {
|
|
|
404
414
|
break;
|
|
405
415
|
}
|
|
406
416
|
if (this.customSampleBank >= 2) {
|
|
407
|
-
names.push(`${prefix}-${this.name}${this.customSampleBank}`);
|
|
417
|
+
names.push(`${prefix}-${this.name}${this.customSampleBank.toString()}`);
|
|
408
418
|
}
|
|
409
419
|
names.push(`${prefix}-${this.name}`, this.name);
|
|
410
420
|
return names;
|
|
@@ -573,6 +583,7 @@ class PreciseDroidHitWindow extends HitWindow {
|
|
|
573
583
|
}
|
|
574
584
|
}
|
|
575
585
|
|
|
586
|
+
/* eslint-disable @typescript-eslint/prefer-literal-enum-member */
|
|
576
587
|
/**
|
|
577
588
|
* Bitmask constant of object types. This is needed as osu! uses bits to determine object types.
|
|
578
589
|
*/
|
|
@@ -713,7 +724,7 @@ class Vector2 {
|
|
|
713
724
|
* Returns a string representation of the vector.
|
|
714
725
|
*/
|
|
715
726
|
toString() {
|
|
716
|
-
return `${this.x},${this.y}`;
|
|
727
|
+
return `${this.x.toString()},${this.y.toString()}`;
|
|
717
728
|
}
|
|
718
729
|
}
|
|
719
730
|
|
|
@@ -741,6 +752,7 @@ class BeatmapDifficulty {
|
|
|
741
752
|
* @param min Minimum of the resulting range which will be achieved by a difficulty value of 0.
|
|
742
753
|
* @param mid Midpoint of the resulting range which will be achieved by a difficulty value of 5.
|
|
743
754
|
* @param max Maximum of the resulting range which will be achieved by a difficulty value of 10.
|
|
755
|
+
* @returns The value to which the difficulty value maps in the specified range.
|
|
744
756
|
*/
|
|
745
757
|
static difficultyRange(difficulty, min, mid, max) {
|
|
746
758
|
switch (true) {
|
|
@@ -752,6 +764,19 @@ class BeatmapDifficulty {
|
|
|
752
764
|
return mid;
|
|
753
765
|
}
|
|
754
766
|
}
|
|
767
|
+
/**
|
|
768
|
+
* Maps a difficulty value [0, 10] to a two-piece linear range of values. Floors the value to an integer,
|
|
769
|
+
* usually to match osu!stable specifications.
|
|
770
|
+
*
|
|
771
|
+
* @param difficulty The difficulty value to be mapped.
|
|
772
|
+
* @param min Minimum of the resulting range which will be achieved by a difficulty value of 0.
|
|
773
|
+
* @param mid Midpoint of the resulting range which will be achieved by a difficulty value of 5.
|
|
774
|
+
* @param max Maximum of the resulting range which will be achieved by a difficulty value of 10.
|
|
775
|
+
* @returns The value to which the difficulty value maps in the specified range.
|
|
776
|
+
*/
|
|
777
|
+
static difficultyRangeInt(difficulty, min, mid, max) {
|
|
778
|
+
return Math.trunc(BeatmapDifficulty.difficultyRange(difficulty, min, mid, max));
|
|
779
|
+
}
|
|
755
780
|
/**
|
|
756
781
|
* Inverse function to `difficultyRange`. Maps a value returned by the function back to the
|
|
757
782
|
* difficulty that produced it.
|
|
@@ -1169,7 +1194,7 @@ class HitObject {
|
|
|
1169
1194
|
if (this.hitWindow) {
|
|
1170
1195
|
this.hitWindow.overallDifficulty = difficulty.od;
|
|
1171
1196
|
}
|
|
1172
|
-
this.timePreempt = BeatmapDifficulty.
|
|
1197
|
+
this.timePreempt = BeatmapDifficulty.difficultyRangeInt(difficulty.ar, HitObject.preemptMax, HitObject.preemptMid, HitObject.preemptMin);
|
|
1173
1198
|
// Preempt time can go below 450ms. Normally, this is achieved via the DT mod which uniformly speeds up all animations game wide regardless of AR.
|
|
1174
1199
|
// This uniform speedup is hard to match 1:1, however we can at least make AR>10 (via mods) feel good by extending the upper linear function above.
|
|
1175
1200
|
// Note that this doesn't exactly match the AR>10 visuals as they're classically known, but it feels good.
|
|
@@ -1370,6 +1395,7 @@ class ModSetting {
|
|
|
1370
1395
|
/**
|
|
1371
1396
|
* The formatter to display the value of this `ModSetting`.
|
|
1372
1397
|
*/
|
|
1398
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
1373
1399
|
this.displayFormatter = (v) => `${v}`;
|
|
1374
1400
|
this.valueChangedListeners = new Set();
|
|
1375
1401
|
this.name = name;
|
|
@@ -1618,7 +1644,7 @@ class SliderNestedHitObject extends HitObject {
|
|
|
1618
1644
|
this.spanStartTime = values.spanStartTime;
|
|
1619
1645
|
}
|
|
1620
1646
|
toString() {
|
|
1621
|
-
return `Position: [${this.
|
|
1647
|
+
return `Position: [${this.position.x.toString()}, ${this.position.y.toString()}], span index: ${this.spanIndex.toString()}, span start time: ${this.spanStartTime.toString()}`;
|
|
1622
1648
|
}
|
|
1623
1649
|
}
|
|
1624
1650
|
|
|
@@ -2016,7 +2042,9 @@ class Slider extends HitObject {
|
|
|
2016
2042
|
this.tickDistanceMultiplier
|
|
2017
2043
|
: Number.POSITIVE_INFINITY;
|
|
2018
2044
|
this.createNestedHitObjects(controlPoints);
|
|
2019
|
-
this.nestedHitObjects.forEach((v) =>
|
|
2045
|
+
this.nestedHitObjects.forEach((v) => {
|
|
2046
|
+
v.applyDefaults(controlPoints, difficulty, mode);
|
|
2047
|
+
});
|
|
2020
2048
|
}
|
|
2021
2049
|
applySamples(controlPoints) {
|
|
2022
2050
|
super.applySamples(controlPoints);
|
|
@@ -2219,7 +2247,7 @@ class Slider extends HitObject {
|
|
|
2219
2247
|
});
|
|
2220
2248
|
}
|
|
2221
2249
|
toString() {
|
|
2222
|
-
return `Position: [${this.position.x}, ${this.position.y}], distance: ${this.path.expectedDistance}, repeat count: ${this.repeatCount}, slider ticks: ${this.
|
|
2250
|
+
return `Position: [${this.position.x.toString()}, ${this.position.y.toString()}], distance: ${this.path.expectedDistance.toString()}, repeat count: ${this.repeatCount.toString()}, slider ticks: ${this.ticks.toString()}`;
|
|
2223
2251
|
}
|
|
2224
2252
|
}
|
|
2225
2253
|
Slider.baseNormalSlideSample = new BankHitSampleInfo("sliderslide");
|
|
@@ -2227,43 +2255,6 @@ Slider.baseWhistleSlideSample = new BankHitSampleInfo("sliderwhistle");
|
|
|
2227
2255
|
Slider.baseTickSample = new BankHitSampleInfo("slidertick");
|
|
2228
2256
|
Slider.legacyLastTickOffset = 36;
|
|
2229
2257
|
|
|
2230
|
-
/**
|
|
2231
|
-
* Represents the Freeze Frame mod.
|
|
2232
|
-
*/
|
|
2233
|
-
class ModFreezeFrame extends Mod {
|
|
2234
|
-
constructor() {
|
|
2235
|
-
super();
|
|
2236
|
-
this.name = "Freeze Frame";
|
|
2237
|
-
this.acronym = "FR";
|
|
2238
|
-
this.droidRanked = false;
|
|
2239
|
-
this.isDroidRelevant = true;
|
|
2240
|
-
this.droidScoreMultiplier = 1;
|
|
2241
|
-
this.osuRanked = false;
|
|
2242
|
-
this.isOsuRelevant = true;
|
|
2243
|
-
this.osuScoreMultiplier = 1;
|
|
2244
|
-
this.lastNewComboTime = 0;
|
|
2245
|
-
this.incompatibleMods.add(ModApproachDifferent);
|
|
2246
|
-
}
|
|
2247
|
-
applyToBeatmap(beatmap) {
|
|
2248
|
-
this.lastNewComboTime = 0;
|
|
2249
|
-
for (const hitObject of beatmap.hitObjects) {
|
|
2250
|
-
if (hitObject.isNewCombo) {
|
|
2251
|
-
this.lastNewComboTime = hitObject.startTime;
|
|
2252
|
-
}
|
|
2253
|
-
this.applyFadeInAdjustment(hitObject);
|
|
2254
|
-
}
|
|
2255
|
-
}
|
|
2256
|
-
applyFadeInAdjustment(hitObject) {
|
|
2257
|
-
hitObject.timePreempt += hitObject.startTime - this.lastNewComboTime;
|
|
2258
|
-
if (hitObject instanceof Slider) {
|
|
2259
|
-
// Freezing slider ticks doesn't play well with snaking sliders, and slider repeats will not
|
|
2260
|
-
// layer correctly if its preempt is changed.
|
|
2261
|
-
this.applyFadeInAdjustment(hitObject.head);
|
|
2262
|
-
this.applyFadeInAdjustment(hitObject.tail);
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
2266
|
-
|
|
2267
2258
|
/**
|
|
2268
2259
|
* Represents the Traceable mod.
|
|
2269
2260
|
*/
|
|
@@ -2315,7 +2306,10 @@ class ModHidden extends Mod {
|
|
|
2315
2306
|
* The main object body will not fade when enabled.
|
|
2316
2307
|
*/
|
|
2317
2308
|
this.onlyFadeApproachCircles = new BooleanModSetting("Only fade approach circles", "The main object body will not fade when enabled.", false);
|
|
2318
|
-
this.incompatibleMods
|
|
2309
|
+
this.incompatibleMods
|
|
2310
|
+
.add(ModTraceable)
|
|
2311
|
+
.add(ModApproachDifferent)
|
|
2312
|
+
.add(ModFreezeFrame);
|
|
2319
2313
|
}
|
|
2320
2314
|
get droidScoreMultiplier() {
|
|
2321
2315
|
return this.usesDefaultSettings ? 1.06 : 1;
|
|
@@ -2354,6 +2348,43 @@ class ModHidden extends Mod {
|
|
|
2354
2348
|
ModHidden.fadeInDurationMultiplier = 0.4;
|
|
2355
2349
|
ModHidden.fadeOutDurationMultiplier = 0.3;
|
|
2356
2350
|
|
|
2351
|
+
/**
|
|
2352
|
+
* Represents the Freeze Frame mod.
|
|
2353
|
+
*/
|
|
2354
|
+
class ModFreezeFrame extends Mod {
|
|
2355
|
+
constructor() {
|
|
2356
|
+
super();
|
|
2357
|
+
this.name = "Freeze Frame";
|
|
2358
|
+
this.acronym = "FR";
|
|
2359
|
+
this.droidRanked = false;
|
|
2360
|
+
this.isDroidRelevant = true;
|
|
2361
|
+
this.droidScoreMultiplier = 1;
|
|
2362
|
+
this.osuRanked = false;
|
|
2363
|
+
this.isOsuRelevant = true;
|
|
2364
|
+
this.osuScoreMultiplier = 1;
|
|
2365
|
+
this.lastNewComboTime = 0;
|
|
2366
|
+
this.incompatibleMods.add(ModApproachDifferent).add(ModHidden);
|
|
2367
|
+
}
|
|
2368
|
+
applyToBeatmap(beatmap) {
|
|
2369
|
+
this.lastNewComboTime = 0;
|
|
2370
|
+
for (const hitObject of beatmap.hitObjects) {
|
|
2371
|
+
if (hitObject.isNewCombo) {
|
|
2372
|
+
this.lastNewComboTime = hitObject.startTime;
|
|
2373
|
+
}
|
|
2374
|
+
this.applyFadeInAdjustment(hitObject);
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
applyFadeInAdjustment(hitObject) {
|
|
2378
|
+
hitObject.timePreempt += hitObject.startTime - this.lastNewComboTime;
|
|
2379
|
+
if (hitObject instanceof Slider) {
|
|
2380
|
+
// Freezing slider ticks doesn't play well with snaking sliders, and slider repeats will not
|
|
2381
|
+
// layer correctly if its preempt is changed.
|
|
2382
|
+
this.applyFadeInAdjustment(hitObject.head);
|
|
2383
|
+
this.applyFadeInAdjustment(hitObject.tail);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2357
2388
|
/**
|
|
2358
2389
|
* Represents a `Mod` specific setting that is constrained to a range of values.
|
|
2359
2390
|
*/
|
|
@@ -2410,13 +2441,13 @@ class NumberModSetting extends RangeConstrainedModSetting {
|
|
|
2410
2441
|
super(name, description, defaultValue, min, max, step);
|
|
2411
2442
|
this.displayFormatter = (v) => v.toString();
|
|
2412
2443
|
if (min > max) {
|
|
2413
|
-
throw new RangeError(`The minimum value (${min}) must be less than or equal to the maximum value (${max}).`);
|
|
2444
|
+
throw new RangeError(`The minimum value (${min.toString()}) must be less than or equal to the maximum value (${max.toString()}).`);
|
|
2414
2445
|
}
|
|
2415
2446
|
if (step < 0) {
|
|
2416
|
-
throw new RangeError(`The step size (${step}) must be greater than or equal to 0.`);
|
|
2447
|
+
throw new RangeError(`The step size (${step.toString()}) must be greater than or equal to 0.`);
|
|
2417
2448
|
}
|
|
2418
2449
|
if (defaultValue < min || defaultValue > max) {
|
|
2419
|
-
throw new RangeError(`The default value (${defaultValue}) must be between the minimum (${min}) and maximum (${max}) values.`);
|
|
2450
|
+
throw new RangeError(`The default value (${defaultValue.toString()}) must be between the minimum (${min.toString()}) and maximum (${max.toString()}) values.`);
|
|
2420
2451
|
}
|
|
2421
2452
|
}
|
|
2422
2453
|
processValue(value) {
|
|
@@ -2438,7 +2469,7 @@ class DecimalModSetting extends NumberModSetting {
|
|
|
2438
2469
|
}
|
|
2439
2470
|
set precision(value) {
|
|
2440
2471
|
if (value !== null && value < 0) {
|
|
2441
|
-
throw new RangeError(`The precision (${value}) must be greater than or equal to 0.`);
|
|
2472
|
+
throw new RangeError(`The precision (${value.toString()}) must be greater than or equal to 0.`);
|
|
2442
2473
|
}
|
|
2443
2474
|
this._precision = value;
|
|
2444
2475
|
if (value !== null) {
|
|
@@ -2454,7 +2485,7 @@ class DecimalModSetting extends NumberModSetting {
|
|
|
2454
2485
|
return super.toDisplayString();
|
|
2455
2486
|
};
|
|
2456
2487
|
if (precision !== null && precision < 0) {
|
|
2457
|
-
throw new RangeError(`The precision (${precision}) must be greater than or equal to 0.`);
|
|
2488
|
+
throw new RangeError(`The precision (${precision.toString()}) must be greater than or equal to 0.`);
|
|
2458
2489
|
}
|
|
2459
2490
|
this._precision = precision;
|
|
2460
2491
|
}
|
|
@@ -2807,11 +2838,8 @@ class ModDeflate extends ModObjectScaleTween {
|
|
|
2807
2838
|
* rectangle).
|
|
2808
2839
|
*/
|
|
2809
2840
|
class Circle extends HitObject {
|
|
2810
|
-
constructor(values) {
|
|
2811
|
-
super(values);
|
|
2812
|
-
}
|
|
2813
2841
|
toString() {
|
|
2814
|
-
return `Position: [${this.
|
|
2842
|
+
return `Position: [${this.position.x.toString()}, ${this.position.y.toString()}]`;
|
|
2815
2843
|
}
|
|
2816
2844
|
}
|
|
2817
2845
|
|
|
@@ -2862,7 +2890,7 @@ class Spinner extends HitObject {
|
|
|
2862
2890
|
return new EmptyHitWindow();
|
|
2863
2891
|
}
|
|
2864
2892
|
toString() {
|
|
2865
|
-
return `Position: [${this.
|
|
2893
|
+
return `Position: [${this.position.x.toString()}, ${this.position.y.toString()}], duration: ${this.duration.toString()}`;
|
|
2866
2894
|
}
|
|
2867
2895
|
}
|
|
2868
2896
|
Spinner.baseSpinnerSpinSample = new BankHitSampleInfo("spinnerspin");
|
|
@@ -3758,7 +3786,7 @@ class HitObjectGenerationUtils {
|
|
|
3758
3786
|
/**
|
|
3759
3787
|
* Determines whether a {@link HitObject} is on a beat.
|
|
3760
3788
|
*
|
|
3761
|
-
* @param beatmap The {@link
|
|
3789
|
+
* @param beatmap The {@link IBeatmap} the {@link HitObject} is a part of.
|
|
3762
3790
|
* @param hitObject The {@link HitObject} to check.
|
|
3763
3791
|
* @param downbeatsOnly If `true`, whether this method only returns `true` is on a downbeat.
|
|
3764
3792
|
* @return `true` if the {@link HitObject} is on a (down-)beat, `false` otherwise.
|
|
@@ -4327,7 +4355,7 @@ class NullableDecimalModSetting extends RangeConstrainedModSetting {
|
|
|
4327
4355
|
}
|
|
4328
4356
|
set precision(value) {
|
|
4329
4357
|
if (value !== null && value < 0) {
|
|
4330
|
-
throw new RangeError(`The precision (${value}) must be greater than or equal to 0.`);
|
|
4358
|
+
throw new RangeError(`The precision (${value.toString()}) must be greater than or equal to 0.`);
|
|
4331
4359
|
}
|
|
4332
4360
|
this._precision = value;
|
|
4333
4361
|
if (value !== null) {
|
|
@@ -4346,14 +4374,14 @@ class NullableDecimalModSetting extends RangeConstrainedModSetting {
|
|
|
4346
4374
|
return super.toDisplayString();
|
|
4347
4375
|
};
|
|
4348
4376
|
if (min > max) {
|
|
4349
|
-
throw new RangeError(`The minimum value (${min}) must be less than or equal to the maximum value (${max}).`);
|
|
4377
|
+
throw new RangeError(`The minimum value (${min.toString()}) must be less than or equal to the maximum value (${max.toString()}).`);
|
|
4350
4378
|
}
|
|
4351
4379
|
if (step < 0) {
|
|
4352
|
-
throw new RangeError(`The step size (${step}) must be greater than or equal to 0.`);
|
|
4380
|
+
throw new RangeError(`The step size (${step.toString()}) must be greater than or equal to 0.`);
|
|
4353
4381
|
}
|
|
4354
4382
|
if (defaultValue !== null &&
|
|
4355
4383
|
(defaultValue < min || defaultValue > max)) {
|
|
4356
|
-
throw new RangeError(`The default value (${defaultValue}) must be between the minimum (${min}) and maximum (${max}) values.`);
|
|
4384
|
+
throw new RangeError(`The default value (${defaultValue.toString()}) must be between the minimum (${min.toString()}) and maximum (${max.toString()}) values.`);
|
|
4357
4385
|
}
|
|
4358
4386
|
this._precision = precision;
|
|
4359
4387
|
}
|
|
@@ -4943,11 +4971,11 @@ class NullableIntegerModSetting extends RangeConstrainedModSetting {
|
|
|
4943
4971
|
super(name, description, defaultValue, min, max, 1);
|
|
4944
4972
|
this.displayFormatter = (v) => { var _a; return (_a = v === null || v === void 0 ? void 0 : v.toString()) !== null && _a !== void 0 ? _a : "None"; };
|
|
4945
4973
|
if (min > max) {
|
|
4946
|
-
throw new RangeError(`The minimum value (${min}) must be less than or equal to the maximum value (${max}).`);
|
|
4974
|
+
throw new RangeError(`The minimum value (${min.toString()}) must be less than or equal to the maximum value (${max.toString()}).`);
|
|
4947
4975
|
}
|
|
4948
4976
|
if (defaultValue !== null &&
|
|
4949
4977
|
(defaultValue < min || defaultValue > max)) {
|
|
4950
|
-
throw new RangeError(`The default value (${defaultValue}) must be between the minimum (${min}) and maximum (${max}) values.`);
|
|
4978
|
+
throw new RangeError(`The default value (${defaultValue.toString()}) must be between the minimum (${min.toString()}) and maximum (${max.toString()}) values.`);
|
|
4951
4979
|
}
|
|
4952
4980
|
}
|
|
4953
4981
|
processValue(value) {
|
|
@@ -5107,7 +5135,7 @@ class ModRandom extends Mod {
|
|
|
5107
5135
|
toString() {
|
|
5108
5136
|
const settings = [];
|
|
5109
5137
|
if (this.seed.value !== null) {
|
|
5110
|
-
settings.push(`seed: ${this.seed.value}`);
|
|
5138
|
+
settings.push(`seed: ${this.seed.value.toString()}`);
|
|
5111
5139
|
}
|
|
5112
5140
|
settings.push(`angle sharpness: ${this.angleSharpness.toDisplayString()}`);
|
|
5113
5141
|
return `${super.toString()} (${settings.join(", ")})`;
|
|
@@ -5143,12 +5171,8 @@ class ModSpunOut extends Mod {
|
|
|
5143
5171
|
this.name = "SpunOut";
|
|
5144
5172
|
this.osuRanked = true;
|
|
5145
5173
|
this.bitwise = 1 << 12;
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
return true;
|
|
5149
|
-
}
|
|
5150
|
-
get osuScoreMultiplier() {
|
|
5151
|
-
return 0.9;
|
|
5174
|
+
this.isOsuRelevant = true;
|
|
5175
|
+
this.osuScoreMultiplier = 0.9;
|
|
5152
5176
|
}
|
|
5153
5177
|
}
|
|
5154
5178
|
|
|
@@ -5179,12 +5203,8 @@ class ModTouchDevice extends Mod {
|
|
|
5179
5203
|
this.name = "TouchDevice";
|
|
5180
5204
|
this.osuRanked = true;
|
|
5181
5205
|
this.bitwise = 1 << 2;
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
return true;
|
|
5185
|
-
}
|
|
5186
|
-
get osuScoreMultiplier() {
|
|
5187
|
-
return 1;
|
|
5206
|
+
this.isOsuRelevant = true;
|
|
5207
|
+
this.osuScoreMultiplier = 1;
|
|
5188
5208
|
}
|
|
5189
5209
|
}
|
|
5190
5210
|
|
|
@@ -6144,8 +6164,7 @@ class BeatmapProcessor {
|
|
|
6144
6164
|
if (objectN instanceof Spinner) {
|
|
6145
6165
|
break;
|
|
6146
6166
|
}
|
|
6147
|
-
const stackThreshold = objectN
|
|
6148
|
-
this.beatmap.general.stackLeniency;
|
|
6167
|
+
const stackThreshold = this.calculateStackThreshold(objectN);
|
|
6149
6168
|
if (objectN.startTime - stackBaseObject.endTime >
|
|
6150
6169
|
stackThreshold) {
|
|
6151
6170
|
// We are no longer within stacking range of the next object.
|
|
@@ -6187,7 +6206,7 @@ class BeatmapProcessor {
|
|
|
6187
6206
|
if (objectI.stackHeight !== 0 || objectI instanceof Spinner) {
|
|
6188
6207
|
continue;
|
|
6189
6208
|
}
|
|
6190
|
-
const stackThreshold =
|
|
6209
|
+
const stackThreshold = this.calculateStackThreshold(objectI);
|
|
6191
6210
|
// If this object is a hit circle, then we enter this "special" case.
|
|
6192
6211
|
// It either ends with a stack of hit circles only, or a stack of hit circles that are underneath a slider.
|
|
6193
6212
|
// Any other case is handled by the "instanceof Slider" code below this.
|
|
@@ -6197,7 +6216,11 @@ class BeatmapProcessor {
|
|
|
6197
6216
|
if (objectN instanceof Spinner) {
|
|
6198
6217
|
continue;
|
|
6199
6218
|
}
|
|
6200
|
-
|
|
6219
|
+
// Truncation to integer is required to match osu!stable - both quantities being subtracted there
|
|
6220
|
+
// are integers.
|
|
6221
|
+
if (Math.trunc(objectI.startTime) -
|
|
6222
|
+
Math.trunc(objectN.endTime) >
|
|
6223
|
+
stackThreshold) {
|
|
6201
6224
|
// We are no longer within stacking range of the previous object.
|
|
6202
6225
|
break;
|
|
6203
6226
|
}
|
|
@@ -6266,7 +6289,7 @@ class BeatmapProcessor {
|
|
|
6266
6289
|
}
|
|
6267
6290
|
let startTime = currentObject.endTime;
|
|
6268
6291
|
let sliderStack = 0;
|
|
6269
|
-
const stackThreshold =
|
|
6292
|
+
const stackThreshold = this.calculateStackThreshold(currentObject);
|
|
6270
6293
|
for (let j = i + 1; j < objects.length; ++j) {
|
|
6271
6294
|
if (objects[j].startTime - stackThreshold > startTime) {
|
|
6272
6295
|
break;
|
|
@@ -6294,6 +6317,18 @@ class BeatmapProcessor {
|
|
|
6294
6317
|
}
|
|
6295
6318
|
}
|
|
6296
6319
|
}
|
|
6320
|
+
/**
|
|
6321
|
+
* Truncation of {@link HitObject.timePreempt} to an integer, as well as keeping the result as a float,
|
|
6322
|
+
* are both done for the purposes of osu!stable compatibility.
|
|
6323
|
+
*
|
|
6324
|
+
* Note that top-level objects {@link HitObject.timePreempt} is supposed to be integral anyway; see
|
|
6325
|
+
* {@link HitObject.applyDefaults} using `BeatmapDifficulty.difficultyRangeInt` when calculating it.
|
|
6326
|
+
*
|
|
6327
|
+
* Slider ticks and end circles are the exception to that, but they do not matter for stacking.
|
|
6328
|
+
*/
|
|
6329
|
+
calculateStackThreshold(object) {
|
|
6330
|
+
return (Math.trunc(object.timePreempt) * this.beatmap.general.stackLeniency);
|
|
6331
|
+
}
|
|
6297
6332
|
}
|
|
6298
6333
|
BeatmapProcessor.stackDistance = 3;
|
|
6299
6334
|
|
|
@@ -6393,13 +6428,13 @@ class TimingControlPoint extends ControlPoint {
|
|
|
6393
6428
|
}
|
|
6394
6429
|
toString() {
|
|
6395
6430
|
return ("{ time: " +
|
|
6396
|
-
this.time +
|
|
6431
|
+
this.time.toString() +
|
|
6397
6432
|
", " +
|
|
6398
6433
|
"ms_per_beat: " +
|
|
6399
6434
|
this.msPerBeat.toFixed(2) +
|
|
6400
6435
|
", " +
|
|
6401
6436
|
"timeSignature: " +
|
|
6402
|
-
this.timeSignature +
|
|
6437
|
+
this.timeSignature.toString() +
|
|
6403
6438
|
" }");
|
|
6404
6439
|
}
|
|
6405
6440
|
}
|
|
@@ -6611,12 +6646,12 @@ class DifficultyControlPoint extends ControlPoint {
|
|
|
6611
6646
|
}
|
|
6612
6647
|
toString() {
|
|
6613
6648
|
return ("{ time: " +
|
|
6614
|
-
this.time +
|
|
6649
|
+
this.time.toString() +
|
|
6615
6650
|
", " +
|
|
6616
6651
|
"speed multiplier: " +
|
|
6617
6652
|
this.speedMultiplier.toFixed(2) +
|
|
6618
6653
|
", generate ticks: " +
|
|
6619
|
-
this.generateTicks +
|
|
6654
|
+
this.generateTicks.toString() +
|
|
6620
6655
|
" }");
|
|
6621
6656
|
}
|
|
6622
6657
|
}
|
|
@@ -6651,7 +6686,12 @@ class EffectControlPoint extends ControlPoint {
|
|
|
6651
6686
|
return this.isKiai === existing.isKiai;
|
|
6652
6687
|
}
|
|
6653
6688
|
toString() {
|
|
6654
|
-
return "{ time: " +
|
|
6689
|
+
return ("{ time: " +
|
|
6690
|
+
this.time.toString() +
|
|
6691
|
+
", " +
|
|
6692
|
+
"kiai: " +
|
|
6693
|
+
this.isKiai.toString() +
|
|
6694
|
+
" }");
|
|
6655
6695
|
}
|
|
6656
6696
|
}
|
|
6657
6697
|
|
|
@@ -6712,13 +6752,13 @@ class SampleControlPoint extends ControlPoint {
|
|
|
6712
6752
|
}
|
|
6713
6753
|
toString() {
|
|
6714
6754
|
return ("{ time: " +
|
|
6715
|
-
this.time +
|
|
6755
|
+
this.time.toString() +
|
|
6716
6756
|
", " +
|
|
6717
6757
|
"sample bank: " +
|
|
6718
|
-
this.sampleBank +
|
|
6758
|
+
this.sampleBank.toString() +
|
|
6719
6759
|
", " +
|
|
6720
6760
|
"sample volume: " +
|
|
6721
|
-
this.sampleVolume +
|
|
6761
|
+
this.sampleVolume.toString() +
|
|
6722
6762
|
" }");
|
|
6723
6763
|
}
|
|
6724
6764
|
}
|
|
@@ -6774,6 +6814,7 @@ class BeatmapControlPoints {
|
|
|
6774
6814
|
}
|
|
6775
6815
|
}
|
|
6776
6816
|
|
|
6817
|
+
/* eslint-disable @typescript-eslint/prefer-literal-enum-member */
|
|
6777
6818
|
/**
|
|
6778
6819
|
* Represents the grid size setting in the editor.
|
|
6779
6820
|
*/
|
|
@@ -7060,7 +7101,7 @@ class Beatmap {
|
|
|
7060
7101
|
var _a, _b, _c, _d, _e;
|
|
7061
7102
|
// The last playable time in the beatmap - the last timing point extends to this time.
|
|
7062
7103
|
// Note: This is more accurate and may present different results because osu-stable didn't have the ability to calculate slider durations in this context.
|
|
7063
|
-
const lastTime = (_d = (_b = (_a = this.hitObjects.objects
|
|
7104
|
+
const lastTime = (_d = (_b = (_a = this.hitObjects.objects.at(-1)) === null || _a === void 0 ? void 0 : _a.endTime) !== null && _b !== void 0 ? _b : (_c = this.controlPoints.timing.points.at(-1)) === null || _c === void 0 ? void 0 : _c.time) !== null && _d !== void 0 ? _d : 0;
|
|
7064
7105
|
const mostCommon =
|
|
7065
7106
|
// Construct a set of {beatLength, duration} objects for each individual timing point.
|
|
7066
7107
|
this.controlPoints.timing.points
|
|
@@ -7076,8 +7117,9 @@ class Beatmap {
|
|
|
7076
7117
|
duration: nextTime - currentTime,
|
|
7077
7118
|
};
|
|
7078
7119
|
})
|
|
7079
|
-
|
|
7080
|
-
.
|
|
7120
|
+
.sort((a, b) => b.duration - a.duration)
|
|
7121
|
+
.at(0);
|
|
7122
|
+
// Get the most common one, or 0 as a suitable default.
|
|
7081
7123
|
return (_e = mostCommon === null || mostCommon === void 0 ? void 0 : mostCommon.beatLength) !== null && _e !== void 0 ? _e : 0;
|
|
7082
7124
|
}
|
|
7083
7125
|
getOffsetTime(time) {
|
|
@@ -7232,7 +7274,9 @@ class Beatmap {
|
|
|
7232
7274
|
const processor = new BeatmapProcessor(converted);
|
|
7233
7275
|
processor.preProcess();
|
|
7234
7276
|
// Compute default values for hit objects, including creating nested hit objects in-case they're needed.
|
|
7235
|
-
converted.hitObjects.objects.forEach((hitObject) =>
|
|
7277
|
+
converted.hitObjects.objects.forEach((hitObject) => {
|
|
7278
|
+
hitObject.applyDefaults(converted.controlPoints, converted.difficulty, mode);
|
|
7279
|
+
});
|
|
7236
7280
|
mods.forEach((mod) => {
|
|
7237
7281
|
if (mod.isApplicableToHitObject()) {
|
|
7238
7282
|
for (const hitObject of converted.hitObjects.objects) {
|
|
@@ -7275,25 +7319,25 @@ class Beatmap {
|
|
|
7275
7319
|
"\n" +
|
|
7276
7320
|
"\n" +
|
|
7277
7321
|
"AR" +
|
|
7278
|
-
MathUtils.round(this.difficulty.ar, 2) +
|
|
7322
|
+
MathUtils.round(this.difficulty.ar, 2).toString() +
|
|
7279
7323
|
" " +
|
|
7280
7324
|
"OD" +
|
|
7281
|
-
MathUtils.round(this.difficulty.od, 2) +
|
|
7325
|
+
MathUtils.round(this.difficulty.od, 2).toString() +
|
|
7282
7326
|
" " +
|
|
7283
7327
|
"CS" +
|
|
7284
|
-
MathUtils.round(this.difficulty.cs, 2) +
|
|
7328
|
+
MathUtils.round(this.difficulty.cs, 2).toString() +
|
|
7285
7329
|
" " +
|
|
7286
7330
|
"HP" +
|
|
7287
|
-
MathUtils.round(this.difficulty.hp, 2) +
|
|
7331
|
+
MathUtils.round(this.difficulty.hp, 2).toString() +
|
|
7288
7332
|
"\n" +
|
|
7289
|
-
this.hitObjects.circles +
|
|
7333
|
+
this.hitObjects.circles.toString() +
|
|
7290
7334
|
" circles, " +
|
|
7291
|
-
this.hitObjects.sliders +
|
|
7335
|
+
this.hitObjects.sliders.toString() +
|
|
7292
7336
|
" sliders, " +
|
|
7293
|
-
this.hitObjects.spinners +
|
|
7337
|
+
this.hitObjects.spinners.toString() +
|
|
7294
7338
|
" spinners" +
|
|
7295
7339
|
"\n" +
|
|
7296
|
-
this.maxCombo +
|
|
7340
|
+
this.maxCombo.toString() +
|
|
7297
7341
|
" max combo";
|
|
7298
7342
|
return res;
|
|
7299
7343
|
}
|
|
@@ -7309,6 +7353,7 @@ class BeatmapBackground {
|
|
|
7309
7353
|
}
|
|
7310
7354
|
}
|
|
7311
7355
|
|
|
7356
|
+
/* eslint-disable @typescript-eslint/prefer-literal-enum-member */
|
|
7312
7357
|
/**
|
|
7313
7358
|
* Represents available hitsound types.
|
|
7314
7359
|
*/
|
|
@@ -7321,6 +7366,7 @@ exports.HitSoundType = void 0;
|
|
|
7321
7366
|
HitSoundType[HitSoundType["clap"] = 8] = "clap";
|
|
7322
7367
|
})(exports.HitSoundType || (exports.HitSoundType = {}));
|
|
7323
7368
|
|
|
7369
|
+
/* eslint-disable @typescript-eslint/no-duplicate-enum-values */
|
|
7324
7370
|
/**
|
|
7325
7371
|
* Constants for beatmap parser.
|
|
7326
7372
|
*/
|
|
@@ -7403,7 +7449,7 @@ class Decoder {
|
|
|
7403
7449
|
* @returns The current decoder instance.
|
|
7404
7450
|
*/
|
|
7405
7451
|
decode(str) {
|
|
7406
|
-
var _a;
|
|
7452
|
+
var _a, _b;
|
|
7407
7453
|
this.reset();
|
|
7408
7454
|
for (let line of str.split("\n")) {
|
|
7409
7455
|
this.currentLine = line;
|
|
@@ -7424,7 +7470,7 @@ class Decoder {
|
|
|
7424
7470
|
if (line.startsWith("[") && line.endsWith("]")) {
|
|
7425
7471
|
const section = line.substring(1, line.length - 1);
|
|
7426
7472
|
if (!Object.values(BeatmapSection).includes(section)) {
|
|
7427
|
-
console.warn(`Unknown section "${line}" at line ${this.line}`);
|
|
7473
|
+
console.warn(`Unknown section "${line}" at line ${this.line.toString()}`);
|
|
7428
7474
|
continue;
|
|
7429
7475
|
}
|
|
7430
7476
|
this.section = section;
|
|
@@ -7443,7 +7489,7 @@ class Decoder {
|
|
|
7443
7489
|
}
|
|
7444
7490
|
catch (e) {
|
|
7445
7491
|
console.error(e);
|
|
7446
|
-
console.error(`at line ${this.line}\n${(_a = this.decoders[this.section]) === null || _a === void 0 ? void 0 : _a.logExceptionPosition()}`);
|
|
7492
|
+
console.error(`at line ${this.line.toString()}\n${(_b = (_a = this.decoders[this.section]) === null || _a === void 0 ? void 0 : _a.logExceptionPosition()) !== null && _b !== void 0 ? _b : ""}`);
|
|
7447
7493
|
}
|
|
7448
7494
|
}
|
|
7449
7495
|
return this;
|
|
@@ -7533,7 +7579,7 @@ class SectionDecoder {
|
|
|
7533
7579
|
* @param str The string to parse.
|
|
7534
7580
|
* @param min The minimum threshold. Defaults to `-ParserConstants.MAX_PARSE_VALUE`.
|
|
7535
7581
|
* @param max The maximum threshold. Defaults to `ParserConstants.MAX_PARSE_VALUE`.
|
|
7536
|
-
* @param allowNaN Whether to allow NaN.
|
|
7582
|
+
* @param allowNaN Whether to allow NaN. Defaults to `false`.
|
|
7537
7583
|
* @returns The parsed integer.
|
|
7538
7584
|
*/
|
|
7539
7585
|
tryParseInt(str, min = -ParserConstants.MAX_PARSE_VALUE, max = ParserConstants.MAX_PARSE_VALUE, allowNaN = false) {
|
|
@@ -7557,7 +7603,7 @@ class SectionDecoder {
|
|
|
7557
7603
|
* @param str The string to parse.
|
|
7558
7604
|
* @param min The minimum threshold. Defaults to `-ParserConstants.MAX_PARSE_VALUE`.
|
|
7559
7605
|
* @param max The maximum threshold. Defaults to `ParserConstants.MAX_PARSE_VALUE`.
|
|
7560
|
-
* @param allowNaN Whether to allow NaN.
|
|
7606
|
+
* @param allowNaN Whether to allow NaN. Defaults to `false`.
|
|
7561
7607
|
* @returns The parsed float.
|
|
7562
7608
|
*/
|
|
7563
7609
|
tryParseFloat(str, min = -ParserConstants.MAX_PARSE_VALUE, max = ParserConstants.MAX_PARSE_VALUE, allowNaN = false) {
|
|
@@ -7835,7 +7881,7 @@ class BeatmapGeneralDecoder extends SectionDecoder {
|
|
|
7835
7881
|
this.target.general.previewTime = this.tryParseInt(p[1]);
|
|
7836
7882
|
break;
|
|
7837
7883
|
case "Countdown":
|
|
7838
|
-
this.target.general.countdown =
|
|
7884
|
+
this.target.general.countdown = this.tryParseInt(p[1]);
|
|
7839
7885
|
break;
|
|
7840
7886
|
case "SampleSet":
|
|
7841
7887
|
switch (p[1]) {
|
|
@@ -7866,7 +7912,8 @@ class BeatmapGeneralDecoder extends SectionDecoder {
|
|
|
7866
7912
|
this.target.general.useSkinSprites = !!this.tryParseInt(p[1]);
|
|
7867
7913
|
break;
|
|
7868
7914
|
case "OverlayPosition":
|
|
7869
|
-
this.target.general.overlayPosition =
|
|
7915
|
+
this.target.general.overlayPosition =
|
|
7916
|
+
p[1];
|
|
7870
7917
|
break;
|
|
7871
7918
|
case "SkinPreference":
|
|
7872
7919
|
this.target.general.skinPreference = (_a = p[1]) !== null && _a !== void 0 ? _a : "";
|
|
@@ -7889,6 +7936,7 @@ class BeatmapGeneralDecoder extends SectionDecoder {
|
|
|
7889
7936
|
this.target.editor.bookmarks = p[1]
|
|
7890
7937
|
.split(",")
|
|
7891
7938
|
.map((v) => this.tryParseInt(v));
|
|
7939
|
+
break;
|
|
7892
7940
|
}
|
|
7893
7941
|
}
|
|
7894
7942
|
}
|
|
@@ -7912,7 +7960,7 @@ class BeatmapEditorDecoder extends SectionDecoder {
|
|
|
7912
7960
|
this.target.editor.beatDivisor = this.tryParseFloat(p[1]);
|
|
7913
7961
|
break;
|
|
7914
7962
|
case "GridSize":
|
|
7915
|
-
this.target.editor.gridSize =
|
|
7963
|
+
this.target.editor.gridSize = this.tryParseInt(p[1]);
|
|
7916
7964
|
break;
|
|
7917
7965
|
case "TimelineZoom":
|
|
7918
7966
|
this.target.editor.timelineZoom = this.tryParseFloat(p[1]);
|
|
@@ -7942,15 +7990,15 @@ class BreakPoint {
|
|
|
7942
7990
|
get duration() {
|
|
7943
7991
|
return this.endTime - this.startTime;
|
|
7944
7992
|
}
|
|
7945
|
-
constructor(
|
|
7946
|
-
this.startTime =
|
|
7947
|
-
this.endTime =
|
|
7993
|
+
constructor(startTime, endTime) {
|
|
7994
|
+
this.startTime = startTime;
|
|
7995
|
+
this.endTime = endTime;
|
|
7948
7996
|
}
|
|
7949
7997
|
/**
|
|
7950
7998
|
* Returns a string representation of the class.
|
|
7951
7999
|
*/
|
|
7952
8000
|
toString() {
|
|
7953
|
-
return `Start time: ${this.startTime}, end time: ${this.endTime}, duration: ${this.duration}`;
|
|
8001
|
+
return `Start time: ${this.startTime.toString()}, end time: ${this.endTime.toString()}, duration: ${this.duration.toString()}`;
|
|
7954
8002
|
}
|
|
7955
8003
|
/**
|
|
7956
8004
|
* Whether this break period contains a specified time.
|
|
@@ -8003,10 +8051,7 @@ class BeatmapEventsDecoder extends SectionDecoder {
|
|
|
8003
8051
|
this.target.events.video = new BeatmapVideo(this.tryParseInt(this.setPosition(s[1])), this.setPosition(s[2]).replace(/"/g, ""), new Vector2(this.tryParseFloat(this.setPosition((_a = s[3]) !== null && _a !== void 0 ? _a : "0")), this.tryParseFloat(this.setPosition((_b = s[4]) !== null && _b !== void 0 ? _b : "0"))));
|
|
8004
8052
|
}
|
|
8005
8053
|
parseBreak(s) {
|
|
8006
|
-
this.target.events.breaks.push(new BreakPoint(
|
|
8007
|
-
startTime: this.target.getOffsetTime(this.tryParseInt(this.setPosition(s[1]))),
|
|
8008
|
-
endTime: this.target.getOffsetTime(this.tryParseInt(this.setPosition(s[2]))),
|
|
8009
|
-
}));
|
|
8054
|
+
this.target.events.breaks.push(new BreakPoint(this.target.getOffsetTime(this.tryParseInt(this.setPosition(s[1]))), this.target.getOffsetTime(this.tryParseInt(this.setPosition(s[2])))));
|
|
8010
8055
|
}
|
|
8011
8056
|
}
|
|
8012
8057
|
|
|
@@ -8079,6 +8124,7 @@ class BeatmapMetadataDecoder extends SectionDecoder {
|
|
|
8079
8124
|
}
|
|
8080
8125
|
}
|
|
8081
8126
|
|
|
8127
|
+
/* eslint-disable @typescript-eslint/prefer-literal-enum-member */
|
|
8082
8128
|
/**
|
|
8083
8129
|
* Effects that can occur in an effect control point.
|
|
8084
8130
|
*/
|
|
@@ -8177,10 +8223,10 @@ class RGBColor {
|
|
|
8177
8223
|
*/
|
|
8178
8224
|
toString() {
|
|
8179
8225
|
if (this.a === 1) {
|
|
8180
|
-
return `${this.r},${this.g},${this.b}`;
|
|
8226
|
+
return `${this.r.toString()},${this.g.toString()},${this.b.toString()}`;
|
|
8181
8227
|
}
|
|
8182
8228
|
else {
|
|
8183
|
-
return `${this.r},${this.g},${this.b},${this.a}`;
|
|
8229
|
+
return `${this.r.toString()},${this.g.toString()},${this.b.toString()},${this.a.toString()}`;
|
|
8184
8230
|
}
|
|
8185
8231
|
}
|
|
8186
8232
|
/**
|
|
@@ -8462,7 +8508,8 @@ class Command {
|
|
|
8462
8508
|
return this.parameterType !== undefined;
|
|
8463
8509
|
}
|
|
8464
8510
|
toString() {
|
|
8465
|
-
|
|
8511
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
8512
|
+
return `${this.startTime.toString()} -> ${this.endTime.toString()}, ${this.startValue} -> ${this.endValue} ${this.easing.toString()}`;
|
|
8466
8513
|
}
|
|
8467
8514
|
}
|
|
8468
8515
|
|
|
@@ -8684,7 +8731,7 @@ class CommandLoop extends CommandTimelineGroup {
|
|
|
8684
8731
|
return commands;
|
|
8685
8732
|
}
|
|
8686
8733
|
toString() {
|
|
8687
|
-
return `${this.loopStartTime} x${this.totalIterations}`;
|
|
8734
|
+
return `${this.loopStartTime.toString()} x${this.totalIterations.toString()}`;
|
|
8688
8735
|
}
|
|
8689
8736
|
}
|
|
8690
8737
|
|
|
@@ -8700,7 +8747,7 @@ class CommandTrigger extends CommandTimelineGroup {
|
|
|
8700
8747
|
this.groupNumber = groupNumber;
|
|
8701
8748
|
}
|
|
8702
8749
|
toString() {
|
|
8703
|
-
return `${this.triggerName} ${this.triggerStartTime} -> ${this.triggerEndTime} (${this.groupNumber})`;
|
|
8750
|
+
return `${this.triggerName} ${this.triggerStartTime.toString()} -> ${this.triggerEndTime.toString()} (${this.groupNumber.toString()})`;
|
|
8704
8751
|
}
|
|
8705
8752
|
}
|
|
8706
8753
|
|
|
@@ -8736,7 +8783,7 @@ class StoryboardSprite extends StoryboardElement {
|
|
|
8736
8783
|
// You can imagine that the first command of each type decides that type's start value, so if the initial alpha is zero,
|
|
8737
8784
|
// anything before that point can be ignored (the sprite is not visible after all).
|
|
8738
8785
|
const alphaCommands = [];
|
|
8739
|
-
let command = this.timelineGroup.alpha.commands
|
|
8786
|
+
let command = this.timelineGroup.alpha.commands.at(0);
|
|
8740
8787
|
if (command) {
|
|
8741
8788
|
alphaCommands.push({
|
|
8742
8789
|
startTime: command.startTime,
|
|
@@ -8744,7 +8791,7 @@ class StoryboardSprite extends StoryboardElement {
|
|
|
8744
8791
|
});
|
|
8745
8792
|
}
|
|
8746
8793
|
for (const l of this.loops) {
|
|
8747
|
-
command = l.alpha.commands
|
|
8794
|
+
command = l.alpha.commands.at(0);
|
|
8748
8795
|
if (command) {
|
|
8749
8796
|
alphaCommands.push({
|
|
8750
8797
|
startTime: command.startTime + l.loopStartTime,
|
|
@@ -8826,7 +8873,7 @@ class StoryboardSprite extends StoryboardElement {
|
|
|
8826
8873
|
return trigger;
|
|
8827
8874
|
}
|
|
8828
8875
|
toString() {
|
|
8829
|
-
return `${this.path}, ${this.origin}, ${this.initialPosition}`;
|
|
8876
|
+
return `${this.path}, ${this.origin}, ${this.initialPosition.toString()}`;
|
|
8830
8877
|
}
|
|
8831
8878
|
}
|
|
8832
8879
|
|
|
@@ -8963,7 +9010,7 @@ class StoryboardEventsDecoder extends SectionDecoder {
|
|
|
8963
9010
|
if (!s[3]) {
|
|
8964
9011
|
s[3] = this.setPosition(s[2]);
|
|
8965
9012
|
}
|
|
8966
|
-
const easing =
|
|
9013
|
+
const easing = this.tryParseInt(this.setPosition(s[1]));
|
|
8967
9014
|
const startTime = this.tryParseInt(this.setPosition(s[2]));
|
|
8968
9015
|
const endTime = this.tryParseInt(this.setPosition(s[3]));
|
|
8969
9016
|
switch (s[0]) {
|
|
@@ -9221,13 +9268,13 @@ class BeatmapDecoder extends Decoder {
|
|
|
9221
9268
|
/**
|
|
9222
9269
|
* @param str The string to decode.
|
|
9223
9270
|
* @param mode The mode to parse the beatmap as. Defaults to osu!standard.
|
|
9224
|
-
* @param parseStoryboard Whether to parse the beatmap's storyboard.
|
|
9271
|
+
* @param parseStoryboard Whether to parse the beatmap's storyboard. Defaults to `true`.
|
|
9225
9272
|
*/
|
|
9226
9273
|
decode(str, mode = exports.Modes.osu, parseStoryboard = true) {
|
|
9227
9274
|
super.decode(str);
|
|
9228
9275
|
this.finalResult.mode = mode;
|
|
9229
9276
|
if (parseStoryboard) {
|
|
9230
|
-
const eventsDecoder =
|
|
9277
|
+
const eventsDecoder = this.decoders[BeatmapSection.events];
|
|
9231
9278
|
if (eventsDecoder.storyboardLines.length > 0) {
|
|
9232
9279
|
this.finalResult.events.storyboard = new StoryboardDecoder(this.finalResult.formatVersion).decode(eventsDecoder.storyboardLines.join("\n")).result;
|
|
9233
9280
|
}
|
|
@@ -9315,6 +9362,9 @@ class Encoder {
|
|
|
9315
9362
|
* The base of all encoders.
|
|
9316
9363
|
*/
|
|
9317
9364
|
class BaseEncoder {
|
|
9365
|
+
/**
|
|
9366
|
+
* @param encodeSections Whether sections should be encoded. Defaults to `true`.
|
|
9367
|
+
*/
|
|
9318
9368
|
constructor(encodeSections = true) {
|
|
9319
9369
|
/**
|
|
9320
9370
|
* The target of the encoding process.
|
|
@@ -9393,10 +9443,10 @@ class BeatmapColorEncoder extends BeatmapBaseEncoder {
|
|
|
9393
9443
|
}
|
|
9394
9444
|
for (let i = 0; i < colors.combo.length; ++i) {
|
|
9395
9445
|
const color = colors.combo[i];
|
|
9396
|
-
this.write(`Combo${i + 1}: `);
|
|
9397
|
-
this.write(`${color.r},`);
|
|
9398
|
-
this.write(`${color.g},`);
|
|
9399
|
-
this.write(
|
|
9446
|
+
this.write(`Combo${(i + 1).toString()}: `);
|
|
9447
|
+
this.write(`${color.r.toString()},`);
|
|
9448
|
+
this.write(`${color.g.toString()},`);
|
|
9449
|
+
this.write(color.b.toString());
|
|
9400
9450
|
this.writeLine();
|
|
9401
9451
|
}
|
|
9402
9452
|
}
|
|
@@ -9429,14 +9479,14 @@ class BeatmapControlPointsEncoder extends BeatmapBaseEncoder {
|
|
|
9429
9479
|
for (const group of Object.values(this.controlPointGroups).sort((a, b) => a.time - b.time)) {
|
|
9430
9480
|
// If the group contains a timing control point, it needs to be output separately.
|
|
9431
9481
|
if (group.timing) {
|
|
9432
|
-
this.write(`${group.timing.time},`);
|
|
9433
|
-
this.write(`${group.timing.msPerBeat},`);
|
|
9482
|
+
this.write(`${group.timing.time.toString()},`);
|
|
9483
|
+
this.write(`${group.timing.msPerBeat.toString()},`);
|
|
9434
9484
|
this.outputControlPointGroup(group, true);
|
|
9435
9485
|
}
|
|
9436
9486
|
// Output any remaining effects as secondary non-timing control point.
|
|
9437
|
-
this.write(`${group.time},`);
|
|
9487
|
+
this.write(`${group.time.toString()},`);
|
|
9438
9488
|
const difficultyPoint = (_a = group.difficulty) !== null && _a !== void 0 ? _a : this.map.controlPoints.difficulty.controlPointAt(group.time);
|
|
9439
|
-
this.write(`${-100 / difficultyPoint.speedMultiplier},`);
|
|
9489
|
+
this.write(`${(-100 / difficultyPoint.speedMultiplier).toString()},`);
|
|
9440
9490
|
this.outputControlPointGroup(group, false);
|
|
9441
9491
|
}
|
|
9442
9492
|
}
|
|
@@ -9484,7 +9534,7 @@ class BeatmapControlPointsEncoder extends BeatmapBaseEncoder {
|
|
|
9484
9534
|
if (effectPoint.omitFirstBarLine) {
|
|
9485
9535
|
effectFlags |= EffectFlags.omitFirstBarLine;
|
|
9486
9536
|
}
|
|
9487
|
-
this.write(`${((_c = group.timing) !== null && _c !== void 0 ? _c : this.map.controlPoints.timing.controlPointAt(group.time)).timeSignature},`);
|
|
9537
|
+
this.write(`${((_c = group.timing) !== null && _c !== void 0 ? _c : this.map.controlPoints.timing.controlPointAt(group.time)).timeSignature.toString()},`);
|
|
9488
9538
|
this.write(`${samplePoint.sampleBank.toString()},`);
|
|
9489
9539
|
this.write(`${samplePoint.customSampleBank.toString()},`);
|
|
9490
9540
|
this.write(`${samplePoint.sampleVolume.toString()},`);
|
|
@@ -9503,12 +9553,12 @@ class BeatmapDifficultyEncoder extends BeatmapBaseEncoder {
|
|
|
9503
9553
|
this.writeLine("[Difficulty]");
|
|
9504
9554
|
}
|
|
9505
9555
|
const { difficulty } = this.map;
|
|
9506
|
-
this.writeLine(`HPDrainRate: ${difficulty.hp}`);
|
|
9507
|
-
this.writeLine(`CircleSize: ${difficulty.cs}`);
|
|
9508
|
-
this.writeLine(`OverallDifficulty: ${difficulty.od}`);
|
|
9509
|
-
this.writeLine(`ApproachRate: ${difficulty.ar}`);
|
|
9510
|
-
this.writeLine(`SliderMultiplier: ${difficulty.sliderMultiplier}`);
|
|
9511
|
-
this.writeLine(`SliderTickRate: ${difficulty.sliderTickRate}`);
|
|
9556
|
+
this.writeLine(`HPDrainRate: ${difficulty.hp.toString()}`);
|
|
9557
|
+
this.writeLine(`CircleSize: ${difficulty.cs.toString()}`);
|
|
9558
|
+
this.writeLine(`OverallDifficulty: ${difficulty.od.toString()}`);
|
|
9559
|
+
this.writeLine(`ApproachRate: ${difficulty.ar.toString()}`);
|
|
9560
|
+
this.writeLine(`SliderMultiplier: ${difficulty.sliderMultiplier.toString()}`);
|
|
9561
|
+
this.writeLine(`SliderTickRate: ${difficulty.sliderTickRate.toString()}`);
|
|
9512
9562
|
}
|
|
9513
9563
|
}
|
|
9514
9564
|
|
|
@@ -9524,10 +9574,10 @@ class BeatmapEditorEncoder extends BeatmapBaseEncoder {
|
|
|
9524
9574
|
if (editor.bookmarks.length > 0) {
|
|
9525
9575
|
this.writeLine(editor.bookmarks.join());
|
|
9526
9576
|
}
|
|
9527
|
-
this.writeLine(`DistanceSpacing: ${editor.distanceSnap}`);
|
|
9528
|
-
this.writeLine(`BeatDivisor: ${editor.beatDivisor}`);
|
|
9529
|
-
this.writeLine(`GridSize: ${editor.gridSize}`);
|
|
9530
|
-
this.writeLine(`TimelineZoom: ${editor.timelineZoom}`);
|
|
9577
|
+
this.writeLine(`DistanceSpacing: ${editor.distanceSnap.toString()}`);
|
|
9578
|
+
this.writeLine(`BeatDivisor: ${editor.beatDivisor.toString()}`);
|
|
9579
|
+
this.writeLine(`GridSize: ${editor.gridSize.toString()}`);
|
|
9580
|
+
this.writeLine(`TimelineZoom: ${editor.timelineZoom.toString()}`);
|
|
9531
9581
|
}
|
|
9532
9582
|
}
|
|
9533
9583
|
|
|
@@ -9584,10 +9634,10 @@ class StoryboardEventsEncoder extends StoryboardBaseEncoder {
|
|
|
9584
9634
|
this.write(`${layerType},`);
|
|
9585
9635
|
this.write(`${element.origin},`);
|
|
9586
9636
|
this.write(`"${element.path}",`);
|
|
9587
|
-
this.write(`${element.initialPosition},`);
|
|
9588
|
-
this.write(`${element.frameCount},`);
|
|
9589
|
-
this.write(`${element.frameDelay},`);
|
|
9590
|
-
this.writeLine(
|
|
9637
|
+
this.write(`${element.initialPosition.toString()},`);
|
|
9638
|
+
this.write(`${element.frameCount.toString()},`);
|
|
9639
|
+
this.write(`${element.frameDelay.toString()},`);
|
|
9640
|
+
this.writeLine(element.loopType.toString());
|
|
9591
9641
|
this.encodeElement(element);
|
|
9592
9642
|
}
|
|
9593
9643
|
else if (element instanceof StoryboardSprite) {
|
|
@@ -9595,15 +9645,15 @@ class StoryboardEventsEncoder extends StoryboardBaseEncoder {
|
|
|
9595
9645
|
this.write(`${layerType},`);
|
|
9596
9646
|
this.write(`${element.origin},`);
|
|
9597
9647
|
this.write(`"${element.path}",`);
|
|
9598
|
-
this.writeLine(
|
|
9648
|
+
this.writeLine(element.initialPosition.toString());
|
|
9599
9649
|
this.encodeElement(element);
|
|
9600
9650
|
}
|
|
9601
9651
|
else if (element instanceof StoryboardSample) {
|
|
9602
9652
|
this.write(`${exports.StoryboardEventType.sample},`);
|
|
9603
|
-
this.write(`${element.startTime},`);
|
|
9653
|
+
this.write(`${element.startTime.toString()},`);
|
|
9604
9654
|
this.write(`${layerType},`);
|
|
9605
9655
|
this.write(`"${element.path}",`);
|
|
9606
|
-
this.writeLine(
|
|
9656
|
+
this.writeLine(element.volume.toString());
|
|
9607
9657
|
}
|
|
9608
9658
|
}
|
|
9609
9659
|
}
|
|
@@ -9620,21 +9670,21 @@ class StoryboardEventsEncoder extends StoryboardBaseEncoder {
|
|
|
9620
9670
|
if (group instanceof CommandLoop) {
|
|
9621
9671
|
this.write(" ");
|
|
9622
9672
|
this.write(`${exports.StoryboardCommandType.loop},`);
|
|
9623
|
-
this.write(`${group.startTime},`);
|
|
9624
|
-
this.write(
|
|
9673
|
+
this.write(`${group.startTime.toString()},`);
|
|
9674
|
+
this.write(group.totalIterations.toString());
|
|
9625
9675
|
}
|
|
9626
9676
|
else if (group instanceof CommandTrigger) {
|
|
9627
9677
|
this.write(" ");
|
|
9628
9678
|
this.write(`${exports.StoryboardCommandType.trigger},`);
|
|
9629
|
-
this.write(
|
|
9679
|
+
this.write(group.triggerName);
|
|
9630
9680
|
if (group.triggerEndTime !== Number.MAX_SAFE_INTEGER) {
|
|
9631
9681
|
this.write(",");
|
|
9632
|
-
this.write(`${group.triggerStartTime},`);
|
|
9633
|
-
this.write(
|
|
9682
|
+
this.write(`${group.triggerStartTime.toString()},`);
|
|
9683
|
+
this.write(group.triggerEndTime.toString());
|
|
9634
9684
|
}
|
|
9635
9685
|
if (group.groupNumber !== 0) {
|
|
9636
9686
|
this.write(",");
|
|
9637
|
-
this.write(
|
|
9687
|
+
this.write(group.groupNumber.toString());
|
|
9638
9688
|
}
|
|
9639
9689
|
}
|
|
9640
9690
|
this.encodeTimeline(group.alpha);
|
|
@@ -9655,9 +9705,11 @@ class StoryboardEventsEncoder extends StoryboardBaseEncoder {
|
|
|
9655
9705
|
encodeCommand(command) {
|
|
9656
9706
|
this.write(" ");
|
|
9657
9707
|
this.write(`${command.type},`);
|
|
9658
|
-
this.write(`${command.easing},`);
|
|
9659
|
-
this.write(`${command.startTime},`);
|
|
9660
|
-
this.write(command.startTime !== command.endTime
|
|
9708
|
+
this.write(`${command.easing.toString()},`);
|
|
9709
|
+
this.write(`${command.startTime.toString()},`);
|
|
9710
|
+
this.write(command.startTime !== command.endTime
|
|
9711
|
+
? command.endTime.toString()
|
|
9712
|
+
: "");
|
|
9661
9713
|
this.write(",");
|
|
9662
9714
|
if (command.startValue instanceof Vector2 &&
|
|
9663
9715
|
command.endValue instanceof Vector2) {
|
|
@@ -9752,14 +9804,14 @@ class BeatmapEventsEncoder extends BeatmapBaseEncoder {
|
|
|
9752
9804
|
this.writeLine("//Background and Video Events");
|
|
9753
9805
|
const { events } = this.map;
|
|
9754
9806
|
if (events.background) {
|
|
9755
|
-
this.writeLine(`0,0,"${events.background.filename}",${events.background.offset.x},${events.background.offset.y}`);
|
|
9807
|
+
this.writeLine(`0,0,"${events.background.filename}",${events.background.offset.x.toString()},${events.background.offset.y.toString()}`);
|
|
9756
9808
|
}
|
|
9757
9809
|
if (events.video) {
|
|
9758
|
-
this.writeLine(`Video,${events.video.startTime},"${events.video.filename}",${events.video.offset.x},${events.video.offset.y}`);
|
|
9810
|
+
this.writeLine(`Video,${events.video.startTime.toString()},"${events.video.filename}",${events.video.offset.x.toString()},${events.video.offset.y.toString()}`);
|
|
9759
9811
|
}
|
|
9760
9812
|
this.writeLine("//Break Periods");
|
|
9761
9813
|
for (const b of events.breaks) {
|
|
9762
|
-
this.writeLine(`2,${b.startTime},${b.endTime}`);
|
|
9814
|
+
this.writeLine(`2,${b.startTime.toString()},${b.endTime.toString()}`);
|
|
9763
9815
|
}
|
|
9764
9816
|
if (this.map.events.storyboard) {
|
|
9765
9817
|
this.writeLine(new StoryboardEncoder(this.map.events.storyboard, false).encode().result);
|
|
@@ -9787,20 +9839,20 @@ class BeatmapGeneralEncoder extends BeatmapBaseEncoder {
|
|
|
9787
9839
|
if (general.audioFilename) {
|
|
9788
9840
|
this.writeLine(`AudioFilename: ${general.audioFilename}`);
|
|
9789
9841
|
}
|
|
9790
|
-
this.writeLine(`AudioLeadIn: ${general.audioLeadIn}`);
|
|
9791
|
-
this.writeLine(`PreviewTime: ${general.previewTime}`);
|
|
9792
|
-
this.writeLine(`Countdown: ${general.countdown}`);
|
|
9842
|
+
this.writeLine(`AudioLeadIn: ${general.audioLeadIn.toString()}`);
|
|
9843
|
+
this.writeLine(`PreviewTime: ${general.previewTime.toString()}`);
|
|
9844
|
+
this.writeLine(`Countdown: ${general.countdown.toString()}`);
|
|
9793
9845
|
this.writeLine(`SampleSet: ${this.sampleBankToString(general.sampleBank)}`);
|
|
9794
|
-
this.writeLine(`StackLeniency: ${general.stackLeniency}`);
|
|
9795
|
-
this.writeLine(`Mode: ${general.mode}`);
|
|
9796
|
-
this.writeLine(`LetterboxInBreaks: ${general.letterBoxInBreaks ? 1 : 0}`);
|
|
9846
|
+
this.writeLine(`StackLeniency: ${general.stackLeniency.toString()}`);
|
|
9847
|
+
this.writeLine(`Mode: ${general.mode.toString()}`);
|
|
9848
|
+
this.writeLine(`LetterboxInBreaks: ${general.letterBoxInBreaks ? "1" : "0"}`);
|
|
9797
9849
|
if (general.epilepsyWarning) {
|
|
9798
9850
|
this.writeLine("EpilepsyWarning: 1");
|
|
9799
9851
|
}
|
|
9800
9852
|
if (general.countdownOffset > 0) {
|
|
9801
|
-
this.writeLine(`CountdownOffset: ${general.countdownOffset}`);
|
|
9853
|
+
this.writeLine(`CountdownOffset: ${general.countdownOffset.toString()}`);
|
|
9802
9854
|
}
|
|
9803
|
-
this.writeLine(`WidescreenStoryboard: ${general.widescreenStoryboard ? 1 : 0}`);
|
|
9855
|
+
this.writeLine(`WidescreenStoryboard: ${general.widescreenStoryboard ? "1" : "0"}`);
|
|
9804
9856
|
if (general.samplesMatchPlaybackRate) {
|
|
9805
9857
|
this.writeLine("SamplesMatchPlaybackRate: 1");
|
|
9806
9858
|
}
|
|
@@ -9820,10 +9872,10 @@ class BeatmapHitObjectsEncoder extends BeatmapBaseEncoder {
|
|
|
9820
9872
|
}
|
|
9821
9873
|
}
|
|
9822
9874
|
encodeHitObject(object) {
|
|
9823
|
-
this.write(`${object.position.x},`);
|
|
9824
|
-
this.write(`${object.position.y},`);
|
|
9825
|
-
this.write(`${object.startTime},`);
|
|
9826
|
-
this.write(`${object.type},`);
|
|
9875
|
+
this.write(`${object.position.x.toString()},`);
|
|
9876
|
+
this.write(`${object.position.y.toString()},`);
|
|
9877
|
+
this.write(`${object.startTime.toString()},`);
|
|
9878
|
+
this.write(`${object.type.toString()},`);
|
|
9827
9879
|
this.write(`${this.samplesToHitSoundType(object.samples).toString()},`);
|
|
9828
9880
|
if (object instanceof Slider) {
|
|
9829
9881
|
this.addSliderPath(object);
|
|
@@ -9831,7 +9883,7 @@ class BeatmapHitObjectsEncoder extends BeatmapBaseEncoder {
|
|
|
9831
9883
|
}
|
|
9832
9884
|
else {
|
|
9833
9885
|
if (object instanceof Spinner) {
|
|
9834
|
-
this.write(`${object.endTime},`);
|
|
9886
|
+
this.write(`${object.endTime.toString()},`);
|
|
9835
9887
|
}
|
|
9836
9888
|
this.write(this.getSampleBank(object.samples));
|
|
9837
9889
|
}
|
|
@@ -9864,11 +9916,11 @@ class BeatmapHitObjectsEncoder extends BeatmapBaseEncoder {
|
|
|
9864
9916
|
// start position of the slider.
|
|
9865
9917
|
for (let i = 1; i < slider.path.controlPoints.length; ++i) {
|
|
9866
9918
|
const realPosition = slider.path.controlPoints[i].add(slider.position);
|
|
9867
|
-
this.write(`${realPosition.x}:${realPosition.y}`);
|
|
9919
|
+
this.write(`${realPosition.x.toString()}:${realPosition.y.toString()}`);
|
|
9868
9920
|
this.write(i != slider.path.controlPoints.length - 1 ? "|" : ",");
|
|
9869
9921
|
}
|
|
9870
|
-
this.write(`${slider.
|
|
9871
|
-
this.write(`${slider.path.expectedDistance},`);
|
|
9922
|
+
this.write(`${slider.spanCount.toString()},`);
|
|
9923
|
+
this.write(`${slider.path.expectedDistance.toString()},`);
|
|
9872
9924
|
// edgeSamples
|
|
9873
9925
|
for (let i = 0; i < slider.nodeSamples.length; ++i) {
|
|
9874
9926
|
this.write(this.samplesToHitSoundType(slider.nodeSamples[i]).toString());
|
|
@@ -9887,14 +9939,14 @@ class BeatmapHitObjectsEncoder extends BeatmapBaseEncoder {
|
|
|
9887
9939
|
const addBank = (_d = (_c = samples.find((s) => s instanceof BankHitSampleInfo &&
|
|
9888
9940
|
s.name &&
|
|
9889
9941
|
s.name !== BankHitSampleInfo.HIT_NORMAL)) === null || _c === void 0 ? void 0 : _c.bank) !== null && _d !== void 0 ? _d : exports.SampleBank.none;
|
|
9890
|
-
let sampleBankString = `${normalBank}:${addBank}`;
|
|
9942
|
+
let sampleBankString = `${normalBank.toString()}:${addBank.toString()}`;
|
|
9891
9943
|
if (!banksOnly) {
|
|
9892
|
-
const firstSample = samples
|
|
9944
|
+
const firstSample = samples.at(0);
|
|
9893
9945
|
sampleBankString += ":";
|
|
9894
9946
|
sampleBankString += `${firstSample instanceof BankHitSampleInfo
|
|
9895
|
-
? firstSample.customSampleBank
|
|
9896
|
-
: 0}:`;
|
|
9897
|
-
sampleBankString += `${(_e = firstSample === null || firstSample === void 0 ? void 0 : firstSample.volume) !== null && _e !== void 0 ? _e : 100}:`;
|
|
9947
|
+
? firstSample.customSampleBank.toString()
|
|
9948
|
+
: "0"}:`;
|
|
9949
|
+
sampleBankString += `${((_e = firstSample === null || firstSample === void 0 ? void 0 : firstSample.volume) !== null && _e !== void 0 ? _e : 100).toString()}:`;
|
|
9898
9950
|
if (firstSample instanceof FileHitSampleInfo) {
|
|
9899
9951
|
sampleBankString += `${this.sampleBankToString(exports.SampleBank.none)}-${firstSample.filename}`;
|
|
9900
9952
|
}
|
|
@@ -9916,7 +9968,6 @@ class BeatmapHitObjectsEncoder extends BeatmapBaseEncoder {
|
|
|
9916
9968
|
*/
|
|
9917
9969
|
class BeatmapMetadataEncoder extends BeatmapBaseEncoder {
|
|
9918
9970
|
encodeInternal() {
|
|
9919
|
-
var _a, _b;
|
|
9920
9971
|
if (this.encodeSections) {
|
|
9921
9972
|
this.writeLine("[Metadata]");
|
|
9922
9973
|
}
|
|
@@ -9937,11 +9988,11 @@ class BeatmapMetadataEncoder extends BeatmapBaseEncoder {
|
|
|
9937
9988
|
if (metadata.tags.length > 0) {
|
|
9938
9989
|
this.writeLine(`Tags: ${metadata.tags.join(" ")}`);
|
|
9939
9990
|
}
|
|
9940
|
-
if (
|
|
9941
|
-
this.writeLine(`BeatmapID: ${metadata.beatmapId}`);
|
|
9991
|
+
if (metadata.beatmapId !== undefined && metadata.beatmapId > 0) {
|
|
9992
|
+
this.writeLine(`BeatmapID: ${metadata.beatmapId.toString()}`);
|
|
9942
9993
|
}
|
|
9943
|
-
if (
|
|
9944
|
-
this.writeLine(`BeatmapSetID: ${metadata.beatmapSetId}`);
|
|
9994
|
+
if (metadata.beatmapSetId !== undefined && metadata.beatmapSetId > 0) {
|
|
9995
|
+
this.writeLine(`BeatmapSetID: ${metadata.beatmapSetId.toString()}`);
|
|
9945
9996
|
}
|
|
9946
9997
|
}
|
|
9947
9998
|
}
|
|
@@ -9959,7 +10010,7 @@ class BeatmapEncoder extends Encoder {
|
|
|
9959
10010
|
this.latestVersion = 14;
|
|
9960
10011
|
}
|
|
9961
10012
|
encodeInternal() {
|
|
9962
|
-
this.writeLine(`osu file format v${this.latestVersion}`);
|
|
10013
|
+
this.writeLine(`osu file format v${this.latestVersion.toString()}`);
|
|
9963
10014
|
this.writeLine();
|
|
9964
10015
|
super.encodeInternal();
|
|
9965
10016
|
}
|
|
@@ -10268,7 +10319,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
10268
10319
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
10269
10320
|
PERFORMANCE OF THIS SOFTWARE.
|
|
10270
10321
|
***************************************************************************** */
|
|
10271
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
10322
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
10272
10323
|
|
|
10273
10324
|
|
|
10274
10325
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
@@ -10289,6 +10340,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
10289
10340
|
/**
|
|
10290
10341
|
* The base of API request builders.
|
|
10291
10342
|
*/
|
|
10343
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
10292
10344
|
class APIRequestBuilder {
|
|
10293
10345
|
constructor() {
|
|
10294
10346
|
/**
|
|
@@ -10357,22 +10409,24 @@ class APIRequestBuilder {
|
|
|
10357
10409
|
.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
10358
10410
|
++this.fetchAttempts;
|
|
10359
10411
|
if (res.status >= 500 && this.fetchAttempts < 5) {
|
|
10360
|
-
console.error(`Request to ${url} failed with the following error: ${yield res.text()}; ${this.fetchAttempts} attempts so far; retrying`);
|
|
10361
|
-
|
|
10412
|
+
console.error(`Request to ${url} failed with the following error: ${yield res.text()}; ${this.fetchAttempts.toString()} attempts so far; retrying`);
|
|
10413
|
+
resolve(this.sendRequest());
|
|
10414
|
+
return;
|
|
10362
10415
|
}
|
|
10363
10416
|
this.fetchAttempts = 0;
|
|
10364
|
-
|
|
10417
|
+
resolve({
|
|
10365
10418
|
data: Buffer.from(yield res.arrayBuffer()),
|
|
10366
10419
|
statusCode: res.status,
|
|
10367
10420
|
});
|
|
10368
10421
|
}))
|
|
10369
10422
|
.catch((e) => {
|
|
10370
|
-
console.error(`Request to ${url} failed with the following error: ${e.message}; ${this.fetchAttempts} attempts so far; aborting`);
|
|
10423
|
+
console.error(`Request to ${url} failed with the following error: ${e.message}; ${this.fetchAttempts.toString()} attempts so far; aborting`);
|
|
10371
10424
|
this.fetchAttempts = 0;
|
|
10372
|
-
|
|
10425
|
+
resolve({
|
|
10373
10426
|
data: Buffer.from([]),
|
|
10374
10427
|
statusCode: 400,
|
|
10375
10428
|
});
|
|
10429
|
+
return;
|
|
10376
10430
|
});
|
|
10377
10431
|
});
|
|
10378
10432
|
}
|
|
@@ -10976,7 +11030,7 @@ class ErrorFunction {
|
|
|
10976
11030
|
* calculation for erf(x) in the interval [1e-10, 0.5].
|
|
10977
11031
|
*/
|
|
10978
11032
|
ErrorFunction.erfImpAn = [
|
|
10979
|
-
0.003379167095512574, -
|
|
11033
|
+
0.003379167095512574, -7369565304816795e-19, -0.3747323373929196,
|
|
10980
11034
|
0.0817442448733587, -0.04210893199365486, 0.007016570951209576,
|
|
10981
11035
|
-0.004950912559824351, 0.0008716465990379225,
|
|
10982
11036
|
];
|
|
@@ -10987,7 +11041,7 @@ ErrorFunction.erfImpAn = [
|
|
|
10987
11041
|
ErrorFunction.erfImpAd = [
|
|
10988
11042
|
1, -0.2180882180879246, 0.4125429727254421, -0.08418911478731068,
|
|
10989
11043
|
0.0655338856400242, -0.01200196044549418, 0.00408165558926174,
|
|
10990
|
-
-
|
|
11044
|
+
-6159007215577697e-19,
|
|
10991
11045
|
];
|
|
10992
11046
|
/**
|
|
10993
11047
|
* Polynomial coefficients for a numerator in erfImp
|
|
@@ -11038,7 +11092,7 @@ ErrorFunction.erfImpDn = [
|
|
|
11038
11092
|
ErrorFunction.erfImpDd = [
|
|
11039
11093
|
1, 1.7596709814716753, 1.3288357143796112, 0.5525285965087576,
|
|
11040
11094
|
0.1337930569413329, 0.017950964517628076, 0.001047124400199374,
|
|
11041
|
-
-
|
|
11095
|
+
-1.0664038182035734e-8,
|
|
11042
11096
|
];
|
|
11043
11097
|
/**
|
|
11044
11098
|
* Polynomial coefficients for a numerator in erfImp
|
|
@@ -11073,7 +11127,7 @@ ErrorFunction.erfImpFn = [
|
|
|
11073
11127
|
ErrorFunction.erfImpFd = [
|
|
11074
11128
|
1, 1.210196977736308, 0.6209146682211439, 0.1730384306611428,
|
|
11075
11129
|
0.0276550813773432, 0.002406259744243097, 0.8918118172513366e-4,
|
|
11076
|
-
-
|
|
11130
|
+
-4655288362833827e-27,
|
|
11077
11131
|
];
|
|
11078
11132
|
/**
|
|
11079
11133
|
* Polynomial coefficients for a numerator in erfImp
|
|
@@ -11112,7 +11166,7 @@ ErrorFunction.erfImpHd = [
|
|
|
11112
11166
|
* calculation for erfc(x) in the interval [11.5, 17].
|
|
11113
11167
|
*/
|
|
11114
11168
|
ErrorFunction.erfImpIn = [
|
|
11115
|
-
-
|
|
11169
|
+
-5690799360109496e-19, 0.0001694985403737623, 0.5184723545811009e-4,
|
|
11116
11170
|
0.38281931223192885e-5, 0.8249899312818944e-7,
|
|
11117
11171
|
];
|
|
11118
11172
|
/**
|
|
@@ -11121,14 +11175,14 @@ ErrorFunction.erfImpIn = [
|
|
|
11121
11175
|
*/
|
|
11122
11176
|
ErrorFunction.erfImpId = [
|
|
11123
11177
|
1, 0.3396372500511393, 0.04347264787031066, 0.002485493352246371,
|
|
11124
|
-
0.5356333053371529e-4, -
|
|
11178
|
+
0.5356333053371529e-4, -11749094440545958e-29,
|
|
11125
11179
|
];
|
|
11126
11180
|
/**
|
|
11127
11181
|
* Polynomial coefficients for a numerator in erfImp
|
|
11128
11182
|
* calculation for erfc(x) in the interval [17, 24].
|
|
11129
11183
|
*/
|
|
11130
11184
|
ErrorFunction.erfImpJn = [
|
|
11131
|
-
-
|
|
11185
|
+
-24131359948399134e-20, 0.5742249752025015e-4, 0.11599896292738377e-4,
|
|
11132
11186
|
0.581762134402594e-6, 0.8539715550856736e-8,
|
|
11133
11187
|
];
|
|
11134
11188
|
/**
|
|
@@ -11144,7 +11198,7 @@ ErrorFunction.erfImpJd = [
|
|
|
11144
11198
|
* calculation for erfc(x) in the interval [24, 38].
|
|
11145
11199
|
*/
|
|
11146
11200
|
ErrorFunction.erfImpKn = [
|
|
11147
|
-
-
|
|
11201
|
+
-14667469927776036e-20, 0.1626665521122805e-4, 0.26911624850916523e-5,
|
|
11148
11202
|
0.979584479468092e-7, 0.10199464762572346e-8,
|
|
11149
11203
|
];
|
|
11150
11204
|
/**
|
|
@@ -11160,7 +11214,7 @@ ErrorFunction.erfImpKd = [
|
|
|
11160
11214
|
* calculation for erfc(x) in the interval [38, 60].
|
|
11161
11215
|
*/
|
|
11162
11216
|
ErrorFunction.erfImpLn = [
|
|
11163
|
-
-
|
|
11217
|
+
-5839057976297718e-20, 0.4125103251054962e-5, 0.43179092242025094e-6,
|
|
11164
11218
|
0.9933651555900132e-8, 0.653480510020105e-10,
|
|
11165
11219
|
];
|
|
11166
11220
|
/**
|
|
@@ -11176,7 +11230,7 @@ ErrorFunction.erfImpLd = [
|
|
|
11176
11230
|
* calculation for erfc(x) in the interval [60, 85].
|
|
11177
11231
|
*/
|
|
11178
11232
|
ErrorFunction.erfImpMn = [
|
|
11179
|
-
-
|
|
11233
|
+
-19645779760922958e-21, 0.1572438876668007e-5, 0.5439025111927009e-7,
|
|
11180
11234
|
0.3174724923691177e-9,
|
|
11181
11235
|
];
|
|
11182
11236
|
/**
|
|
@@ -11192,7 +11246,7 @@ ErrorFunction.erfImpMd = [
|
|
|
11192
11246
|
* calculation for erfc(x) in the interval [85, 110].
|
|
11193
11247
|
*/
|
|
11194
11248
|
ErrorFunction.erfImpNn = [
|
|
11195
|
-
-
|
|
11249
|
+
-789224703978723e-20, 0.622088451660987e-6, 0.1457284456768824e-7,
|
|
11196
11250
|
0.603715505542715e-10,
|
|
11197
11251
|
];
|
|
11198
11252
|
/**
|
|
@@ -11209,7 +11263,7 @@ ErrorFunction.erfImpNd = [
|
|
|
11209
11263
|
* calculation for erf^-1(z) in the interval [0, 0.5].
|
|
11210
11264
|
*/
|
|
11211
11265
|
ErrorFunction.ervInvImpAn = [
|
|
11212
|
-
-
|
|
11266
|
+
-5087819496582806e-19, -0.008368748197417368, 0.033480662540974461,
|
|
11213
11267
|
-0.012692614766297402, -0.03656379714117627, 0.02198786811111689,
|
|
11214
11268
|
0.008226878746769157, -0.005387729650712429,
|
|
11215
11269
|
];
|
|
@@ -11247,8 +11301,8 @@ ErrorFunction.ervInvImpBd = [
|
|
|
11247
11301
|
ErrorFunction.ervInvImpCn = [
|
|
11248
11302
|
-0.1311027816799519, -0.1637940471933171, 0.11703015634199525,
|
|
11249
11303
|
0.387079738972604337, 0.3377855389120359, 0.1428695344081572,
|
|
11250
|
-
0.029015791000532906, 0.002145589953888053, -
|
|
11251
|
-
0.2852253317822171e-7, -
|
|
11304
|
+
0.029015791000532906, 0.002145589953888053, -6.794655751811264e-7,
|
|
11305
|
+
0.2852253317822171e-7, -681149956853777e-24,
|
|
11252
11306
|
];
|
|
11253
11307
|
/**
|
|
11254
11308
|
* Polynomial coefficients for a denominator of erfInvImp
|
|
@@ -11266,7 +11320,7 @@ ErrorFunction.ervInvImpCd = [
|
|
|
11266
11320
|
ErrorFunction.ervInvImpDn = [
|
|
11267
11321
|
-0.0350353787183178, -0.002224265292134479, 0.018557330651423107,
|
|
11268
11322
|
0.009508047013259196, 0.001871234928195592, 0.00015754461742496055,
|
|
11269
|
-
0.460469890584318e-5, -
|
|
11323
|
+
0.460469890584318e-5, -2304047769118826e-25, 0.266339227425782e-11,
|
|
11270
11324
|
];
|
|
11271
11325
|
/**
|
|
11272
11326
|
* Polynomial coefficients for a denominator of erfInvImp
|
|
@@ -11283,7 +11337,7 @@ ErrorFunction.ervInvImpDd = [
|
|
|
11283
11337
|
ErrorFunction.ervInvImpEn = [
|
|
11284
11338
|
-0.016743100507663373, -0.001129514387455803, 0.001056288621524929,
|
|
11285
11339
|
0.0002093863174875881, 0.14962478375834237e-4, 0.4496967899277065e-6,
|
|
11286
|
-
0.4625961635228786e-8, -
|
|
11340
|
+
0.4625961635228786e-8, -2811287356288318e-29,
|
|
11287
11341
|
0.9905570997331033e-16,
|
|
11288
11342
|
];
|
|
11289
11343
|
/**
|
|
@@ -11299,9 +11353,9 @@ ErrorFunction.ervInvImpEd = [
|
|
|
11299
11353
|
* calculation for erf^-1(z) in the interval [0.75, 1] with x between 18 and 44.
|
|
11300
11354
|
*/
|
|
11301
11355
|
ErrorFunction.ervInvImpFn = [
|
|
11302
|
-
-0.
|
|
11356
|
+
-0.002497821279189813, -779190719229054e-20, 0.2547230374130275e-4,
|
|
11303
11357
|
0.1623977773425109e-5, 0.3963410113048011685e-7, 0.4116328311909442e-9,
|
|
11304
|
-
0.145596286718675e-11, -
|
|
11358
|
+
0.145596286718675e-11, -11676501239718427e-34,
|
|
11305
11359
|
];
|
|
11306
11360
|
/**
|
|
11307
11361
|
* Polynomial coefficients for a denominator of erfInvImp
|
|
@@ -11316,9 +11370,9 @@ ErrorFunction.ervInvImpFd = [
|
|
|
11316
11370
|
* calculation for erf^-1(z) in the interval [0.75, 1] with x greater than 44.
|
|
11317
11371
|
*/
|
|
11318
11372
|
ErrorFunction.ervInvImpGn = [
|
|
11319
|
-
-
|
|
11373
|
+
-5390429110190786e-19, -2.839875900472772e-7, 0.8994651148922914e-6,
|
|
11320
11374
|
0.2293458592659209e-7, 0.2255614448635001e-9, 0.9478466275030226e-12,
|
|
11321
|
-
0.13588013010892486e-14, -
|
|
11375
|
+
0.13588013010892486e-14, -3488903933999489e-37,
|
|
11322
11376
|
];
|
|
11323
11377
|
/**
|
|
11324
11378
|
* Polynomial coefficients for a denominator of erfInvImp
|
|
@@ -11553,13 +11607,13 @@ class MapInfo {
|
|
|
11553
11607
|
* The osu! site link to this beatmap.
|
|
11554
11608
|
*/
|
|
11555
11609
|
get beatmapLink() {
|
|
11556
|
-
return `https://osu.ppy.sh/b/${this.beatmapId}`;
|
|
11610
|
+
return `https://osu.ppy.sh/b/${this.beatmapId.toString()}`;
|
|
11557
11611
|
}
|
|
11558
11612
|
/**
|
|
11559
11613
|
* The osu! site link to this beatmapset.
|
|
11560
11614
|
*/
|
|
11561
11615
|
get beatmapSetLink() {
|
|
11562
|
-
return `https://osu.ppy.sh/s/${this.beatmapSetId}`;
|
|
11616
|
+
return `https://osu.ppy.sh/s/${this.beatmapSetId.toString()}`;
|
|
11563
11617
|
}
|
|
11564
11618
|
static getInformation(beatmapIdOrHash, downloadBeatmap) {
|
|
11565
11619
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -11570,7 +11624,7 @@ class MapInfo {
|
|
|
11570
11624
|
if (result.statusCode !== 200) {
|
|
11571
11625
|
throw new Error("osu! API error");
|
|
11572
11626
|
}
|
|
11573
|
-
const mapinfo = JSON.parse(result.data.toString("utf-8"))
|
|
11627
|
+
const mapinfo = JSON.parse(result.data.toString("utf-8")).at(0);
|
|
11574
11628
|
if (!mapinfo) {
|
|
11575
11629
|
return null;
|
|
11576
11630
|
}
|
|
@@ -11655,7 +11709,7 @@ class MapInfo {
|
|
|
11655
11709
|
toAPIResponse() {
|
|
11656
11710
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
11657
11711
|
const padDateNumber = (num) => num.toString().padStart(2, "0");
|
|
11658
|
-
const convertDate = (date) => `${date.getUTCFullYear()}-${padDateNumber(date.getUTCMonth() + 1)}-${padDateNumber(date.getUTCDate())} ${padDateNumber(date.getUTCHours())}:${padDateNumber(date.getUTCMinutes())}:${padDateNumber(date.getUTCSeconds())}`;
|
|
11712
|
+
const convertDate = (date) => `${date.getUTCFullYear().toString()}-${padDateNumber(date.getUTCMonth() + 1)}-${padDateNumber(date.getUTCDate())} ${padDateNumber(date.getUTCHours())}:${padDateNumber(date.getUTCMinutes())}:${padDateNumber(date.getUTCSeconds())}`;
|
|
11659
11713
|
return {
|
|
11660
11714
|
approved: this.approved.toString(),
|
|
11661
11715
|
submit_date: convertDate(this.submitDate),
|
|
@@ -11667,7 +11721,7 @@ class MapInfo {
|
|
|
11667
11721
|
beatmap_id: this.beatmapId.toString(),
|
|
11668
11722
|
beatmapset_id: this.beatmapSetId.toString(),
|
|
11669
11723
|
bpm: this.bpm.toString(),
|
|
11670
|
-
creator: this.creator
|
|
11724
|
+
creator: this.creator,
|
|
11671
11725
|
creator_id: this.creatorId.toString(),
|
|
11672
11726
|
difficultyrating: (_b = (_a = this.totalDifficulty) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : null,
|
|
11673
11727
|
diff_aim: (_d = (_c = this.aimDifficulty) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : null,
|
|
@@ -11677,13 +11731,13 @@ class MapInfo {
|
|
|
11677
11731
|
diff_approach: this.ar.toString(),
|
|
11678
11732
|
diff_drain: this.hp.toString(),
|
|
11679
11733
|
hit_length: this.hitLength.toString(),
|
|
11680
|
-
source: this.source
|
|
11734
|
+
source: this.source,
|
|
11681
11735
|
genre_id: this.genre.toString(),
|
|
11682
11736
|
language_id: this.language.toString(),
|
|
11683
|
-
title: this.title
|
|
11737
|
+
title: this.title,
|
|
11684
11738
|
total_length: this.totalLength.toString(),
|
|
11685
|
-
version: this.version
|
|
11686
|
-
file_md5: this.hash
|
|
11739
|
+
version: this.version,
|
|
11740
|
+
file_md5: this.hash,
|
|
11687
11741
|
// Guaranteed to be osu!standard for the time being.
|
|
11688
11742
|
mode: "0",
|
|
11689
11743
|
tags: this.tags.join(" "),
|
|
@@ -11720,7 +11774,7 @@ class MapInfo {
|
|
|
11720
11774
|
if (this.hasDownloadedBeatmap() && !force) {
|
|
11721
11775
|
return;
|
|
11722
11776
|
}
|
|
11723
|
-
const url = `https://osu.ppy.sh/osu/${this.beatmapId}`;
|
|
11777
|
+
const url = `https://osu.ppy.sh/osu/${this.beatmapId.toString()}`;
|
|
11724
11778
|
return fetch(url)
|
|
11725
11779
|
.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
11726
11780
|
const text = yield res.text();
|
|
@@ -11730,7 +11784,7 @@ class MapInfo {
|
|
|
11730
11784
|
this.cachedBeatmap = new BeatmapDecoder().decode(text).result;
|
|
11731
11785
|
}))
|
|
11732
11786
|
.catch((e) => {
|
|
11733
|
-
console.error(`Request to ${url} failed with
|
|
11787
|
+
console.error(`Request to ${url} failed with an error, aborting`, e);
|
|
11734
11788
|
});
|
|
11735
11789
|
});
|
|
11736
11790
|
}
|
|
@@ -11748,7 +11802,8 @@ class MapInfo {
|
|
|
11748
11802
|
* Returns a string representative of the class.
|
|
11749
11803
|
*/
|
|
11750
11804
|
toString() {
|
|
11751
|
-
|
|
11805
|
+
var _a, _b;
|
|
11806
|
+
return `${this.fullTitle}\nCS: ${this.cs.toString()} - AR: ${this.ar.toString()} - OD: ${this.od.toString()} - HP: ${this.hp.toString()}\nBPM: ${this.bpm.toString()} - Length: ${this.hitLength.toString()}/${this.totalLength.toString()} - Max Combo: ${(_b = (_a = this.maxCombo) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "N/A"}\nLast Update: ${this.lastUpdate.toUTCString()}`;
|
|
11752
11807
|
}
|
|
11753
11808
|
}
|
|
11754
11809
|
|