remove combo scaling for vn/ap
This commit is contained in:
+9
-1
@@ -6,13 +6,15 @@ mod pp;
|
||||
mod scaling_factor;
|
||||
mod skills;
|
||||
|
||||
use skills::OsuStrainSkill;
|
||||
|
||||
use crate::{curve::CurveBuffers, parse::Pos2, AnyStars, Beatmap, GameMode, Mods};
|
||||
|
||||
use self::{
|
||||
difficulty_object::{Distances, OsuDifficultyObject},
|
||||
osu_object::{ObjectParameters, OsuObject},
|
||||
scaling_factor::ScalingFactor,
|
||||
skills::{Skill, Skills},
|
||||
skills::Skills,
|
||||
};
|
||||
|
||||
pub use self::{gradual_difficulty::*, gradual_performance::*, pp::*};
|
||||
@@ -183,6 +185,8 @@ impl<'map> OsuStars<'map> {
|
||||
attrs.slider_factor = slider_factor;
|
||||
attrs.stars = star_rating;
|
||||
attrs.speed_note_count = speed_notes;
|
||||
attrs.aim_difficult_strain_count = aim.count_difficult_strains();
|
||||
attrs.speed = speed.count_difficult_strains();
|
||||
|
||||
attrs
|
||||
}
|
||||
@@ -513,6 +517,10 @@ pub struct OsuDifficultyAttributes {
|
||||
pub flashlight: f64,
|
||||
/// The ratio of the aim strain with and without considering sliders
|
||||
pub slider_factor: f64,
|
||||
/// The number of difficult aim strains.
|
||||
pub aim_difficult_strain_count: f64,
|
||||
/// The number of difficult speed strains.
|
||||
pub speed_difficult_strain_count: f64,
|
||||
/// The number of clickable objects weighted by difficulty.
|
||||
pub speed_note_count: f64,
|
||||
/// The approach rate.
|
||||
|
||||
+12
-14
@@ -470,16 +470,13 @@ impl OsuPpInner {
|
||||
|
||||
aim_value *= len_bonus;
|
||||
|
||||
// * Penalize misses by assessing # of misses relative to the total # of objects.
|
||||
// * Default a 3% reduction for any # of misses.
|
||||
if self.effective_miss_count > 0.0 {
|
||||
aim_value *= 0.97
|
||||
* (1.0 - (self.effective_miss_count / total_hits).powf(0.775))
|
||||
.powf(self.effective_miss_count);
|
||||
aim_value *= calculate_miss_penalty(
|
||||
self.effective_miss_count,
|
||||
self.attrs.aim_difficult_strain_count,
|
||||
);
|
||||
}
|
||||
|
||||
aim_value *= self.get_combo_scaling_factor();
|
||||
|
||||
let ar_factor = if self.mods.rx() {
|
||||
0.0
|
||||
} else if self.attrs.ar > 10.33 {
|
||||
@@ -536,16 +533,13 @@ impl OsuPpInner {
|
||||
|
||||
speed_value *= len_bonus;
|
||||
|
||||
// * Penalize misses by assessing # of misses relative to the total # of objects.
|
||||
// * Default a 3% reduction for any # of misses.
|
||||
if self.effective_miss_count > 0.0 {
|
||||
speed_value *= 0.97
|
||||
* (1.0 - (self.effective_miss_count / total_hits).powf(0.775))
|
||||
.powf(self.effective_miss_count.powf(0.875));
|
||||
speed_value *= calculate_miss_penalty(
|
||||
self.effective_miss_count,
|
||||
self.attrs.speed_difficult_strain_count,
|
||||
);
|
||||
}
|
||||
|
||||
speed_value *= self.get_combo_scaling_factor();
|
||||
|
||||
let ar_factor = if self.mods.ap() {
|
||||
0.0
|
||||
} else if self.attrs.ar > 10.33 {
|
||||
@@ -701,6 +695,10 @@ fn calculate_effective_misses(attrs: &OsuDifficultyAttributes, state: &OsuScoreS
|
||||
combo_based_miss_count.max(state.n_misses as f64)
|
||||
}
|
||||
|
||||
fn calculate_miss_penalty(miss_count: f64, difficult_strain_count: f64) -> f64 {
|
||||
0.96 / ((miss_count / (4.0 * difficult_strain_count.ln().powf(0.94))) + 1.0)
|
||||
}
|
||||
|
||||
/// Abstract type to provide flexibility when passing difficulty attributes to a performance calculation.
|
||||
pub trait OsuAttributeProvider {
|
||||
/// Provide the actual difficulty attributes.
|
||||
|
||||
@@ -11,6 +11,7 @@ pub(crate) struct Aim {
|
||||
curr_section_end: f64,
|
||||
pub(crate) strain_peaks: Vec<f64>,
|
||||
with_sliders: bool,
|
||||
object_strains: Vec<f64>,
|
||||
}
|
||||
|
||||
impl Aim {
|
||||
@@ -24,6 +25,7 @@ impl Aim {
|
||||
curr_section_end: 0.0,
|
||||
strain_peaks: Vec::new(),
|
||||
with_sliders,
|
||||
object_strains: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +76,8 @@ impl StrainSkill for Aim {
|
||||
self.curr_strain += AimEvaluator::evaluate_diff_of(curr, diff_objects, self.with_sliders)
|
||||
* Self::SKILL_MULTIPLIER;
|
||||
|
||||
self.object_strains.push(self.curr_strain);
|
||||
|
||||
self.curr_strain
|
||||
}
|
||||
|
||||
@@ -93,7 +97,11 @@ impl StrainSkill for Aim {
|
||||
}
|
||||
}
|
||||
|
||||
impl OsuStrainSkill for Aim {}
|
||||
impl OsuStrainSkill for Aim {
|
||||
fn strains(&self) -> &Vec<f64> {
|
||||
&self.object_strains
|
||||
}
|
||||
}
|
||||
|
||||
struct AimEvaluator;
|
||||
|
||||
|
||||
@@ -108,7 +108,13 @@ impl StrainSkill for Flashlight {
|
||||
}
|
||||
}
|
||||
|
||||
impl OsuStrainSkill for Flashlight {}
|
||||
const HOLDING_VEC: &Vec<f64> = &vec![];
|
||||
|
||||
impl OsuStrainSkill for Flashlight {
|
||||
fn strains(&self) -> &Vec<f64> {
|
||||
HOLDING_VEC
|
||||
}
|
||||
}
|
||||
|
||||
struct FlashlightEvaluator;
|
||||
|
||||
|
||||
@@ -121,6 +121,10 @@ impl StrainSkill for Speed {
|
||||
impl OsuStrainSkill for Speed {
|
||||
const REDUCED_SECTION_COUNT: usize = 5;
|
||||
const DIFFICULTY_MULTIPLER: f64 = 1.04;
|
||||
|
||||
fn strains(&self) -> &Vec<f64> {
|
||||
&self.object_strains
|
||||
}
|
||||
}
|
||||
|
||||
struct SpeedEvaluator;
|
||||
|
||||
@@ -125,4 +125,24 @@ pub(crate) trait OsuStrainSkill: StrainSkill + Sized {
|
||||
|
||||
difficulty * Self::DIFFICULTY_MULTIPLER
|
||||
}
|
||||
|
||||
fn strains(&self) -> &Vec<f64>;
|
||||
|
||||
fn count_difficult_strains(&mut self) -> f64 {
|
||||
let difficulty_value = OsuStrainSkill::difficulty_value(self);
|
||||
if difficulty_value == 0.0 {
|
||||
0.0
|
||||
} else {
|
||||
// * What would the top strain be if all strain values were identical
|
||||
let consistent_top_strain = difficulty_value / 10.0;
|
||||
|
||||
let strains = self.strains();
|
||||
|
||||
// Use a weighted sum of all strains. Constants are arbitrary and give nice values
|
||||
strains
|
||||
.iter()
|
||||
.map(|&s| 1.1 / (1.0 + (-10.0 * (s / consistent_top_strain - 0.88)).exp()))
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user