Skip to main content

rosu_pp/catch/
score_state.rs

1/// osu!catch hitresults.
2#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3pub struct CatchHitResults {
4    /// Amount of current fruits (300s).
5    pub fruits: u32,
6    /// Amount of current droplets (100s).
7    pub droplets: u32,
8    /// Amount of current tiny droplets (50s).
9    pub tiny_droplets: u32,
10    /// Amount of current tiny droplet misses (katus).
11    pub tiny_droplet_misses: u32,
12    /// Amount of current misses (fruits and droplets).
13    pub misses: u32,
14}
15
16impl CatchHitResults {
17    /// Create a new empty score state.
18    pub const fn new() -> Self {
19        Self {
20            fruits: 0,
21            droplets: 0,
22            tiny_droplets: 0,
23            tiny_droplet_misses: 0,
24            misses: 0,
25        }
26    }
27
28    /// Return the total amount of hits by adding everything up.
29    pub const fn total_hits(&self) -> u32 {
30        self.fruits + self.droplets + self.tiny_droplets + self.tiny_droplet_misses + self.misses
31    }
32
33    /// Return the total amount of successful hits by adding up fruits,
34    /// droplets, and tiny droplets.
35    pub const fn total_successful_hits(&self) -> u32 {
36        self.fruits + self.droplets + self.tiny_droplets
37    }
38
39    /// Calculate the accuracy between `0.0` and `1.0` for this state.
40    pub fn accuracy(&self) -> f64 {
41        let total_hits = self.total_hits();
42
43        if total_hits == 0 {
44            return 0.0;
45        }
46
47        let numerator = self.total_successful_hits();
48        let denominator = total_hits;
49
50        f64::from(numerator) / f64::from(denominator)
51    }
52}
53
54impl Default for CatchHitResults {
55    fn default() -> Self {
56        Self::new()
57    }
58}
59
60/// Aggregation for a score's current state.
61#[derive(Clone, Debug, PartialEq, Eq)]
62pub struct CatchScoreState {
63    /// Maximum combo that the score has had so far.
64    /// **Not** the maximum possible combo of the map so far.
65    ///
66    /// Note that only fruits and droplets are considered for osu!catch combo.
67    pub max_combo: u32,
68    /// Hitresults of a score.
69    pub hitresults: CatchHitResults,
70}
71
72impl CatchScoreState {
73    /// Create a new empty score state.
74    pub const fn new() -> Self {
75        Self {
76            max_combo: 0,
77            hitresults: CatchHitResults::new(),
78        }
79    }
80}
81
82impl Default for CatchScoreState {
83    fn default() -> Self {
84        Self::new()
85    }
86}