rosu_pp/osu/
attributes.rs

1use crate::{model::beatmap::BeatmapAttributesBuilder, osu::performance::OsuPerformance};
2
3/// The result of a difficulty calculation on an osu!standard map.
4#[derive(Clone, Debug, Default, PartialEq)]
5pub struct OsuDifficultyAttributes {
6    /// The difficulty of the aim skill.
7    pub aim: f64,
8    /// The number of sliders weighted by difficulty.
9    pub aim_difficult_slider_count: f64,
10    /// The difficulty of the speed skill.
11    pub speed: f64,
12    /// The difficulty of the flashlight skill.
13    pub flashlight: f64,
14    /// The ratio of the aim strain with and without considering sliders
15    pub slider_factor: f64,
16    /// The number of clickable objects weighted by difficulty.
17    pub speed_note_count: f64,
18    /// Weighted sum of aim strains.
19    pub aim_difficult_strain_count: f64,
20    /// Weighted sum of speed strains.
21    pub speed_difficult_strain_count: f64,
22    /// The approach rate.
23    pub ar: f64,
24    /// The great hit window.
25    pub great_hit_window: f64,
26    /// The ok hit window.
27    pub ok_hit_window: f64,
28    /// The meh hit window.
29    pub meh_hit_window: f64,
30    /// The health drain rate.
31    pub hp: f64,
32    /// The amount of circles.
33    pub n_circles: u32,
34    /// The amount of sliders.
35    pub n_sliders: u32,
36    /// The amount of "large ticks".
37    ///
38    /// The meaning depends on the kind of score:
39    /// - if set on osu!stable, this value is irrelevant
40    /// - if set on osu!lazer *with* slider accuracy, this value is the amount
41    ///   of hit slider ticks and repeats
42    /// - if set on osu!lazer *without* slider accuracy, this value is the
43    ///   amount of hit slider heads, ticks, and repeats
44    pub n_large_ticks: u32,
45    /// The amount of spinners.
46    pub n_spinners: u32,
47    /// The final star rating
48    pub stars: f64,
49    /// The maximum combo.
50    pub max_combo: u32,
51}
52
53impl OsuDifficultyAttributes {
54    /// Return the maximum combo.
55    pub const fn max_combo(&self) -> u32 {
56        self.max_combo
57    }
58
59    /// Return the amount of hitobjects.
60    pub const fn n_objects(&self) -> u32 {
61        self.n_circles + self.n_sliders + self.n_spinners
62    }
63
64    /// The overall difficulty
65    pub const fn od(&self) -> f64 {
66        BeatmapAttributesBuilder::osu_great_hit_window_to_od(self.great_hit_window)
67    }
68
69    /// Returns a builder for performance calculation.
70    pub fn performance<'a>(self) -> OsuPerformance<'a> {
71        self.into()
72    }
73}
74
75/// The result of a performance calculation on an osu!standard map.
76#[derive(Clone, Debug, Default, PartialEq)]
77pub struct OsuPerformanceAttributes {
78    /// The difficulty attributes that were used for the performance calculation
79    pub difficulty: OsuDifficultyAttributes,
80    /// The final performance points.
81    pub pp: f64,
82    /// The accuracy portion of the final pp.
83    pub pp_acc: f64,
84    /// The aim portion of the final pp.
85    pub pp_aim: f64,
86    /// The flashlight portion of the final pp.
87    pub pp_flashlight: f64,
88    /// The speed portion of the final pp.
89    pub pp_speed: f64,
90    /// Misses including an approximated amount of slider breaks
91    pub effective_miss_count: f64,
92    /// Approximated unstable-rate
93    pub speed_deviation: Option<f64>,
94}
95
96impl OsuPerformanceAttributes {
97    /// Return the star value.
98    pub const fn stars(&self) -> f64 {
99        self.difficulty.stars
100    }
101
102    /// Return the performance point value.
103    pub const fn pp(&self) -> f64 {
104        self.pp
105    }
106
107    /// Return the maximum combo of the map.
108    pub const fn max_combo(&self) -> u32 {
109        self.difficulty.max_combo
110    }
111    /// Return the amount of hitobjects.
112    pub const fn n_objects(&self) -> u32 {
113        self.difficulty.n_objects()
114    }
115
116    /// Returns a builder for performance calculation.
117    pub fn performance<'a>(self) -> OsuPerformance<'a> {
118        self.difficulty.into()
119    }
120}
121
122impl From<OsuPerformanceAttributes> for OsuDifficultyAttributes {
123    fn from(attributes: OsuPerformanceAttributes) -> Self {
124        attributes.difficulty
125    }
126}