peace_performance/parse/
attributes.rs1use crate::Mods;
2
3#[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 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 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 let od = (self.od * multiplier).min(10.0);
61
62 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 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}