Skip to main content

rosu_pp/mania/performance/
inspect.rs

1use std::cmp;
2
3use crate::{
4    Difficulty,
5    any::{HitResultPriority, InspectablePerformance},
6    mania::{Mania, ManiaDifficultyAttributes},
7};
8
9/// Inspectable [`ManiaPerformance`] to expose all of its internal details.
10///
11/// [`ManiaPerformance`]: crate::mania::performance::ManiaPerformance
12#[derive(Clone, Debug)]
13pub struct InspectManiaPerformance<'a> {
14    pub attrs: &'a ManiaDifficultyAttributes,
15    pub difficulty: &'a Difficulty,
16    pub n320: Option<u32>,
17    pub n300: Option<u32>,
18    pub n200: Option<u32>,
19    pub n100: Option<u32>,
20    pub n50: Option<u32>,
21    pub misses: Option<u32>,
22    pub acc: Option<f64>,
23    pub hitresult_priority: HitResultPriority,
24}
25
26impl InspectManiaPerformance<'_> {
27    pub fn total_hits(&self) -> u32 {
28        let passed_objects = self.difficulty.get_passed_objects() as u32;
29        let total_hits = cmp::min(passed_objects, self.attrs.n_objects);
30
31        if self.is_classic() {
32            total_hits
33        } else {
34            // Note that we don't consider `passed_objects` here. Unsure if
35            // that's the correct behavior.
36            total_hits + self.attrs.n_hold_notes
37        }
38    }
39
40    pub fn misses(&self) -> u32 {
41        self.misses.map_or(0, |n| cmp::min(n, self.total_hits()))
42    }
43
44    pub fn is_classic(&self) -> bool {
45        !self.difficulty.get_lazer() || self.difficulty.get_mods().cl()
46    }
47}
48
49impl InspectablePerformance for Mania {
50    type InspectPerformance<'a> = InspectManiaPerformance<'a>;
51
52    fn inspect_performance<'a>(
53        perf: &'a Self::Performance<'_>,
54        attrs: &'a Self::DifficultyAttributes,
55    ) -> Self::InspectPerformance<'a> {
56        InspectManiaPerformance {
57            attrs,
58            difficulty: &perf.difficulty,
59            n320: perf.n320,
60            n300: perf.n300,
61            n200: perf.n200,
62            n100: perf.n100,
63            n50: perf.n50,
64            misses: perf.misses,
65            acc: perf.acc,
66            hitresult_priority: perf.hitresult_priority,
67        }
68    }
69}