@rian8337/osu-difficulty-calculator 4.0.0-beta.82 → 4.0.0-beta.83
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 +32 -28
- package/package.json +2 -2
- package/typings/index.d.ts +5 -1
package/dist/index.js
CHANGED
|
@@ -326,7 +326,6 @@ class DifficultyHitObject {
|
|
|
326
326
|
}
|
|
327
327
|
setDistances(clockRate) {
|
|
328
328
|
if (this.object instanceof osuBase.Slider) {
|
|
329
|
-
this.calculateSliderCursorPosition();
|
|
330
329
|
this.travelDistance = this.lazyTravelDistance;
|
|
331
330
|
// Bonus for repeat sliders until a better per nested object strain system can be achieved.
|
|
332
331
|
if (this.mode === osuBase.Modes.droid) {
|
|
@@ -343,7 +342,7 @@ class DifficultyHitObject {
|
|
|
343
342
|
this.lastObject instanceof osuBase.Spinner) {
|
|
344
343
|
return;
|
|
345
344
|
}
|
|
346
|
-
// We will scale distances by this factor, so we can assume a uniform
|
|
345
|
+
// We will scale distances by this factor, so we can assume a uniform circle size among beatmaps.
|
|
347
346
|
let scalingFactor = DifficultyHitObject.normalizedRadius / this.object.radius;
|
|
348
347
|
// High circle size (small CS) bonus
|
|
349
348
|
if (this.mode === osuBase.Modes.osu && this.object.radius < 30) {
|
|
@@ -2193,7 +2192,11 @@ class PerformanceCalculator {
|
|
|
2193
2192
|
*/
|
|
2194
2193
|
this.computedAccuracy = new osuBase.Accuracy({});
|
|
2195
2194
|
/**
|
|
2196
|
-
* The
|
|
2195
|
+
* The calculated maximum combo.
|
|
2196
|
+
*/
|
|
2197
|
+
this.combo = 0;
|
|
2198
|
+
/**
|
|
2199
|
+
* The amount of misses, including slider nested misses.
|
|
2197
2200
|
*/
|
|
2198
2201
|
this.effectiveMissCount = 0;
|
|
2199
2202
|
/**
|
|
@@ -2287,7 +2290,7 @@ class PerformanceCalculator {
|
|
|
2287
2290
|
}
|
|
2288
2291
|
const maxCombo = this.difficultyAttributes.maxCombo;
|
|
2289
2292
|
const miss = this.computedAccuracy.nmiss;
|
|
2290
|
-
|
|
2293
|
+
this.combo = (_b = options === null || options === void 0 ? void 0 : options.combo) !== null && _b !== void 0 ? _b : maxCombo - miss;
|
|
2291
2294
|
if ((options === null || options === void 0 ? void 0 : options.sliderEndsDropped) !== undefined &&
|
|
2292
2295
|
(options === null || options === void 0 ? void 0 : options.sliderTicksMissed) !== undefined) {
|
|
2293
2296
|
this._usingClassicSliderAccuracy = false;
|
|
@@ -2300,8 +2303,8 @@ class PerformanceCalculator {
|
|
|
2300
2303
|
this.sliderTicksMissed = 0;
|
|
2301
2304
|
}
|
|
2302
2305
|
// Ensure that combo is within possible bounds.
|
|
2303
|
-
combo = osuBase.MathUtils.clamp(combo, 0, maxCombo - miss - this.sliderEndsDropped - this.sliderTicksMissed);
|
|
2304
|
-
this.effectiveMissCount = this.calculateEffectiveMissCount(
|
|
2306
|
+
this.combo = osuBase.MathUtils.clamp(this.combo, 0, maxCombo - miss - this.sliderEndsDropped - this.sliderTicksMissed);
|
|
2307
|
+
this.effectiveMissCount = this.calculateEffectiveMissCount(maxCombo);
|
|
2305
2308
|
if (this.mods.has(osuBase.ModNoFail)) {
|
|
2306
2309
|
this.finalMultiplier *= Math.max(0.9, 1 - 0.02 * this.effectiveMissCount);
|
|
2307
2310
|
}
|
|
@@ -2311,18 +2314,20 @@ class PerformanceCalculator {
|
|
|
2311
2314
|
Math.pow(this.difficultyAttributes.spinnerCount / this.totalHits, 0.85);
|
|
2312
2315
|
}
|
|
2313
2316
|
if (this.mods.has(osuBase.ModRelax)) {
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
: 1);
|
|
2317
|
+
const { overallDifficulty: od } = this.difficultyAttributes;
|
|
2318
|
+
let n100Multiplier;
|
|
2319
|
+
if (this.mode === osuBase.Modes.droid) {
|
|
2320
|
+
// Graph: https://www.desmos.com/calculator/vspzsop6td
|
|
2321
|
+
// We use OD13.3 as maximum since it's the value at which great hit window becomes 0.
|
|
2322
|
+
n100Multiplier =
|
|
2323
|
+
0.75 * Math.max(0, od > 0 ? 1 - od / 13.33 : 1);
|
|
2324
|
+
}
|
|
2325
|
+
else {
|
|
2326
|
+
// Graph: https://www.desmos.com/calculator/bc9eybdthb
|
|
2327
|
+
// We use OD13.3 as maximum since it's the value at which great hit window becomes 0.
|
|
2328
|
+
n100Multiplier = Math.max(0, od > 0 ? 1 - Math.pow(od / 13.33, 1.8) : 1);
|
|
2329
|
+
}
|
|
2330
|
+
const n50Multiplier = Math.max(0, od > 0 ? 1 - Math.pow(od / 13.33, 5) : 1);
|
|
2326
2331
|
// As we're adding 100s and 50s to an approximated number of combo breaks, the result can be higher
|
|
2327
2332
|
// than total hits in specific scenarios (which breaks some calculations), so we need to clamp it.
|
|
2328
2333
|
this.effectiveMissCount = Math.min(this.effectiveMissCount +
|
|
@@ -2335,7 +2340,7 @@ class PerformanceCalculator {
|
|
|
2335
2340
|
if (this.usingClassicSliderAccuracy) {
|
|
2336
2341
|
// When the score is considered classic (regardless if it was made on old client or not),
|
|
2337
2342
|
// we consider all missing combo to be dropped difficult sliders.
|
|
2338
|
-
estimateImproperlyFollowedDifficultSliders = osuBase.MathUtils.clamp(Math.min(this.totalImperfectHits, maxCombo - combo), 0, aimDifficultSliderCount);
|
|
2343
|
+
estimateImproperlyFollowedDifficultSliders = osuBase.MathUtils.clamp(Math.min(this.totalImperfectHits, maxCombo - this.combo), 0, aimDifficultSliderCount);
|
|
2339
2344
|
}
|
|
2340
2345
|
else {
|
|
2341
2346
|
// We add tick misses here since they too mean that the player didn't follow the slider
|
|
@@ -2370,26 +2375,25 @@ class PerformanceCalculator {
|
|
|
2370
2375
|
/**
|
|
2371
2376
|
* Calculates the amount of misses + sliderbreaks from combo.
|
|
2372
2377
|
*/
|
|
2373
|
-
calculateEffectiveMissCount(
|
|
2378
|
+
calculateEffectiveMissCount(maxCombo) {
|
|
2374
2379
|
let missCount = this.computedAccuracy.nmiss;
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
if (this.usingClassicSliderAccuracy || this.mode === osuBase.Modes.droid) {
|
|
2380
|
+
if (this.difficultyAttributes.sliderCount > 0) {
|
|
2381
|
+
if (this.usingClassicSliderAccuracy) {
|
|
2378
2382
|
// Consider that full combo is maximum combo minus dropped slider tails since
|
|
2379
2383
|
// they don't contribute to combo but also don't break it.
|
|
2380
2384
|
// In classic scores, we can't know the amount of dropped sliders so we estimate
|
|
2381
2385
|
// to 10% of all sliders in the beatmap.
|
|
2382
|
-
const fullComboThreshold = maxCombo - 0.1 * sliderCount;
|
|
2383
|
-
if (combo < fullComboThreshold) {
|
|
2384
|
-
missCount = fullComboThreshold / Math.max(1, combo);
|
|
2386
|
+
const fullComboThreshold = maxCombo - 0.1 * this.difficultyAttributes.sliderCount;
|
|
2387
|
+
if (this.combo < fullComboThreshold) {
|
|
2388
|
+
missCount = fullComboThreshold / Math.max(1, this.combo);
|
|
2385
2389
|
}
|
|
2386
2390
|
// In classic scores, there can't be more misses than a sum of all non-perfect judgements.
|
|
2387
2391
|
missCount = Math.min(missCount, this.totalImperfectHits);
|
|
2388
2392
|
}
|
|
2389
2393
|
else {
|
|
2390
2394
|
const fullComboThreshold = maxCombo - this.sliderEndsDropped;
|
|
2391
|
-
if (combo < fullComboThreshold) {
|
|
2392
|
-
missCount = fullComboThreshold / Math.max(1, combo);
|
|
2395
|
+
if (this.combo < fullComboThreshold) {
|
|
2396
|
+
missCount = fullComboThreshold / Math.max(1, this.combo);
|
|
2393
2397
|
}
|
|
2394
2398
|
// Combine regular misses with tick misses, since tick misses break combo as well.
|
|
2395
2399
|
missCount = Math.min(missCount, this.sliderTicksMissed + this.computedAccuracy.nmiss);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rian8337/osu-difficulty-calculator",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.83",
|
|
4
4
|
"description": "A module for calculating osu!standard beatmap difficulty and performance value with respect to the current difficulty and performance algorithm.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"osu",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "da2dd374cbbd45f8956f09a1248809318ac7025a"
|
|
42
42
|
}
|
package/typings/index.d.ts
CHANGED
|
@@ -941,6 +941,10 @@ declare abstract class PerformanceCalculator<T extends IDifficultyAttributes> {
|
|
|
941
941
|
* The calculated accuracy.
|
|
942
942
|
*/
|
|
943
943
|
computedAccuracy: Accuracy;
|
|
944
|
+
/**
|
|
945
|
+
* The calculated maximum combo.
|
|
946
|
+
*/
|
|
947
|
+
combo: number;
|
|
944
948
|
/**
|
|
945
949
|
* The difficulty attributes that is being calculated.
|
|
946
950
|
*/
|
|
@@ -960,7 +964,7 @@ declare abstract class PerformanceCalculator<T extends IDifficultyAttributes> {
|
|
|
960
964
|
*/
|
|
961
965
|
protected abstract readonly mode: Modes;
|
|
962
966
|
/**
|
|
963
|
-
* The amount of misses
|
|
967
|
+
* The amount of misses, including slider nested misses.
|
|
964
968
|
*/
|
|
965
969
|
protected effectiveMissCount: number;
|
|
966
970
|
/**
|