diff --git a/Cargo.toml b/Cargo.toml index 12f50d16..915c8873 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rina-pp" -version = "0.9.14" +version = "0.9.15" authors = ["MaxOhn ", "Aoba Suzukaze "] edition = "2021" license = "MIT" @@ -17,7 +17,8 @@ async_tokio = ["tokio"] [dependencies] async-std = { version = "1.9", optional = true } -tokio = { version = "1.2", optional = true, default-features = false, features = ["fs", "io-util"] } +tokio = { version = "1.2", optional = true, default-features = false, features = ["full"] } +sqlx = { version = "0.7", features = [ "mysql", "runtime-tokio" ] } [dev-dependencies] tokio = { version = "1.2", default-features = false, features = ["fs", "rt"] } diff --git a/src/osu/pp.rs b/src/osu/pp.rs index abe00fdc..6dc71aae 100644 --- a/src/osu/pp.rs +++ b/src/osu/pp.rs @@ -487,6 +487,48 @@ impl OsuPpInner { 0.0 }; + if self.mods.rx() { + let diff_ratio = self.get_distance_duration_ratio(); + let mut length = self.map.hit_length(); + + if self.mods.dt() { + length /= 1.5; + } + + if self.mods.dt() { + aim_value *= 2.31_f64.powf(1.0 + diff_ratio / 11.0) * 0.39; + } else { + aim_value *= 2.31_f64.powf(1.0 + diff_ratio / 7.0) * 0.38; + }; + + println!( + "{} / {} = {} (ratio: {})", + length, + self.total_hits(), + length / self.total_hits(), + diff_ratio + ); + + if self.mods.dt() { + println!( + "aim buff/nerf with ratio {}: {}", + diff_ratio, + 2.31_f64.powf(1.0 + diff_ratio / 11.0) * 0.39 + ); + } else { + println!( + "aim buff/nerf with ratio {}: {}", + diff_ratio, + 2.31_f64.powf(1.0 + diff_ratio / 7.0) * 0.38 + ); + }; + + if length <= 65.0_f64 { + println!("length nerf: {}", (length / 489.0).sqrt() * 1.4 + 0.53); + + aim_value *= (length / 489.0).sqrt() * 1.4 + 0.49 + } + } if self.mods.rx() { aim_value *= 1.0 + ar_factor; } else { @@ -515,26 +557,6 @@ impl OsuPpInner { aim_value *= slider_nerf_factor; } - if self.mods.rx() { - let diff_ratio = self.get_distance_duration_ratio(); - let mut length = self.map.hit_length(); - - if self.mods.dt() { - length /= 1.5; - } - - if self.mods.dt() { - aim_value *= 1.96_f64.powf(diff_ratio + (length / self.total_hits() / 2.0)) * 0.2; - } else { - aim_value *= 2.1_f64.powf(diff_ratio + (length / self.total_hits() / 2.0)) * 0.2; - }; - - if length <= 60.0_f64 { - // maybe say length / total hits instead of 130. - aim_value *= 1.21 * (length / 120.0).sqrt() + 0.1 - } - } - aim_value *= self.acc; // * It is important to consider accuracy difficulty when scaling with accuracy. aim_value *= 0.98 + self.attrs.od * self.attrs.od / 2500.0; @@ -597,7 +619,7 @@ impl OsuPpInner { - (relevant_total_diff - (self.state.n300 + self.state.n100) as f64).max(0.0)) .max(0.0); - let relevant_acc = if self.attrs.speed_note_count.abs() <= f64::EPSILON { + let _relevant_acc = if self.attrs.speed_note_count.abs() <= f64::EPSILON { 0.0 } else { (relevant_n300 * 6.0 + relevant_n100 * 2.0 + relevant_n50) @@ -605,15 +627,15 @@ impl OsuPpInner { }; // * Scale the speed value with accuracy and OD. - speed_value *= (0.95 + self.attrs.od * self.attrs.od / 750.0) - * ((self.acc + relevant_acc) / 2.0).powf((14.5 - (self.attrs.od).max(8.0)) / 2.0); + // speed_value *= (0.95 + self.attrs.od * self.attrs.od / 750.0) + // * ((self.acc + relevant_acc) / 2.0).powf((14.5 - (self.attrs.od).max(8.0)) / 2.0); // * Scale the speed value with # of 50s to punish doubletapping. // akatsuki osu_2019 used 0.98 - // speed_value *= 0.99_f64.powf( - // (self.state.n50 as f64 >= total_hits / 500.0) as u8 as f64 - // * (self.state.n50 as f64 - total_hits / 500.0), - // ); + speed_value *= 0.98_f64.powf( + (self.state.n50 as f64 >= total_hits / 500.0) as u8 as f64 + * (self.state.n50 as f64 - total_hits / 500.0), + ); if self.mods.rx() { let avg_distance = self.get_average_circle_distance(); @@ -636,19 +658,19 @@ impl OsuPpInner { // * of the calculation we focus on hitting the timing hit window. let amount_hit_objects_with_acc = self.attrs.n_circles; - let _better_acc_percentage = if amount_hit_objects_with_acc > 0 { - let sub = self.state.total_hits() - amount_hit_objects_with_acc; + // let _better_acc_percentage = if amount_hit_objects_with_acc > 0 { + // let sub = self.state.total_hits() - amount_hit_objects_with_acc; - // * It is possible to reach a negative accuracy with this formula. Cap it at zero - zero points. - if self.state.n300 < sub { - 0.0 - } else { - ((self.state.n300 - sub) * 6 + self.state.n100 * 2 + self.state.n50) as f64 - / (amount_hit_objects_with_acc * 6) as f64 - } - } else { - 0.0 - }; + // // * It is possible to reach a negative accuracy with this formula. Cap it at zero - zero points. + // if self.state.n300 < sub { + // 0.0 + // } else { + // ((self.state.n300 - sub) * 6 + self.state.n100 * 2 + self.state.n50) as f64 + // / (amount_hit_objects_with_acc * 6) as f64 + // } + // } else { + // 0.0 + // }; // * Lots of arbitrary values from testing. // * Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution. @@ -656,12 +678,17 @@ impl OsuPpInner { // let mut acc_value = 1.52163_f64.powf(self.attrs.ar) * better_acc_percentage.powi(24); //akatsuki osu_2019 - //let better_acc_percentage = (n_circles > 0.0) as u8 as f32 - // * (((n300 - (total_hits - n_circles)) * 6.0 + n100 * 2.0 + n50) / (n_circles * 6.0)) - // .max(0.0); + let better_acc_percentage = (amount_hit_objects_with_acc as f32 > 0.0) as u8 as f32 + * (((self.state.n300 - (self.state.total_hits() - amount_hit_objects_with_acc)) + as f32 + * 6.0 + + self.state.n100 as f32 * 2.0 + + self.state.n50 as f32) + / (amount_hit_objects_with_acc as f32 * 6.0)) + .max(0.0); let mut acc_value = - 1.492_f64.powf(self.attrs.od) * _better_acc_percentage.powi(28).sqrt() * 2.5; + 1.492_f64.powf(self.attrs.od) * (better_acc_percentage as f64).powi(28).sqrt() * 2.5; // * Bonus for many hitcircles - it's harder to keep good accuracy up for longer. if amount_hit_objects_with_acc > 1000 { @@ -723,9 +750,9 @@ impl OsuPpInner { } fn get_combo_scaling_factor(&self) -> f64 { - // if self.mods.rx() { - // return 1.0; - // } + if self.mods.rx() { + return 1.0; + } if self.attrs.max_combo == 0 { 1.0 @@ -779,7 +806,7 @@ impl OsuPpInner { let mut duration = next_obj.start_time - obj.end_time(); if self.mods.dt() { - duration /= 1.19; // should be 1.5, but it buffs maps too much + duration /= 1.5; // should be 1.5, but it buffs maps too much } let mut ratio = 0.0;