Merge pull request #6 from MaxOhn/osu-fix-no-objects

osu: handle maps without objects
This commit is contained in:
Max
2022-01-07 15:17:32 +01:00
committed by GitHub
3 changed files with 47 additions and 32 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
## Upcoming ## Upcoming
- Nothing as of now - osu: Fix panic on maps with 0 objects
# v0.4.0 # v0.4.0
+10 -2
View File
@@ -83,7 +83,11 @@ pub fn stars(
0.0 0.0
}; };
let star_rating = calculate_star_rating(aim_rating, speed_rating, flashlight_rating); let star_rating = if attributes.max_combo == 0 {
0.0
} else {
calculate_star_rating(aim_rating, speed_rating, flashlight_rating)
};
attributes.aim_strain = aim_rating; attributes.aim_strain = aim_rating;
attributes.speed_strain = speed_rating; attributes.speed_strain = speed_rating;
@@ -284,7 +288,11 @@ fn calculate_skills(
fn stacking(hit_objects: &mut [OsuObject], stack_threshold: f64) { fn stacking(hit_objects: &mut [OsuObject], stack_threshold: f64) {
let mut extended_start_idx = 0; let mut extended_start_idx = 0;
let extended_end_idx = hit_objects.len() - 1;
let extended_end_idx = match hit_objects.len().checked_sub(1) {
Some(idx) => idx,
None => return,
};
// First big `if` in osu!lazer's function can be skipped // First big `if` in osu!lazer's function can be skipped
+36 -29
View File
@@ -337,41 +337,48 @@ struct OsuPPInner {
impl OsuPPInner { impl OsuPPInner {
fn calculate(mut self) -> OsuPerformanceAttributes { fn calculate(mut self) -> OsuPerformanceAttributes {
let mut multiplier = 1.12; let (aim_value, speed_value, acc_value, flashlight_value, pp) =
if self.total_hits.abs() <= f64::EPSILON {
(0.0, 0.0, 0.0, 0.0, 0.0)
} else {
let mut multiplier = 1.12;
// NF penalty // NF penalty
if self.mods.nf() { if self.mods.nf() {
multiplier *= (1.0 - 0.02 * (self.effective_misses as f64)).max(0.9); multiplier *= (1.0 - 0.02 * (self.effective_misses as f64)).max(0.9);
} }
// SO penalty // SO penalty
if self.mods.so() { if self.mods.so() {
let n_spinners = self.attributes.n_spinners; let n_spinners = self.attributes.n_spinners;
multiplier *= 1.0 - (n_spinners as f64 / self.total_hits).powf(0.85); multiplier *= 1.0 - (n_spinners as f64 / self.total_hits).powf(0.85);
} }
// Relax penalty // Relax penalty
if self.mods.rx() { if self.mods.rx() {
// * As we're adding 100s and 50s to an approximated number of combo breaks\ // * As we're adding 100s and 50s to an approximated number of combo breaks\
// * the result can be higher than total hits in specific scenarios // * the result can be higher than total hits in specific scenarios
// * (which breaks some calculations) so we need to clamp it. // * (which breaks some calculations) so we need to clamp it.
self.effective_misses = self.effective_misses = (self.effective_misses + self.n100 + self.n50)
(self.effective_misses + self.n100 + self.n50).min(self.total_hits as usize); .min(self.total_hits as usize);
multiplier *= 0.6; multiplier *= 0.6;
} }
let aim_value = self.compute_aim_value(); let aim_value = self.compute_aim_value();
let speed_value = self.compute_speed_value(); let speed_value = self.compute_speed_value();
let acc_value = self.compute_accuracy_value(); let acc_value = self.compute_accuracy_value();
let flashlight_value = self.compute_flashlight_value(); let flashlight_value = self.compute_flashlight_value();
let pp = (aim_value.powf(1.1) let pp = (aim_value.powf(1.1)
+ speed_value.powf(1.1) + speed_value.powf(1.1)
+ acc_value.powf(1.1) + acc_value.powf(1.1)
+ flashlight_value.powf(1.1)) + flashlight_value.powf(1.1))
.powf(1.0 / 1.1) .powf(1.0 / 1.1)
* multiplier; * multiplier;
(aim_value, speed_value, acc_value, flashlight_value, pp)
};
OsuPerformanceAttributes { OsuPerformanceAttributes {
difficulty: self.attributes, difficulty: self.attributes,