store ModeDifficulty in perf calcs
This commit is contained in:
@@ -21,17 +21,14 @@ pub mod gradual;
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct CatchPerformance<'map> {
|
pub struct CatchPerformance<'map> {
|
||||||
pub(crate) map_or_attrs: MapOrAttrs<'map, Catch>,
|
pub(crate) map_or_attrs: MapOrAttrs<'map, Catch>,
|
||||||
pub(crate) mods: u32,
|
pub(crate) difficulty: ModeDifficulty,
|
||||||
pub(crate) acc: Option<f64>,
|
pub(crate) acc: Option<f64>,
|
||||||
pub(crate) combo: Option<u32>,
|
pub(crate) combo: Option<u32>,
|
||||||
|
|
||||||
pub(crate) fruits: Option<u32>,
|
pub(crate) fruits: Option<u32>,
|
||||||
pub(crate) droplets: Option<u32>,
|
pub(crate) droplets: Option<u32>,
|
||||||
pub(crate) tiny_droplets: Option<u32>,
|
pub(crate) tiny_droplets: Option<u32>,
|
||||||
pub(crate) tiny_droplet_misses: Option<u32>,
|
pub(crate) tiny_droplet_misses: Option<u32>,
|
||||||
pub(crate) misses: Option<u32>,
|
pub(crate) misses: Option<u32>,
|
||||||
pub(crate) passed_objects: Option<u32>,
|
|
||||||
pub(crate) clock_rate: Option<f64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'map> CatchPerformance<'map> {
|
impl<'map> CatchPerformance<'map> {
|
||||||
@@ -55,7 +52,7 @@ impl<'map> CatchPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
||||||
pub const fn mods(mut self, mods: u32) -> Self {
|
pub const fn mods(mut self, mods: u32) -> Self {
|
||||||
self.mods = mods;
|
self.difficulty = self.difficulty.mods(mods);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -110,7 +107,7 @@ impl<'map> CatchPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// [`CatchGradualPerformance`]: crate::catch::CatchGradualPerformance
|
/// [`CatchGradualPerformance`]: crate::catch::CatchGradualPerformance
|
||||||
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
||||||
self.passed_objects = Some(passed_objects);
|
self.difficulty = self.difficulty.passed_objects(passed_objects);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -119,7 +116,7 @@ impl<'map> CatchPerformance<'map> {
|
|||||||
/// If none is specified, it will take the clock rate based on the mods
|
/// If none is specified, it will take the clock rate based on the mods
|
||||||
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
||||||
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
||||||
self.clock_rate = Some(clock_rate);
|
self.difficulty = self.difficulty.clock_rate(clock_rate);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -312,7 +309,7 @@ impl<'map> CatchPerformance<'map> {
|
|||||||
|
|
||||||
let inner = CatchPerformanceInner {
|
let inner = CatchPerformanceInner {
|
||||||
attrs,
|
attrs,
|
||||||
mods: self.mods,
|
mods: self.difficulty.get_mods(),
|
||||||
state,
|
state,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -320,17 +317,7 @@ impl<'map> CatchPerformance<'map> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_attributes(&self, map: &CatchBeatmap<'_>) -> CatchDifficultyAttributes {
|
fn generate_attributes(&self, map: &CatchBeatmap<'_>) -> CatchDifficultyAttributes {
|
||||||
let mut calculator = ModeDifficulty::new();
|
self.difficulty.calculate(map)
|
||||||
|
|
||||||
if let Some(passed_objects) = self.passed_objects {
|
|
||||||
calculator = calculator.passed_objects(passed_objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(clock_rate) = self.clock_rate {
|
|
||||||
calculator = calculator.clock_rate(clock_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
calculator.mods(self.mods).calculate(map)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to create [`CatchPerformance`] through a [`ModeAttributeProvider`].
|
/// Try to create [`CatchPerformance`] through a [`ModeAttributeProvider`].
|
||||||
@@ -393,21 +380,19 @@ impl<'map> TryFrom<OsuPerformance<'map>> for CatchPerformance<'map> {
|
|||||||
|
|
||||||
let OsuPerformance {
|
let OsuPerformance {
|
||||||
map_or_attrs: _,
|
map_or_attrs: _,
|
||||||
mods,
|
difficulty,
|
||||||
acc,
|
acc,
|
||||||
combo,
|
combo,
|
||||||
n300,
|
n300,
|
||||||
n100,
|
n100,
|
||||||
n50,
|
n50,
|
||||||
misses,
|
misses,
|
||||||
passed_objects,
|
|
||||||
clock_rate,
|
|
||||||
hitresult_priority: _,
|
hitresult_priority: _,
|
||||||
} = osu;
|
} = osu;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
map_or_attrs: MapOrAttrs::Map(map),
|
map_or_attrs: MapOrAttrs::Map(map),
|
||||||
mods,
|
difficulty,
|
||||||
acc,
|
acc,
|
||||||
combo,
|
combo,
|
||||||
fruits: n300,
|
fruits: n300,
|
||||||
@@ -415,8 +400,6 @@ impl<'map> TryFrom<OsuPerformance<'map>> for CatchPerformance<'map> {
|
|||||||
tiny_droplets: n50,
|
tiny_droplets: n50,
|
||||||
tiny_droplet_misses: None,
|
tiny_droplet_misses: None,
|
||||||
misses,
|
misses,
|
||||||
passed_objects,
|
|
||||||
clock_rate,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,17 +408,14 @@ impl<'map> From<CatchBeatmap<'map>> for CatchPerformance<'map> {
|
|||||||
fn from(map: CatchBeatmap<'map>) -> Self {
|
fn from(map: CatchBeatmap<'map>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Map(map),
|
map_or_attrs: MapOrAttrs::Map(map),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
acc: None,
|
acc: None,
|
||||||
combo: None,
|
combo: None,
|
||||||
|
|
||||||
fruits: None,
|
fruits: None,
|
||||||
droplets: None,
|
droplets: None,
|
||||||
tiny_droplets: None,
|
tiny_droplets: None,
|
||||||
tiny_droplet_misses: None,
|
tiny_droplet_misses: None,
|
||||||
misses: None,
|
misses: None,
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,17 +424,14 @@ impl From<CatchDifficultyAttributes> for CatchPerformance<'_> {
|
|||||||
fn from(attrs: CatchDifficultyAttributes) -> Self {
|
fn from(attrs: CatchDifficultyAttributes) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
acc: None,
|
acc: None,
|
||||||
combo: None,
|
combo: None,
|
||||||
|
|
||||||
fruits: None,
|
fruits: None,
|
||||||
droplets: None,
|
droplets: None,
|
||||||
tiny_droplets: None,
|
tiny_droplets: None,
|
||||||
tiny_droplet_misses: None,
|
tiny_droplet_misses: None,
|
||||||
misses: None,
|
misses: None,
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,17 +21,13 @@ pub mod gradual;
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct ManiaPerformance<'map> {
|
pub struct ManiaPerformance<'map> {
|
||||||
map_or_attrs: MapOrAttrs<'map, Mania>,
|
map_or_attrs: MapOrAttrs<'map, Mania>,
|
||||||
mods: u32,
|
difficulty: ModeDifficulty,
|
||||||
passed_objects: Option<u32>,
|
|
||||||
clock_rate: Option<f64>,
|
|
||||||
|
|
||||||
pub(crate) n320: Option<u32>,
|
pub(crate) n320: Option<u32>,
|
||||||
pub(crate) n300: Option<u32>,
|
pub(crate) n300: Option<u32>,
|
||||||
pub(crate) n200: Option<u32>,
|
pub(crate) n200: Option<u32>,
|
||||||
pub(crate) n100: Option<u32>,
|
pub(crate) n100: Option<u32>,
|
||||||
pub(crate) n50: Option<u32>,
|
pub(crate) n50: Option<u32>,
|
||||||
pub(crate) misses: Option<u32>,
|
pub(crate) misses: Option<u32>,
|
||||||
|
|
||||||
acc: Option<f64>,
|
acc: Option<f64>,
|
||||||
hitresult_priority: HitResultPriority,
|
hitresult_priority: HitResultPriority,
|
||||||
}
|
}
|
||||||
@@ -57,7 +53,7 @@ impl<'map> ManiaPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
||||||
pub const fn mods(mut self, mods: u32) -> Self {
|
pub const fn mods(mut self, mods: u32) -> Self {
|
||||||
self.mods = mods;
|
self.difficulty = self.difficulty.mods(mods);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -70,7 +66,7 @@ impl<'map> ManiaPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// [`ManiaGradualPerformance`]: crate::mania::ManiaGradualPerformance
|
/// [`ManiaGradualPerformance`]: crate::mania::ManiaGradualPerformance
|
||||||
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
||||||
self.passed_objects = Some(passed_objects);
|
self.difficulty = self.difficulty.passed_objects(passed_objects);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -79,7 +75,7 @@ impl<'map> ManiaPerformance<'map> {
|
|||||||
/// If none is specified, it will take the clock rate based on the mods
|
/// If none is specified, it will take the clock rate based on the mods
|
||||||
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
||||||
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
||||||
self.clock_rate = Some(clock_rate);
|
self.difficulty = self.difficulty.clock_rate(clock_rate);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -168,21 +164,17 @@ impl<'map> ManiaPerformance<'map> {
|
|||||||
/// Create the [`ManiaScoreState`] that will be used for performance calculation.
|
/// Create the [`ManiaScoreState`] that will be used for performance calculation.
|
||||||
#[allow(clippy::too_many_lines, clippy::similar_names)]
|
#[allow(clippy::too_many_lines, clippy::similar_names)]
|
||||||
pub fn generate_state(&mut self) -> ManiaScoreState {
|
pub fn generate_state(&mut self) -> ManiaScoreState {
|
||||||
let n_objects = if let Some(passed) = self.passed_objects {
|
let attrs = match self.map_or_attrs {
|
||||||
passed
|
MapOrAttrs::Map(ref map) => {
|
||||||
} else {
|
let attrs = self.generate_attributes(map);
|
||||||
let attrs = match self.map_or_attrs {
|
|
||||||
MapOrAttrs::Map(ref map) => {
|
|
||||||
let attrs = self.generate_attributes(map);
|
|
||||||
|
|
||||||
self.map_or_attrs.attrs_or_insert(attrs)
|
self.map_or_attrs.attrs_or_insert(attrs)
|
||||||
}
|
}
|
||||||
MapOrAttrs::Attrs(ref attrs) => attrs,
|
MapOrAttrs::Attrs(ref attrs) => attrs,
|
||||||
};
|
|
||||||
|
|
||||||
attrs.n_objects
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let n_objects = cmp::min(self.difficulty.get_passed_objects() as u32, attrs.n_objects);
|
||||||
|
|
||||||
let priority = self.hitresult_priority;
|
let priority = self.hitresult_priority;
|
||||||
|
|
||||||
let misses = self.misses.map_or(0, |n| cmp::min(n, n_objects));
|
let misses = self.misses.map_or(0, |n| cmp::min(n, n_objects));
|
||||||
@@ -705,7 +697,7 @@ impl<'map> ManiaPerformance<'map> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let inner = ManiaPerformanceInner {
|
let inner = ManiaPerformanceInner {
|
||||||
mods: self.mods,
|
mods: self.difficulty.get_mods(),
|
||||||
attrs,
|
attrs,
|
||||||
state,
|
state,
|
||||||
};
|
};
|
||||||
@@ -714,17 +706,7 @@ impl<'map> ManiaPerformance<'map> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_attributes(&self, map: &ManiaBeatmap<'_>) -> ManiaDifficultyAttributes {
|
fn generate_attributes(&self, map: &ManiaBeatmap<'_>) -> ManiaDifficultyAttributes {
|
||||||
let mut calculator = ModeDifficulty::new();
|
self.difficulty.calculate(map)
|
||||||
|
|
||||||
if let Some(passed_objects) = self.passed_objects {
|
|
||||||
calculator = calculator.passed_objects(passed_objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(clock_rate) = self.clock_rate {
|
|
||||||
calculator = calculator.clock_rate(clock_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
calculator.mods(self.mods).calculate(map)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to create [`ManiaPerformance`] through a [`ModeAttributeProvider`].
|
/// Try to create [`ManiaPerformance`] through a [`ModeAttributeProvider`].
|
||||||
@@ -787,23 +769,19 @@ impl<'map> TryFrom<OsuPerformance<'map>> for ManiaPerformance<'map> {
|
|||||||
|
|
||||||
let OsuPerformance {
|
let OsuPerformance {
|
||||||
map_or_attrs: _,
|
map_or_attrs: _,
|
||||||
mods,
|
difficulty,
|
||||||
acc,
|
acc,
|
||||||
combo: _,
|
combo: _,
|
||||||
n300,
|
n300,
|
||||||
n100,
|
n100,
|
||||||
n50,
|
n50,
|
||||||
misses,
|
misses,
|
||||||
passed_objects,
|
|
||||||
clock_rate,
|
|
||||||
hitresult_priority,
|
hitresult_priority,
|
||||||
} = osu;
|
} = osu;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
map_or_attrs: MapOrAttrs::Map(map),
|
map_or_attrs: MapOrAttrs::Map(map),
|
||||||
mods,
|
difficulty,
|
||||||
passed_objects,
|
|
||||||
clock_rate,
|
|
||||||
n320: None,
|
n320: None,
|
||||||
n300,
|
n300,
|
||||||
n200: None,
|
n200: None,
|
||||||
@@ -820,9 +798,7 @@ impl<'map> From<ManiaBeatmap<'map>> for ManiaPerformance<'map> {
|
|||||||
fn from(map: ManiaBeatmap<'map>) -> Self {
|
fn from(map: ManiaBeatmap<'map>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Map(map),
|
map_or_attrs: MapOrAttrs::Map(map),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
n320: None,
|
n320: None,
|
||||||
n300: None,
|
n300: None,
|
||||||
n200: None,
|
n200: None,
|
||||||
@@ -839,9 +815,7 @@ impl From<ManiaDifficultyAttributes> for ManiaPerformance<'_> {
|
|||||||
fn from(attrs: ManiaDifficultyAttributes) -> Self {
|
fn from(attrs: ManiaDifficultyAttributes) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
n320: None,
|
n320: None,
|
||||||
n300: None,
|
n300: None,
|
||||||
n200: None,
|
n200: None,
|
||||||
|
|||||||
+12
-28
@@ -25,16 +25,13 @@ pub mod gradual;
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct OsuPerformance<'map> {
|
pub struct OsuPerformance<'map> {
|
||||||
pub(crate) map_or_attrs: MapOrAttrs<'map, Osu>,
|
pub(crate) map_or_attrs: MapOrAttrs<'map, Osu>,
|
||||||
pub(crate) mods: u32,
|
pub(crate) difficulty: ModeDifficulty,
|
||||||
pub(crate) acc: Option<f64>,
|
pub(crate) acc: Option<f64>,
|
||||||
pub(crate) combo: Option<u32>,
|
pub(crate) combo: Option<u32>,
|
||||||
|
|
||||||
pub(crate) n300: Option<u32>,
|
pub(crate) n300: Option<u32>,
|
||||||
pub(crate) n100: Option<u32>,
|
pub(crate) n100: Option<u32>,
|
||||||
pub(crate) n50: Option<u32>,
|
pub(crate) n50: Option<u32>,
|
||||||
pub(crate) misses: Option<u32>,
|
pub(crate) misses: Option<u32>,
|
||||||
pub(crate) passed_objects: Option<u32>,
|
|
||||||
pub(crate) clock_rate: Option<f64>,
|
|
||||||
pub(crate) hitresult_priority: HitResultPriority,
|
pub(crate) hitresult_priority: HitResultPriority,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +105,7 @@ impl<'map> OsuPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
||||||
pub const fn mods(mut self, mods: u32) -> Self {
|
pub const fn mods(mut self, mods: u32) -> Self {
|
||||||
self.mods = mods;
|
self.difficulty = self.difficulty.mods(mods);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -165,7 +162,7 @@ impl<'map> OsuPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// [`OsuGradualPerformance`]: crate::osu::OsuGradualPerformance
|
/// [`OsuGradualPerformance`]: crate::osu::OsuGradualPerformance
|
||||||
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
||||||
self.passed_objects = Some(passed_objects);
|
self.difficulty = self.difficulty.passed_objects(passed_objects);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -174,7 +171,7 @@ impl<'map> OsuPerformance<'map> {
|
|||||||
/// If none is specified, it will take the clock rate based on the mods
|
/// If none is specified, it will take the clock rate based on the mods
|
||||||
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
||||||
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
||||||
self.clock_rate = Some(clock_rate);
|
self.difficulty = self.difficulty.clock_rate(clock_rate);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -220,7 +217,10 @@ impl<'map> OsuPerformance<'map> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let max_combo = attrs.max_combo;
|
let max_combo = attrs.max_combo;
|
||||||
let n_objects = self.passed_objects.unwrap_or(attrs.n_objects());
|
let n_objects = cmp::min(
|
||||||
|
self.difficulty.get_passed_objects() as u32,
|
||||||
|
attrs.n_objects(),
|
||||||
|
);
|
||||||
let priority = self.hitresult_priority;
|
let priority = self.hitresult_priority;
|
||||||
|
|
||||||
let misses = self.misses.map_or(0, |n| cmp::min(n, n_objects));
|
let misses = self.misses.map_or(0, |n| cmp::min(n, n_objects));
|
||||||
@@ -401,7 +401,7 @@ impl<'map> OsuPerformance<'map> {
|
|||||||
|
|
||||||
let inner = OsuPerformanceInner {
|
let inner = OsuPerformanceInner {
|
||||||
attrs,
|
attrs,
|
||||||
mods: self.mods,
|
mods: self.difficulty.get_mods(),
|
||||||
acc: state.accuracy(),
|
acc: state.accuracy(),
|
||||||
state,
|
state,
|
||||||
effective_miss_count,
|
effective_miss_count,
|
||||||
@@ -411,17 +411,7 @@ impl<'map> OsuPerformance<'map> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_attributes(&self, map: &OsuBeatmap<'_>) -> OsuDifficultyAttributes {
|
fn generate_attributes(&self, map: &OsuBeatmap<'_>) -> OsuDifficultyAttributes {
|
||||||
let mut calculator = ModeDifficulty::new();
|
self.difficulty.calculate(map)
|
||||||
|
|
||||||
if let Some(passed_objects) = self.passed_objects {
|
|
||||||
calculator = calculator.passed_objects(passed_objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(clock_rate) = self.clock_rate {
|
|
||||||
calculator = calculator.clock_rate(clock_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
calculator.mods(self.mods).calculate(map)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to create [`OsuPerformance`] through a [`ModeAttributeProvider`].
|
/// Try to create [`OsuPerformance`] through a [`ModeAttributeProvider`].
|
||||||
@@ -461,16 +451,13 @@ impl<'map> From<OsuBeatmap<'map>> for OsuPerformance<'map> {
|
|||||||
fn from(map: OsuBeatmap<'map>) -> Self {
|
fn from(map: OsuBeatmap<'map>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Map(map),
|
map_or_attrs: MapOrAttrs::Map(map),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
acc: None,
|
acc: None,
|
||||||
combo: None,
|
combo: None,
|
||||||
|
|
||||||
n300: None,
|
n300: None,
|
||||||
n100: None,
|
n100: None,
|
||||||
n50: None,
|
n50: None,
|
||||||
misses: None,
|
misses: None,
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
hitresult_priority: HitResultPriority::default(),
|
hitresult_priority: HitResultPriority::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -480,16 +467,13 @@ impl From<OsuDifficultyAttributes> for OsuPerformance<'_> {
|
|||||||
fn from(attrs: OsuDifficultyAttributes) -> Self {
|
fn from(attrs: OsuDifficultyAttributes) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
acc: None,
|
acc: None,
|
||||||
combo: None,
|
combo: None,
|
||||||
|
|
||||||
n300: None,
|
n300: None,
|
||||||
n100: None,
|
n100: None,
|
||||||
n50: None,
|
n50: None,
|
||||||
misses: None,
|
misses: None,
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
hitresult_priority: HitResultPriority::default(),
|
hitresult_priority: HitResultPriority::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,10 @@ pub mod gradual;
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct TaikoPerformance<'map> {
|
pub struct TaikoPerformance<'map> {
|
||||||
pub(crate) map_or_attrs: MapOrAttrs<'map, Taiko>,
|
pub(crate) map_or_attrs: MapOrAttrs<'map, Taiko>,
|
||||||
mods: u32,
|
difficulty: ModeDifficulty,
|
||||||
combo: Option<u32>,
|
combo: Option<u32>,
|
||||||
acc: Option<f64>,
|
acc: Option<f64>,
|
||||||
passed_objects: Option<u32>,
|
|
||||||
clock_rate: Option<f64>,
|
|
||||||
hitresult_priority: HitResultPriority,
|
hitresult_priority: HitResultPriority,
|
||||||
|
|
||||||
pub(crate) n300: Option<u32>,
|
pub(crate) n300: Option<u32>,
|
||||||
pub(crate) n100: Option<u32>,
|
pub(crate) n100: Option<u32>,
|
||||||
pub(crate) misses: Option<u32>,
|
pub(crate) misses: Option<u32>,
|
||||||
@@ -54,7 +51,7 @@ impl<'map> TaikoPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
/// See [https://github.com/ppy/osu-api/wiki#mods](https://github.com/ppy/osu-api/wiki#mods)
|
||||||
pub const fn mods(mut self, mods: u32) -> Self {
|
pub const fn mods(mut self, mods: u32) -> Self {
|
||||||
self.mods = mods;
|
self.difficulty = self.difficulty.mods(mods);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -112,7 +109,7 @@ impl<'map> TaikoPerformance<'map> {
|
|||||||
///
|
///
|
||||||
/// [`TaikoGradualPerformance`]: crate::taiko::TaikoGradualPerformance
|
/// [`TaikoGradualPerformance`]: crate::taiko::TaikoGradualPerformance
|
||||||
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
pub const fn passed_objects(mut self, passed_objects: u32) -> Self {
|
||||||
self.passed_objects = Some(passed_objects);
|
self.difficulty = self.difficulty.passed_objects(passed_objects);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -121,7 +118,7 @@ impl<'map> TaikoPerformance<'map> {
|
|||||||
/// If none is specified, it will take the clock rate based on the mods
|
/// If none is specified, it will take the clock rate based on the mods
|
||||||
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
||||||
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
pub const fn clock_rate(mut self, clock_rate: f64) -> Self {
|
||||||
self.clock_rate = Some(clock_rate);
|
self.difficulty = self.difficulty.clock_rate(clock_rate);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -157,11 +154,7 @@ impl<'map> TaikoPerformance<'map> {
|
|||||||
|
|
||||||
let max_combo = attrs.max_combo();
|
let max_combo = attrs.max_combo();
|
||||||
|
|
||||||
let total_result_count = if let Some(passed_objects) = self.passed_objects {
|
let total_result_count = cmp::min(self.difficulty.get_passed_objects() as u32, max_combo);
|
||||||
cmp::min(max_combo, passed_objects)
|
|
||||||
} else {
|
|
||||||
max_combo
|
|
||||||
};
|
|
||||||
|
|
||||||
let priority = self.hitresult_priority;
|
let priority = self.hitresult_priority;
|
||||||
|
|
||||||
@@ -245,7 +238,7 @@ impl<'map> TaikoPerformance<'map> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let inner = TaikoPerformanceInner {
|
let inner = TaikoPerformanceInner {
|
||||||
mods: self.mods,
|
mods: self.difficulty.get_mods(),
|
||||||
state,
|
state,
|
||||||
attrs,
|
attrs,
|
||||||
};
|
};
|
||||||
@@ -254,17 +247,7 @@ impl<'map> TaikoPerformance<'map> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_attributes(&self, map: &TaikoBeatmap<'_>) -> TaikoDifficultyAttributes {
|
fn generate_attributes(&self, map: &TaikoBeatmap<'_>) -> TaikoDifficultyAttributes {
|
||||||
let mut calculator = ModeDifficulty::new();
|
self.difficulty.calculate(map)
|
||||||
|
|
||||||
if let Some(passed_objects) = self.passed_objects {
|
|
||||||
calculator = calculator.passed_objects(passed_objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(clock_rate) = self.clock_rate {
|
|
||||||
calculator = calculator.clock_rate(clock_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
calculator.mods(self.mods).calculate(map)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to create [`TaikoPerformance`] through a [`ModeAttributeProvider`].
|
/// Try to create [`TaikoPerformance`] through a [`ModeAttributeProvider`].
|
||||||
@@ -328,25 +311,21 @@ impl<'map> TryFrom<OsuPerformance<'map>> for TaikoPerformance<'map> {
|
|||||||
|
|
||||||
let OsuPerformance {
|
let OsuPerformance {
|
||||||
map_or_attrs: _,
|
map_or_attrs: _,
|
||||||
mods,
|
difficulty,
|
||||||
acc,
|
acc,
|
||||||
combo,
|
combo,
|
||||||
n300,
|
n300,
|
||||||
n100,
|
n100,
|
||||||
n50: _,
|
n50: _,
|
||||||
misses,
|
misses,
|
||||||
passed_objects,
|
|
||||||
clock_rate,
|
|
||||||
hitresult_priority,
|
hitresult_priority,
|
||||||
} = osu;
|
} = osu;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
map_or_attrs: MapOrAttrs::Map(map),
|
map_or_attrs: MapOrAttrs::Map(map),
|
||||||
mods,
|
difficulty,
|
||||||
combo,
|
combo,
|
||||||
acc,
|
acc,
|
||||||
passed_objects,
|
|
||||||
clock_rate,
|
|
||||||
hitresult_priority,
|
hitresult_priority,
|
||||||
n300,
|
n300,
|
||||||
n100,
|
n100,
|
||||||
@@ -359,12 +338,10 @@ impl<'map> From<TaikoBeatmap<'map>> for TaikoPerformance<'map> {
|
|||||||
fn from(map: TaikoBeatmap<'map>) -> Self {
|
fn from(map: TaikoBeatmap<'map>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Map(map),
|
map_or_attrs: MapOrAttrs::Map(map),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
combo: None,
|
combo: None,
|
||||||
acc: None,
|
acc: None,
|
||||||
misses: None,
|
misses: None,
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
n300: None,
|
n300: None,
|
||||||
n100: None,
|
n100: None,
|
||||||
hitresult_priority: HitResultPriority::default(),
|
hitresult_priority: HitResultPriority::default(),
|
||||||
@@ -376,12 +353,10 @@ impl From<TaikoDifficultyAttributes> for TaikoPerformance<'_> {
|
|||||||
fn from(attrs: TaikoDifficultyAttributes) -> Self {
|
fn from(attrs: TaikoDifficultyAttributes) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
map_or_attrs: MapOrAttrs::Attrs(attrs),
|
||||||
mods: 0,
|
difficulty: ModeDifficulty::new(),
|
||||||
combo: None,
|
combo: None,
|
||||||
acc: None,
|
acc: None,
|
||||||
misses: None,
|
misses: None,
|
||||||
passed_objects: None,
|
|
||||||
clock_rate: None,
|
|
||||||
n300: None,
|
n300: None,
|
||||||
n100: None,
|
n100: None,
|
||||||
hitresult_priority: HitResultPriority::default(),
|
hitresult_priority: HitResultPriority::default(),
|
||||||
|
|||||||
Reference in New Issue
Block a user