@rian8337/osu-droid-replay-analyzer 4.0.0-beta.74 → 4.0.0-beta.76

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
@@ -963,7 +963,7 @@ class SliderCheeseChecker {
963
963
  }
964
964
 
965
965
  /**
966
- * Utility to check whether or not a beatmap is three-fingered for rebalance scores.
966
+ * Utility to check whether or not a beatmap is three-fingered for live scores.
967
967
  */
968
968
  class ThreeFingerChecker {
969
969
  /**
@@ -1026,9 +1026,6 @@ class ThreeFingerChecker {
1026
1026
  }
1027
1027
  this.getAccurateBreakPoints();
1028
1028
  this.filterCursorInstances();
1029
- if (this.downCursorInstances.filter((v) => v.length > 0).length <= 3) {
1030
- return { is3Finger: false, penalty: 1 };
1031
- }
1032
1029
  this.getBeatmapSections();
1033
1030
  this.calculateNerfFactors();
1034
1031
  const finalPenalty = this.calculateFinalPenalty();
@@ -2129,7 +2126,7 @@ class ReplayAnalyzer {
2129
2126
  /**
2130
2127
  * Gets hit error information of the replay.
2131
2128
  *
2132
- * `analyze()` must be called before calling this.
2129
+ * `analyze()` must be called before calling this, and `beatmap` must be defined.
2133
2130
  */
2134
2131
  calculateHitError() {
2135
2132
  var _a, _b;
@@ -2180,6 +2177,124 @@ class ReplayAnalyzer {
2180
2177
  unstableRate: osuBase.MathUtils.calculateStandardDeviation(accuracies) * 10,
2181
2178
  };
2182
2179
  }
2180
+ /**
2181
+ * Obtains the amount of slider ticks and ends hit in the replay.
2182
+ *
2183
+ * This requires `analyze()` to be called first and `beatmap` to be defined.
2184
+ *
2185
+ * @returns Slider hit information or `null` if the replay has not been analyzed or the beatmap is not defined.
2186
+ */
2187
+ obtainSliderHitInformation() {
2188
+ const { data, beatmap } = this;
2189
+ if (!data || !beatmap) {
2190
+ return null;
2191
+ }
2192
+ const sliderInformation = {
2193
+ tick: { obtained: 0, total: beatmap.hitObjects.sliderTicks },
2194
+ end: { obtained: 0, total: beatmap.hitObjects.sliders },
2195
+ };
2196
+ for (let i = 0; i < data.hitObjectData.length; ++i) {
2197
+ const object = beatmap.hitObjects.objects[i];
2198
+ const objectData = data.hitObjectData[i];
2199
+ if (objectData.result === exports.HitResult.miss ||
2200
+ !(object instanceof osuBase.Slider)) {
2201
+ continue;
2202
+ }
2203
+ // Exclude the head circle.
2204
+ for (let j = 1; j < object.nestedHitObjects.length; ++j) {
2205
+ const nested = object.nestedHitObjects[j];
2206
+ if (!objectData.tickset[j - 1]) {
2207
+ continue;
2208
+ }
2209
+ if (nested instanceof osuBase.SliderTick) {
2210
+ ++sliderInformation.tick.obtained;
2211
+ }
2212
+ else if (nested instanceof osuBase.SliderTail) {
2213
+ ++sliderInformation.end.obtained;
2214
+ }
2215
+ }
2216
+ }
2217
+ return sliderInformation;
2218
+ }
2219
+ /**
2220
+ * Simulates a hit window for the replay.
2221
+ *
2222
+ * This does not account for required spins in a spinner.
2223
+ *
2224
+ * Requires `analyze()` to be called first and `beatmap` to be defined.
2225
+ *
2226
+ * @param hitWindow The hit window to simulate.
2227
+ * @returns The accuracy of the replay based on the hit window, or `null` if the replay has not been analyzed or the beatmap is not defined.
2228
+ */
2229
+ simulateHitWindow(hitWindow) {
2230
+ const { data, beatmap } = this;
2231
+ if (!data || !beatmap) {
2232
+ return null;
2233
+ }
2234
+ const accuracy = new osuBase.Accuracy({ n300: 0, n100: 0, n50: 0, nmiss: 0 });
2235
+ for (let i = 0; i < data.hitObjectData.length; ++i) {
2236
+ const object = beatmap.hitObjects.objects[i];
2237
+ const objectData = data.hitObjectData[i];
2238
+ const hitAccuracy = Math.abs(objectData.accuracy);
2239
+ let { result } = objectData;
2240
+ if (object instanceof osuBase.Circle) {
2241
+ if (hitAccuracy <= hitWindow.greatWindow) {
2242
+ result = exports.HitResult.great;
2243
+ }
2244
+ else if (hitAccuracy <= hitWindow.okWindow) {
2245
+ result = exports.HitResult.good;
2246
+ }
2247
+ else if (hitAccuracy <= hitWindow.mehWindow) {
2248
+ result = exports.HitResult.meh;
2249
+ }
2250
+ else {
2251
+ result = exports.HitResult.miss;
2252
+ }
2253
+ }
2254
+ else if (object instanceof osuBase.Slider) {
2255
+ if (hitAccuracy <=
2256
+ Math.min(hitWindow.mehWindow, object.duration)) {
2257
+ let ticksObtained = 1;
2258
+ for (let j = 1; j < object.nestedHitObjects.length; ++j) {
2259
+ if (objectData.tickset[j - 1]) {
2260
+ ++ticksObtained;
2261
+ }
2262
+ }
2263
+ if (ticksObtained === object.nestedHitObjects.length) {
2264
+ result = exports.HitResult.great;
2265
+ }
2266
+ else if (ticksObtained >=
2267
+ Math.trunc(object.nestedHitObjects.length / 2)) {
2268
+ result = exports.HitResult.good;
2269
+ }
2270
+ else if (ticksObtained > 0) {
2271
+ result = exports.HitResult.meh;
2272
+ }
2273
+ else {
2274
+ result = exports.HitResult.miss;
2275
+ }
2276
+ }
2277
+ else {
2278
+ result = exports.HitResult.miss;
2279
+ }
2280
+ }
2281
+ switch (result) {
2282
+ case exports.HitResult.miss:
2283
+ ++accuracy.nmiss;
2284
+ break;
2285
+ case exports.HitResult.meh:
2286
+ ++accuracy.n50;
2287
+ break;
2288
+ case exports.HitResult.good:
2289
+ ++accuracy.n100;
2290
+ break;
2291
+ case exports.HitResult.great:
2292
+ ++accuracy.n300;
2293
+ break;
2294
+ }
2295
+ }
2296
+ return accuracy;
2297
+ }
2183
2298
  /**
2184
2299
  * Checks if a play is using 3 fingers.
2185
2300
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rian8337/osu-droid-replay-analyzer",
3
- "version": "4.0.0-beta.74",
3
+ "version": "4.0.0-beta.76",
4
4
  "description": "A replay analyzer for analyzing osu!droid replay files.",
5
5
  "keywords": [
6
6
  "osu",
@@ -35,8 +35,8 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@rian8337/osu-base": "^4.0.0-beta.74",
38
- "@rian8337/osu-difficulty-calculator": "^4.0.0-beta.74",
39
- "@rian8337/osu-rebalance-difficulty-calculator": "^4.0.0-beta.74",
38
+ "@rian8337/osu-difficulty-calculator": "^4.0.0-beta.76",
39
+ "@rian8337/osu-rebalance-difficulty-calculator": "^4.0.0-beta.76",
40
40
  "java-deserialization": "^0.1.0",
41
41
  "unzipper": "^0.10.11"
42
42
  },
@@ -46,5 +46,5 @@
46
46
  "publishConfig": {
47
47
  "access": "public"
48
48
  },
49
- "gitHead": "00abc82040e820ccff8fcad7ee77d7e7d8031717"
49
+ "gitHead": "d843f2cf65e2e44c87654a2be675d6ed925193ea"
50
50
  }
@@ -1,4 +1,4 @@
1
- import { Vector2, Accuracy, ScoreRank, ModMap, DroidPlayableBeatmap, Beatmap } from '@rian8337/osu-base';
1
+ import { Vector2, Accuracy, ScoreRank, ModMap, DroidPlayableBeatmap, Beatmap, HitWindow } from '@rian8337/osu-base';
2
2
  import { IExtendedDroidDifficultyAttributes as IExtendedDroidDifficultyAttributes$1 } from '@rian8337/osu-difficulty-calculator';
3
3
  import { IExtendedDroidDifficultyAttributes } from '@rian8337/osu-rebalance-difficulty-calculator';
4
4
 
@@ -726,6 +726,33 @@ interface SliderCheeseInformation {
726
726
  visualPenalty: number;
727
727
  }
728
728
 
729
+ /**
730
+ * Represents hit information about sliders in a beatmap.
731
+ */
732
+ interface SliderHitInformation {
733
+ /**
734
+ * Hit information of slider ticks.
735
+ */
736
+ readonly tick: SliderNestedHitObjectInformation;
737
+ /**
738
+ * hit information of slider ends.
739
+ */
740
+ readonly end: SliderNestedHitObjectInformation;
741
+ }
742
+ /**
743
+ * Hit information of a specific nested hit object.
744
+ */
745
+ interface SliderNestedHitObjectInformation {
746
+ /**
747
+ * The amount of the nested hit objects that were obtained.
748
+ */
749
+ obtained: number;
750
+ /**
751
+ * The amount of the nested hit objects in the beatmap.
752
+ */
753
+ readonly total: number;
754
+ }
755
+
729
756
  interface HitErrorInformation {
730
757
  negativeAvg: number;
731
758
  positiveAvg: number;
@@ -822,9 +849,28 @@ declare class ReplayAnalyzer {
822
849
  /**
823
850
  * Gets hit error information of the replay.
824
851
  *
825
- * `analyze()` must be called before calling this.
852
+ * `analyze()` must be called before calling this, and `beatmap` must be defined.
826
853
  */
827
854
  calculateHitError(): HitErrorInformation | null;
855
+ /**
856
+ * Obtains the amount of slider ticks and ends hit in the replay.
857
+ *
858
+ * This requires `analyze()` to be called first and `beatmap` to be defined.
859
+ *
860
+ * @returns Slider hit information or `null` if the replay has not been analyzed or the beatmap is not defined.
861
+ */
862
+ obtainSliderHitInformation(): SliderHitInformation | null;
863
+ /**
864
+ * Simulates a hit window for the replay.
865
+ *
866
+ * This does not account for required spins in a spinner.
867
+ *
868
+ * Requires `analyze()` to be called first and `beatmap` to be defined.
869
+ *
870
+ * @param hitWindow The hit window to simulate.
871
+ * @returns The accuracy of the replay based on the hit window, or `null` if the replay has not been analyzed or the beatmap is not defined.
872
+ */
873
+ simulateHitWindow(hitWindow: HitWindow): Accuracy | null;
828
874
  /**
829
875
  * Checks if a play is using 3 fingers.
830
876
  *
@@ -915,7 +961,7 @@ declare class SliderCheeseChecker {
915
961
  }
916
962
 
917
963
  /**
918
- * Utility to check whether or not a beatmap is three-fingered for rebalance scores.
964
+ * Utility to check whether or not a beatmap is three-fingered for live scores.
919
965
  */
920
966
  declare class ThreeFingerChecker {
921
967
  /**
@@ -1115,4 +1161,4 @@ declare class TwoHandChecker {
1115
1161
  private getCursorPosition;
1116
1162
  }
1117
1163
 
1118
- export { CursorData, type CursorInformation, CursorOccurrence, CursorOccurrenceGroup, type ExportedReplayJSON, type ExportedReplayJSONDataV1, type ExportedReplayJSONDataV2, type ExportedReplayJSONDataV3, type ExportedReplayJSONV1, type ExportedReplayJSONV2, type ExportedReplayJSONV3, type HitErrorInformation, HitResult, MovementType, RebalanceThreeFingerChecker, ReplayAnalyzer, ReplayData, ReplayObjectData, ReplayV3Data, SliderCheeseChecker, type SliderCheeseInformation, ThreeFingerChecker, type ThreeFingerInformation, TwoHandChecker, type TwoHandInformation };
1164
+ export { CursorData, type CursorInformation, CursorOccurrence, CursorOccurrenceGroup, type ExportedReplayJSON, type ExportedReplayJSONDataV1, type ExportedReplayJSONDataV2, type ExportedReplayJSONDataV3, type ExportedReplayJSONV1, type ExportedReplayJSONV2, type ExportedReplayJSONV3, type HitErrorInformation, HitResult, MovementType, RebalanceThreeFingerChecker, ReplayAnalyzer, ReplayData, ReplayObjectData, ReplayV3Data, SliderCheeseChecker, type SliderCheeseInformation, type SliderHitInformation, type SliderNestedHitObjectInformation, ThreeFingerChecker, type ThreeFingerInformation, TwoHandChecker, type TwoHandInformation };