@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 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 CircleSize among beatmaps.
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 amount of misses that are filtered out from sliderbreaks.
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
- let combo = (_b = options === null || options === void 0 ? void 0 : options.combo) !== null && _b !== void 0 ? _b : maxCombo - miss;
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(combo, maxCombo);
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
- // Graph: https://www.desmos.com/calculator/bc9eybdthb
2315
- // We use OD13.3 as maximum since it's the value at which great hit window becomes 0.
2316
- const n100Multiplier = Math.max(0, this.difficultyAttributes.overallDifficulty > 0
2317
- ? 1 -
2318
- Math.pow(this.difficultyAttributes.overallDifficulty /
2319
- 13.33, 1.8)
2320
- : 1);
2321
- const n50Multiplier = Math.max(0, this.difficultyAttributes.overallDifficulty > 0
2322
- ? 1 -
2323
- Math.pow(this.difficultyAttributes.overallDifficulty /
2324
- 13.33, 5)
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(combo, maxCombo) {
2378
+ calculateEffectiveMissCount(maxCombo) {
2374
2379
  let missCount = this.computedAccuracy.nmiss;
2375
- const { sliderCount } = this.difficultyAttributes;
2376
- if (sliderCount > 0) {
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.82",
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": "de134bf082f310d8b84bfa2d99f42d1f2044398b"
41
+ "gitHead": "da2dd374cbbd45f8956f09a1248809318ac7025a"
42
42
  }
@@ -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 that are filtered out from sliderbreaks.
967
+ * The amount of misses, including slider nested misses.
964
968
  */
965
969
  protected effectiveMissCount: number;
966
970
  /**