chore: add patches from https://github.com/osuAkatsuki/akatsuki-pp-rs/pull/29
Clippy checks / Clippy (push) Has been cancelled
Tests / Doc tests (push) Has been cancelled
Tests / Default tests (push) Has been cancelled
Tests / Test sync feature (push) Has been cancelled
Tests / Test with raw_strains feature (push) Has been cancelled

This commit is contained in:
2026-06-26 13:20:06 +02:00
parent 591de0db49
commit f30a6df096
2 changed files with 48 additions and 25 deletions
+25 -16
View File
@@ -302,13 +302,16 @@ impl<'m> OsuPP<'m> {
// Longer maps are worth more
let len_bonus = 0.88
+ 0.4 * (total_hits / 2000.0).min(1.0)
+ (total_hits > 2000.0) as u8 as f32 * 0.5 * (total_hits / 2000.0).log10();
+ 0.4 * (total_hits / 1400.0).min(1.0)
+ (total_hits > 1400.0) as u8 as f32 * 0.2 * (total_hits / 1400.0).log10();
aim_value *= len_bonus;
// Penalize misses
if effective_miss_count > 0.0 {
let miss_penalty = self.calculate_miss_penalty(effective_miss_count);
let miss_penalty = self.calculate_miss_penalty(
effective_miss_count,
attributes.aim_difficult_strain_count as f32
);
aim_value *= miss_penalty;
}
@@ -327,17 +330,19 @@ impl<'m> OsuPP<'m> {
// HD bonus
if self.mods.hd() {
aim_value *= 1.0 + 0.05 * (11.0 - attributes.ar) as f32;
let ar_capped = attributes.ar.min(10.67).max(0.0);
let hd_bonus_factor = (10.67 - ar_capped) as f32;
aim_value *= 1.0 + 0.075 * hd_bonus_factor;
}
// FL bonus
if self.mods.fl() {
aim_value *= 1.0
+ 0.3 * (total_hits / 200.0).min(1.0)
+ 0.2 * (total_hits / 200.0).min(1.0)
+ (total_hits > 200.0) as u8 as f32
* 0.25
* 0.15
* ((total_hits - 200.0) / 300.0).min(1.0)
+ (total_hits > 500.0) as u8 as f32 * (total_hits - 500.0) / 1600.0;
+ (total_hits > 500.0) as u8 as f32 * (total_hits - 500.0) / 2500.0;
}
// Scale with accuracy
@@ -355,13 +360,16 @@ impl<'m> OsuPP<'m> {
// Longer maps are worth more
let len_bonus = 0.88
+ 0.4 * (total_hits / 2000.0).min(1.0)
+ (total_hits > 2000.0) as u8 as f32 * 0.5 * (total_hits / 2000.0).log10();
+ 0.4 * (total_hits / 1600.0).min(1.0)
+ (total_hits > 1600.0) as u8 as f32 * 0.5 * (total_hits / 1600.0).log10();
speed_value *= len_bonus;
// Penalize misses
if effective_miss_count > 0.0 {
let miss_penalty = self.calculate_miss_penalty(effective_miss_count);
let miss_penalty = self.calculate_miss_penalty(
effective_miss_count,
attributes.speed_difficult_strain_count as f32
);
speed_value *= miss_penalty;
}
@@ -439,11 +447,12 @@ impl<'m> OsuPP<'m> {
}
#[inline]
fn calculate_miss_penalty(&self, effective_miss_count: f32) -> f32 {
let total_hits = self.total_hits() as f32;
0.97 * (1.0 - (effective_miss_count / total_hits).powf(0.5))
.powf(1.0 + (effective_miss_count / 1.5))
fn calculate_miss_penalty(
&self,
effective_miss_count: f32,
difficult_strain_count: f32
) -> f32 {
0.96 / ((effective_miss_count / (4.0 * difficult_strain_count.ln().powf(0.94))) + 1.0)
}
#[inline]
@@ -456,7 +465,7 @@ impl<'m> OsuPP<'m> {
let n50 = self.n50.unwrap_or(0) as f32;
if attributes.n_sliders > 0 {
let fc_threshold = attributes.max_combo as f32 - (0.1 * attributes.n_sliders as f32);
let fc_threshold = attributes.max_combo as f32 - (0.2 * attributes.n_sliders as f32);
if combo < fc_threshold {
combo_based_miss_count = fc_threshold / combo.max(1.0);
}
+23 -9
View File
@@ -48,8 +48,8 @@ pub fn stars(
let radius = OBJECT_RADIUS * (1.0 - 0.7 * (map_attributes.cs as f32 - 5.0) / 5.0) / 2.0;
let mut scaling_factor = NORMALIZED_RADIUS / radius;
if radius < 30.0 {
let small_circle_bonus = (30.0 - radius).min(5.0) / 50.0;
if radius < 30.05 {
let small_circle_bonus = ((30.05 - radius) / 50.0).powf(1.01) * 1.45;
scaling_factor *= 1.0 + small_circle_bonus;
}
@@ -132,17 +132,31 @@ pub fn stars(
aim.save_current_peak();
speed.save_current_peak();
let aim_strain = aim.difficulty_value().sqrt() * DIFFICULTY_MULTIPLIER;
let speed_strain = speed.difficulty_value().sqrt() * DIFFICULTY_MULTIPLIER;
let aim_strain_raw = (aim.difficulty_value().sqrt() as f64) * (DIFFICULTY_MULTIPLIER as f64);
let speed_strain = (speed.difficulty_value().sqrt() as f64) * (DIFFICULTY_MULTIPLIER as f64);
let aim_difficult_strain_count = aim.count_difficult_strains();
let speed_difficult_strain_count = speed.count_difficult_strains();
let aim_difficult_strain_count = aim.count_difficult_strains() as f64;
let speed_difficult_strain_count = speed.count_difficult_strains() as f64;
let ar = diff_attributes.ar;
let ar_multiplier: f64 = if ar <= 9.0 {
1.25
} else if ar <= 10.67 {
1.25 - (ar - 9.0) * (0.25 / 1.67)
} else {
1.0 - (ar - 10.67) * (0.05 / 0.33)
};
let intensity_gate = ((aim_difficult_strain_count - 2.0) / 5.0).clamp(0.0, 1.0);
let final_ar_bonus = 1.0 + (ar_multiplier - 1.0) * intensity_gate;
let aim_strain = aim_strain_raw * final_ar_bonus;
let stars = aim_strain + speed_strain + (aim_strain - speed_strain).abs() / 2.0;
diff_attributes.stars = stars as f64;
diff_attributes.speed_strain = speed_strain as f64;
diff_attributes.aim_strain = aim_strain as f64;
diff_attributes.stars = stars;
diff_attributes.speed_strain = speed_strain;
diff_attributes.aim_strain = aim_strain;
diff_attributes.aim_difficult_strain_count = aim_difficult_strain_count;
diff_attributes.speed_difficult_strain_count = speed_difficult_strain_count;