chore: add patches from https://github.com/osuAkatsuki/akatsuki-pp-rs/pull/29
This commit is contained in:
+25
-16
@@ -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
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user