diff --git a/src/osu/attributes.rs b/src/osu/attributes.rs index c968d8e2..7d071fbd 100644 --- a/src/osu/attributes.rs +++ b/src/osu/attributes.rs @@ -1,4 +1,4 @@ -use crate::osu::performance::OsuPerformance; +use crate::{model::hit_object::HitObject, osu::performance::OsuPerformance}; /// The result of a difficulty calculation on an osu!standard map. #[derive(Clone, Debug, Default, PartialEq)] @@ -13,6 +13,8 @@ pub struct OsuDifficultyAttributes { pub slider_factor: f64, /// The number of clickable objects weighted by difficulty. pub speed_note_count: f64, + /// The circle size. + pub cs: f64, /// The approach rate. pub ar: f64, /// The overall difficulty @@ -29,6 +31,8 @@ pub struct OsuDifficultyAttributes { pub stars: f64, /// The maximum combo. pub max_combo: u32, + /// List of all objects. + pub hit_objects: Vec, } impl OsuDifficultyAttributes { diff --git a/src/osu/difficulty/gradual.rs b/src/osu/difficulty/gradual.rs index 777ba7a6..606e8eed 100644 --- a/src/osu/difficulty/gradual.rs +++ b/src/osu/difficulty/gradual.rs @@ -176,6 +176,7 @@ impl Iterator for OsuGradualDifficulty { let speed_difficulty_value = self.skills.speed.as_difficulty_value(); let flashlight_difficulty_value = self.skills.flashlight.as_difficulty_value(); + DifficultyValues::eval( &mut attrs, self.difficulty.get_mods(), @@ -184,6 +185,8 @@ impl Iterator for OsuGradualDifficulty { speed_difficulty_value, speed_relevant_note_count, flashlight_difficulty_value, + // not sure if we will every utilize this feature for pp system, so hit_objects shouldn't matter + vec![] ); Some(attrs) diff --git a/src/osu/difficulty/mod.rs b/src/osu/difficulty/mod.rs index c7b784ec..c350944a 100644 --- a/src/osu/difficulty/mod.rs +++ b/src/osu/difficulty/mod.rs @@ -2,7 +2,7 @@ use std::{cmp, pin::Pin}; use crate::{ any::difficulty::{skills::Skill, Difficulty}, - model::beatmap::BeatmapAttributes, + model::{beatmap::BeatmapAttributes, hit_object::HitObject}, osu::{ convert::convert_objects, difficulty::{object::OsuDifficultyObject, scaling_factor::ScalingFactor}, @@ -45,6 +45,7 @@ pub fn difficulty(difficulty: &Difficulty, converted: &OsuBeatmap<'_>) -> OsuDif let flashlight_difficulty_value = flashlight.difficulty_value(); let mods = difficulty.get_mods(); + let hit_objects = converted.hit_objects.clone(); DifficultyValues::eval( &mut attrs, @@ -54,6 +55,7 @@ pub fn difficulty(difficulty: &Difficulty, converted: &OsuBeatmap<'_>) -> OsuDif speed_difficulty_value, speed_relevant_note_count, flashlight_difficulty_value, + hit_objects, ); attrs @@ -76,6 +78,7 @@ impl OsuDifficultySetup { ar: map_attrs.ar, hp: map_attrs.hp, od: map_attrs.od, + cs: map_attrs.cs, ..Default::default() }; @@ -152,6 +155,7 @@ impl DifficultyValues { speed_difficulty_value: f64, speed_relevant_note_count: f64, flashlight_difficulty_value: f64, + hit_objects: Vec, ) { let mut aim_rating = aim_difficulty_value.sqrt() * DIFFICULTY_MULTIPLIER; let aim_rating_no_sliders = aim_no_sliders_difficulty_value.sqrt() * DIFFICULTY_MULTIPLIER; @@ -205,6 +209,7 @@ impl DifficultyValues { attrs.slider_factor = slider_factor; attrs.stars = star_rating; attrs.speed_note_count = speed_relevant_note_count; + attrs.hit_objects = hit_objects; } pub fn create_difficulty_objects<'a>( diff --git a/src/osu/performance/mod.rs b/src/osu/performance/mod.rs index 0c0daabc..1afcb63d 100644 --- a/src/osu/performance/mod.rs +++ b/src/osu/performance/mod.rs @@ -1,6 +1,6 @@ use std::cmp; -use rosu_map::section::general::GameMode; +use rosu_map::{section::general::GameMode}; use crate::{ any::{Difficulty, HitResultPriority, IntoModePerformance, IntoPerformance, Performance}, @@ -610,9 +610,7 @@ impl OsuPerformanceInner { aim_value *= self.get_combo_scaling_factor(); - let ar_factor = if self.mods.rx() { - 0.0 - } else if self.attrs.ar > 10.33 { + let ar_factor = if self.attrs.ar > 10.33 { 0.3 * (self.attrs.ar - 10.33) } else if self.attrs.ar < 8.0 { 0.05 * (8.0 - self.attrs.ar) @@ -624,7 +622,7 @@ impl OsuPerformanceInner { if self.mods.rx() { aim_value *= 1.0 + ar_factor; } else { - aim_value *= 1.0 + ar_factor * len_bonus + aim_value *= 1.0 + ar_factor * len_bonus; } if self.mods.hd() { @@ -656,10 +654,6 @@ impl OsuPerformanceInner { } fn compute_speed_value(&self) -> f64 { - if self.mods.rx() { - return 0.0; - } - let mut speed_value = (5.0 * (self.attrs.speed / 0.0675).max(1.0) - 4.0).powf(3.0) / 100_000.0; @@ -727,10 +721,6 @@ impl OsuPerformanceInner { } fn compute_accuracy_value(&self) -> f64 { - if self.mods.rx() { - return 0.0; - } - // * This percentage only considers HitCircles of any value - in this part // * of the calculation we focus on hitting the timing hit window. let amount_hit_objects_with_acc = self.attrs.n_circles;