peace_performance/parse/
attributes.rs

1use crate::Mods;
2
3/// Summary struct for a [`Beatmap`](crate::Beatmap)'s attributes.
4#[derive(Clone, Debug)]
5pub struct BeatmapAttributes {
6    pub ar: f32,
7    pub od: f32,
8    pub cs: f32,
9    pub hp: f32,
10    pub clock_rate: f32,
11}
12
13impl BeatmapAttributes {
14    const AR0_MS: f32 = 1800.0;
15    const AR5_MS: f32 = 1200.0;
16    const AR10_MS: f32 = 450.0;
17    const AR_MS_STEP_1: f32 = (Self::AR0_MS - Self::AR5_MS) / 5.0;
18    const AR_MS_STEP_2: f32 = (Self::AR5_MS - Self::AR10_MS) / 5.0;
19
20    #[inline]
21    pub(crate) fn new(ar: f32, od: f32, cs: f32, hp: f32) -> Self {
22        Self {
23            ar,
24            od,
25            cs,
26            hp,
27            clock_rate: 1.0,
28        }
29    }
30
31    /// Adjusts attributes w.r.t. mods.
32    /// AR is further adjusted by its hitwindow.
33    /// OD is __not__ adjusted by its hitwindow.
34    pub fn mods(self, mods: impl Mods) -> Self {
35        if !mods.change_map() {
36            return self;
37        }
38
39        let clock_rate = mods.speed();
40        let multiplier = mods.od_ar_hp_multiplier();
41
42        // AR
43        let mut ar = self.ar * multiplier;
44        let mut ar_ms = if ar <= 5.0 {
45            Self::AR0_MS - Self::AR_MS_STEP_1 * ar
46        } else {
47            Self::AR5_MS - Self::AR_MS_STEP_2 * (ar - 5.0)
48        };
49
50        ar_ms = ar_ms.max(Self::AR10_MS).min(Self::AR0_MS);
51        ar_ms /= clock_rate;
52
53        ar = if ar_ms > Self::AR5_MS {
54            (Self::AR0_MS - ar_ms) / Self::AR_MS_STEP_1
55        } else {
56            5.0 + (Self::AR5_MS - ar_ms) / Self::AR_MS_STEP_2
57        };
58
59        // OD
60        let od = (self.od * multiplier).min(10.0);
61
62        // CS
63        let mut cs = self.cs;
64        if mods.hr() {
65            cs *= 1.3;
66        } else if mods.ez() {
67            cs *= 0.5;
68        }
69        cs = cs.min(10.0);
70
71        // HP
72        let hp = (self.hp * multiplier).min(10.0);
73
74        Self {
75            ar,
76            od,
77            cs,
78            hp,
79            clock_rate,
80        }
81    }
82}