@rian8337/osu-difficulty-calculator 1.2.1 → 1.2.9
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/README.md +102 -2
- package/dist/DroidPerformanceCalculator.js +2 -5
- package/dist/DroidStarRating.js +3 -1
- package/dist/OsuStarRating.js +41 -29
- package/package.json +4 -4
- package/typings/index.d.ts +32 -20
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ yarn add @rian8337/osu-base @rian8337/osu-difficulty-calculator
|
|
|
26
26
|
|
|
27
27
|
# Usage
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Difficulty calculator
|
|
30
30
|
|
|
31
31
|
```js
|
|
32
32
|
import { MapInfo } from "@rian8337/osu-base";
|
|
@@ -67,7 +67,7 @@ console.log(rating.droidStars);
|
|
|
67
67
|
console.log(rating.pcStars);
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
### Specifying difficulty calculation parameters
|
|
71
71
|
|
|
72
72
|
Parameters can be applied to alter the result of the calculation:
|
|
73
73
|
|
|
@@ -104,3 +104,103 @@ console.log(rating.droidStars);
|
|
|
104
104
|
// osu!standard difficulty
|
|
105
105
|
console.log(rating.pcStars);
|
|
106
106
|
```
|
|
107
|
+
|
|
108
|
+
## Performance calculator
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
import { MapInfo } from "@rian8337/osu-base";
|
|
112
|
+
import {
|
|
113
|
+
DroidPerformanceCalculator,
|
|
114
|
+
MapStars,
|
|
115
|
+
OsuPerformanceCalculator,
|
|
116
|
+
} from "@rian8337/osu-difficulty-calculator";
|
|
117
|
+
|
|
118
|
+
const beatmapInfo = await MapInfo.getInformation({ beatmapID: 901854 });
|
|
119
|
+
|
|
120
|
+
if (!beatmapInfo.title) {
|
|
121
|
+
return console.log("Beatmap not found");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const rating = new MapStars().calculate({
|
|
125
|
+
map: beatmapInfo.map,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// osu!droid performance
|
|
129
|
+
const droidPerformance = new DroidPerformanceCalculator().calculate({
|
|
130
|
+
stars: rating.droidStars,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
console.log(droidPerformance);
|
|
134
|
+
|
|
135
|
+
// osu!standard performance
|
|
136
|
+
const osuPerformance = new OsuPerformanceCalculator().calculate({
|
|
137
|
+
stars: rating.pcStars,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
console.log(osuPerformance);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Specifying performance calculation parameters
|
|
144
|
+
|
|
145
|
+
Parameters can be passed to alter the result of the calculation:
|
|
146
|
+
|
|
147
|
+
- Combo: The maximum combo achieved. Defaults to the beatmap's maximum combo.
|
|
148
|
+
- Accuracy: The accuracy achieved. Defaults to 100%.
|
|
149
|
+
- Misses: The amount of misses achieved.
|
|
150
|
+
- Tap penalty: Penalty given from three-finger detection. Only applied for osu!droid gamemode. Defaults to 1.
|
|
151
|
+
- Custom statistics: Used to apply a custom speed multiplier and force AR. Defaults to none.
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
import { Accuracy, MapInfo, MapStats } from "@rian8337/osu-base";
|
|
155
|
+
import {
|
|
156
|
+
OsuPerformanceCalculator,
|
|
157
|
+
OsuStarRating,
|
|
158
|
+
} from "@rian8337/osu-difficulty-calculator";
|
|
159
|
+
|
|
160
|
+
const beatmapInfo = await MapInfo.getInformation({ beatmapID: 901854 });
|
|
161
|
+
|
|
162
|
+
if (!beatmapInfo.title) {
|
|
163
|
+
return console.log("Beatmap not found");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const rating = new OsuStarRating().calculate({
|
|
167
|
+
map: beatmapInfo.map,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const accuracy = new Accuracy({
|
|
171
|
+
// Specify your misses here
|
|
172
|
+
nmiss: 1,
|
|
173
|
+
|
|
174
|
+
// The module provides a convenient way to specify accuracy based on the data that you have
|
|
175
|
+
// Remove the codes below as you see fit
|
|
176
|
+
|
|
177
|
+
// If you have hit data (amount of 300s, 100s, and 50s)
|
|
178
|
+
n300: 1000,
|
|
179
|
+
n100: 0,
|
|
180
|
+
n50: 0,
|
|
181
|
+
|
|
182
|
+
// If you have accuracy percentage
|
|
183
|
+
// While this method is more convenient to use, the amount of 300s, 100s, and 50s will be estimated
|
|
184
|
+
// This will lead to values being off when calculating for specific accuracies
|
|
185
|
+
percent: 100,
|
|
186
|
+
nobjects: beatmapInfo.objects,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const stats = new MapStats({
|
|
190
|
+
ar: 9.5,
|
|
191
|
+
isForceAR: true,
|
|
192
|
+
speedMultiplier: 1.25,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const performance = new OsuPerformanceCalculator().calculate({
|
|
196
|
+
stars: rating,
|
|
197
|
+
combo: 1250,
|
|
198
|
+
accPercent: accuracy,
|
|
199
|
+
// The tap penalty can be properly obtained by checking a replay for three finger usage
|
|
200
|
+
// However, a custom value can also be provided
|
|
201
|
+
tapPenalty: 1.5,
|
|
202
|
+
stats: stats,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
console.log(performance);
|
|
206
|
+
```
|
|
@@ -51,11 +51,8 @@ class DroidPerformanceCalculator extends PerformanceCalculator_1.PerformanceCalc
|
|
|
51
51
|
*/
|
|
52
52
|
calculateAverageRhythmMultiplier() {
|
|
53
53
|
// The first object doesn't have any rhythm multiplier, so we begin with the second object
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
.slice(1);
|
|
57
|
-
this.aggregatedRhythmMultiplier = Math.max(1, rhythmMultipliers.reduce((total, value) => total + value, 0) /
|
|
58
|
-
Math.max(500, rhythmMultipliers.length));
|
|
54
|
+
const rhythmObjects = this.stars.objects.slice(1);
|
|
55
|
+
this.aggregatedRhythmMultiplier = Math.max(1, rhythmObjects.reduce((total, value) => total + value.rhythmMultiplier, 0) / Math.max(500, rhythmObjects.length));
|
|
59
56
|
}
|
|
60
57
|
/**
|
|
61
58
|
* Calculates the aim performance value of the beatmap.
|
package/dist/DroidStarRating.js
CHANGED
|
@@ -115,7 +115,9 @@ class DroidStarRating extends StarRating_1.StarRating {
|
|
|
115
115
|
if (!isRelax) {
|
|
116
116
|
this.postCalculateTap(tapSkill);
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
else {
|
|
119
|
+
this.calculateSpeedNoteCount();
|
|
120
|
+
}
|
|
119
121
|
if (!isRelax) {
|
|
120
122
|
this.postCalculateRhythm(rhythmSkill);
|
|
121
123
|
}
|
package/dist/OsuStarRating.js
CHANGED
|
@@ -35,15 +35,8 @@ class OsuStarRating extends StarRating_1.StarRating {
|
|
|
35
35
|
calculateAim() {
|
|
36
36
|
const aimSkill = new OsuAim_1.OsuAim(this.mods, true);
|
|
37
37
|
const aimSkillWithoutSliders = new OsuAim_1.OsuAim(this.mods, false);
|
|
38
|
-
this.calculateSkills(aimSkill);
|
|
39
|
-
this.
|
|
40
|
-
this.strainPeaks.aimWithoutSliders = aimSkillWithoutSliders.strainPeaks;
|
|
41
|
-
this.aim = this.starValue(aimSkill.difficultyValue());
|
|
42
|
-
if (this.aim) {
|
|
43
|
-
this.attributes.sliderFactor =
|
|
44
|
-
this.starValue(aimSkillWithoutSliders.difficultyValue()) /
|
|
45
|
-
this.aim;
|
|
46
|
-
}
|
|
38
|
+
this.calculateSkills(aimSkill, aimSkillWithoutSliders);
|
|
39
|
+
this.postCalculateAim(aimSkill, aimSkillWithoutSliders);
|
|
47
40
|
}
|
|
48
41
|
/**
|
|
49
42
|
* Calculates the speed star rating of the beatmap and stores it in this instance.
|
|
@@ -54,8 +47,7 @@ class OsuStarRating extends StarRating_1.StarRating {
|
|
|
54
47
|
}
|
|
55
48
|
const speedSkill = new OsuSpeed_1.OsuSpeed(this.mods, new osu_base_1.OsuHitWindow(this.stats.od).hitWindowFor300());
|
|
56
49
|
this.calculateSkills(speedSkill);
|
|
57
|
-
this.
|
|
58
|
-
this.speed = this.starValue(speedSkill.difficultyValue());
|
|
50
|
+
this.postCalculateSpeed(speedSkill);
|
|
59
51
|
}
|
|
60
52
|
/**
|
|
61
53
|
* Calculates the flashlight star rating of the beatmap and stores it in this instance.
|
|
@@ -63,8 +55,7 @@ class OsuStarRating extends StarRating_1.StarRating {
|
|
|
63
55
|
calculateFlashlight() {
|
|
64
56
|
const flashlightSkill = new OsuFlashlight_1.OsuFlashlight(this.mods);
|
|
65
57
|
this.calculateSkills(flashlightSkill);
|
|
66
|
-
this.
|
|
67
|
-
this.flashlight = this.starValue(flashlightSkill.difficultyValue());
|
|
58
|
+
this.postCalculateFlashlight(flashlightSkill);
|
|
68
59
|
}
|
|
69
60
|
calculateTotal() {
|
|
70
61
|
const aimPerformanceValue = this.basePerformanceValue(this.aim);
|
|
@@ -87,10 +78,6 @@ class OsuStarRating extends StarRating_1.StarRating {
|
|
|
87
78
|
calculateAll() {
|
|
88
79
|
const skills = this.createSkills();
|
|
89
80
|
const isRelax = this.mods.some((m) => m instanceof osu_base_1.ModRelax);
|
|
90
|
-
if (isRelax) {
|
|
91
|
-
// Remove speed skill to prevent overhead
|
|
92
|
-
skills.splice(2, 1);
|
|
93
|
-
}
|
|
94
81
|
this.calculateSkills(...skills);
|
|
95
82
|
const aimSkill = skills[0];
|
|
96
83
|
const aimSkillWithoutSliders = skills[1];
|
|
@@ -103,20 +90,11 @@ class OsuStarRating extends StarRating_1.StarRating {
|
|
|
103
90
|
speedSkill = skills[2];
|
|
104
91
|
flashlightSkill = skills[3];
|
|
105
92
|
}
|
|
106
|
-
this.
|
|
107
|
-
this.strainPeaks.aimWithoutSliders = aimSkillWithoutSliders.strainPeaks;
|
|
108
|
-
this.aim = this.starValue(aimSkill.difficultyValue());
|
|
109
|
-
if (this.aim) {
|
|
110
|
-
this.attributes.sliderFactor =
|
|
111
|
-
this.starValue(aimSkillWithoutSliders.difficultyValue()) /
|
|
112
|
-
this.aim;
|
|
113
|
-
}
|
|
93
|
+
this.postCalculateAim(aimSkill, aimSkillWithoutSliders);
|
|
114
94
|
if (speedSkill) {
|
|
115
|
-
this.
|
|
116
|
-
this.speed = this.starValue(speedSkill.difficultyValue());
|
|
95
|
+
this.postCalculateSpeed(speedSkill);
|
|
117
96
|
}
|
|
118
|
-
this.
|
|
119
|
-
this.flashlight = this.starValue(flashlightSkill.difficultyValue());
|
|
97
|
+
this.postCalculateFlashlight(flashlightSkill);
|
|
120
98
|
this.calculateTotal();
|
|
121
99
|
}
|
|
122
100
|
/**
|
|
@@ -143,5 +121,39 @@ class OsuStarRating extends StarRating_1.StarRating {
|
|
|
143
121
|
new OsuFlashlight_1.OsuFlashlight(this.mods),
|
|
144
122
|
];
|
|
145
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Called after aim skill calculation.
|
|
126
|
+
*
|
|
127
|
+
* @param aimSkill The aim skill that considers sliders.
|
|
128
|
+
* @param aimSkillWithoutSliders The aim skill that doesn't consider sliders.
|
|
129
|
+
*/
|
|
130
|
+
postCalculateAim(aimSkill, aimSkillWithoutSliders) {
|
|
131
|
+
this.strainPeaks.aimWithSliders = aimSkill.strainPeaks;
|
|
132
|
+
this.strainPeaks.aimWithoutSliders = aimSkillWithoutSliders.strainPeaks;
|
|
133
|
+
this.aim = this.starValue(aimSkill.difficultyValue());
|
|
134
|
+
if (this.aim) {
|
|
135
|
+
this.attributes.sliderFactor =
|
|
136
|
+
this.starValue(aimSkillWithoutSliders.difficultyValue()) /
|
|
137
|
+
this.aim;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Called after speed skill calculation.
|
|
142
|
+
*
|
|
143
|
+
* @param speedSkill The speed skill.
|
|
144
|
+
*/
|
|
145
|
+
postCalculateSpeed(speedSkill) {
|
|
146
|
+
this.strainPeaks.speed = speedSkill.strainPeaks;
|
|
147
|
+
this.speed = this.starValue(speedSkill.difficultyValue());
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Called after flashlight skill calculation.
|
|
151
|
+
*
|
|
152
|
+
* @param flashlightSkill The flashlight skill.
|
|
153
|
+
*/
|
|
154
|
+
postCalculateFlashlight(flashlightSkill) {
|
|
155
|
+
this.strainPeaks.flashlight = flashlightSkill.strainPeaks;
|
|
156
|
+
this.flashlight = this.starValue(flashlightSkill.difficultyValue());
|
|
157
|
+
}
|
|
146
158
|
}
|
|
147
159
|
exports.OsuStarRating = OsuStarRating;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rian8337/osu-difficulty-calculator",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
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",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"main": "dist/index.js",
|
|
13
13
|
"types": "typings/index.d.ts",
|
|
14
|
+
"typedocMain": "src/index.ts",
|
|
14
15
|
"files": [
|
|
15
16
|
"dist/**",
|
|
16
17
|
"typings/**"
|
|
@@ -21,7 +22,6 @@
|
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
24
|
"build": "tsc",
|
|
24
|
-
"generate-docs": "typedoc src/index.ts",
|
|
25
25
|
"lint": "eslint --ext ts",
|
|
26
26
|
"prepare": "npm run build",
|
|
27
27
|
"test": "jest -i"
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"url": "https://github.com/Rian8337/osu-droid-module/issues"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@rian8337/osu-base": "^1.2.
|
|
33
|
+
"@rian8337/osu-base": "^1.2.9"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "4bb4b0c00cf07d5624e1af644a01685697b2832c"
|
|
39
39
|
}
|
package/typings/index.d.ts
CHANGED
|
@@ -414,16 +414,6 @@ declare module "@rian8337/osu-difficulty-calculator" {
|
|
|
414
414
|
* @param flashlightSkill The flashlight skill.
|
|
415
415
|
*/
|
|
416
416
|
private postCalculateFlashlight(flashlightSkill: DroidFlashlight): void;
|
|
417
|
-
/**
|
|
418
|
-
* Calculates the base rating value of a difficulty.
|
|
419
|
-
*/
|
|
420
|
-
private baseRatingValue(difficulty: number): number;
|
|
421
|
-
/**
|
|
422
|
-
* Calculates the base performance value of a difficulty rating.
|
|
423
|
-
*
|
|
424
|
-
* @param rating The difficulty rating.
|
|
425
|
-
*/
|
|
426
|
-
private basePerformanceValue(rating: number): number;
|
|
427
417
|
}
|
|
428
418
|
|
|
429
419
|
/**
|
|
@@ -716,17 +706,27 @@ declare module "@rian8337/osu-difficulty-calculator" {
|
|
|
716
706
|
*/
|
|
717
707
|
protected override createSkills(): OsuSkill[];
|
|
718
708
|
/**
|
|
719
|
-
*
|
|
709
|
+
* Called after aim skill calculation.
|
|
720
710
|
*
|
|
721
|
-
* @param
|
|
711
|
+
* @param aimSkill The aim skill that considers sliders.
|
|
712
|
+
* @param aimSkillWithoutSliders The aim skill that doesn't consider sliders.
|
|
722
713
|
*/
|
|
723
|
-
private
|
|
714
|
+
private postCalculateAim(
|
|
715
|
+
aimSkill: OsuAim,
|
|
716
|
+
aimSkillWithoutSliders: OsuAim
|
|
717
|
+
): void;
|
|
724
718
|
/**
|
|
725
|
-
*
|
|
719
|
+
* Called after speed skill calculation.
|
|
726
720
|
*
|
|
727
|
-
* @param
|
|
721
|
+
* @param speedSkill The speed skill.
|
|
728
722
|
*/
|
|
729
|
-
private
|
|
723
|
+
private postCalculateSpeed(speedSkill: OsuSpeed): void;
|
|
724
|
+
/**
|
|
725
|
+
* Called after flashlight skill calculation.
|
|
726
|
+
*
|
|
727
|
+
* @param flashlightSkill The flashlight skill.
|
|
728
|
+
*/
|
|
729
|
+
private postCalculateFlashlight(flashlightSkill: OsuFlashlight): void;
|
|
730
730
|
}
|
|
731
731
|
|
|
732
732
|
//#endregion
|
|
@@ -872,9 +872,9 @@ declare module "@rian8337/osu-difficulty-calculator" {
|
|
|
872
872
|
*/
|
|
873
873
|
mode?: modes;
|
|
874
874
|
/**
|
|
875
|
-
* The
|
|
875
|
+
* The tap penalty to apply for penalized scores. Only applies to droid gamemode.
|
|
876
876
|
*/
|
|
877
|
-
|
|
877
|
+
tapPenalty?: number;
|
|
878
878
|
/**
|
|
879
879
|
* Custom map statistics to apply custom speed multiplier and force AR values as well as old statistics.
|
|
880
880
|
*/
|
|
@@ -914,9 +914,9 @@ declare module "@rian8337/osu-difficulty-calculator" {
|
|
|
914
914
|
*/
|
|
915
915
|
mode?: modes;
|
|
916
916
|
/**
|
|
917
|
-
* The
|
|
917
|
+
* The tap penalty to apply for penalized scores.
|
|
918
918
|
*/
|
|
919
|
-
|
|
919
|
+
tapPenalty?: number;
|
|
920
920
|
/**
|
|
921
921
|
* Custom map statistics to apply custom speed multiplier and force AR values as well as old statistics.
|
|
922
922
|
*/
|
|
@@ -1061,6 +1061,18 @@ declare module "@rian8337/osu-difficulty-calculator" {
|
|
|
1061
1061
|
* Creates skills to be calculated.
|
|
1062
1062
|
*/
|
|
1063
1063
|
protected abstract createSkills(): Skill[];
|
|
1064
|
+
/**
|
|
1065
|
+
* Calculates the star rating value of a difficulty.
|
|
1066
|
+
*
|
|
1067
|
+
* @param difficulty The difficulty to calculate.
|
|
1068
|
+
*/
|
|
1069
|
+
protected starValue(difficulty: number): number;
|
|
1070
|
+
/**
|
|
1071
|
+
* Calculates the base performance value of a difficulty rating.
|
|
1072
|
+
*
|
|
1073
|
+
* @param rating The difficulty rating.
|
|
1074
|
+
*/
|
|
1075
|
+
protected basePerformanceValue(rating: number): number;
|
|
1064
1076
|
}
|
|
1065
1077
|
|
|
1066
1078
|
/**
|