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}