Revert "lets try something........"

This reverts commit 576954a0ac.
This commit is contained in:
tsunyoku
2024-12-14 23:35:00 +00:00
parent 576954a0ac
commit 6d22dcdcaf
6 changed files with 70 additions and 97 deletions
+5 -5
View File
@@ -2,23 +2,23 @@ use super::OsuObject;
pub(crate) struct DifficultyObject<'h> { pub(crate) struct DifficultyObject<'h> {
pub(crate) base: &'h OsuObject, pub(crate) base: &'h OsuObject,
pub(crate) prev: Option<(f32, f64)>, // (jump_dist, strain_time) pub(crate) prev: Option<(f32, f32)>, // (jump_dist, strain_time)
pub(crate) jump_dist: f32, pub(crate) jump_dist: f32,
pub(crate) travel_dist: f32, pub(crate) travel_dist: f32,
pub(crate) angle: Option<f32>, pub(crate) angle: Option<f32>,
pub(crate) delta: f64, pub(crate) delta: f32,
pub(crate) strain_time: f64, pub(crate) strain_time: f32,
} }
impl<'h> DifficultyObject<'h> { impl<'h> DifficultyObject<'h> {
pub(crate) fn new( pub(crate) fn new(
base: &'h OsuObject, base: &'h OsuObject,
prev: &OsuObject, prev: &OsuObject,
prev_vals: Option<(f32, f64)>, // (jump_dist, strain_time) prev_vals: Option<(f32, f32)>, // (jump_dist, strain_time)
prev_prev: Option<OsuObject>, prev_prev: Option<OsuObject>,
clock_rate: f64, clock_rate: f32,
scaling_factor: f32, scaling_factor: f32,
) -> Self { ) -> Self {
let delta = (base.time - prev.time) / clock_rate; let delta = (base.time - prev.time) / clock_rate;
+4 -4
View File
@@ -20,7 +20,7 @@ const LEGACY_LAST_TICK_OFFSET: f64 = 36.0;
const BASE_SCORING_DISTANCE: f64 = 100.0; const BASE_SCORING_DISTANCE: f64 = 100.0;
pub(crate) struct OsuObject { pub(crate) struct OsuObject {
pub(crate) time: f64, pub(crate) time: f32,
pub(crate) pos: Pos, pub(crate) pos: Pos,
pub(crate) end_pos: Pos, pub(crate) end_pos: Pos,
// circle: Some(0.0) | slider: Some(_) | spinner: None // circle: Some(0.0) | slider: Some(_) | spinner: None
@@ -44,7 +44,7 @@ impl OsuObject {
attrs.n_circles += 1; attrs.n_circles += 1;
Self { Self {
time: h.start_time, time: h.start_time as f32,
pos: h.pos, pos: h.pos,
end_pos: h.pos, end_pos: h.pos,
travel_dist: Some(0.0), travel_dist: Some(0.0),
@@ -185,7 +185,7 @@ impl OsuObject {
travel_dist *= scaling_factor; travel_dist *= scaling_factor;
Self { Self {
time: h.start_time, time: h.start_time as f32,
pos: h.pos, pos: h.pos,
end_pos, end_pos,
travel_dist: Some(travel_dist), travel_dist: Some(travel_dist),
@@ -195,7 +195,7 @@ impl OsuObject {
attrs.n_spinners += 1; attrs.n_spinners += 1;
Self { Self {
time: h.start_time, time: h.start_time as f32,
pos: h.pos, pos: h.pos,
end_pos: h.pos, end_pos: h.pos,
travel_dist: None, travel_dist: None,
+9 -10
View File
@@ -243,7 +243,7 @@ impl<'m> OsuPP<'m> {
self.assert_hitresults(); self.assert_hitresults();
let total_hits = self.total_hits() as f32; let total_hits = self.total_hits() as f32;
let mut multiplier = 1.15; let mut multiplier = 1.2;
let effective_miss_count = self.calculate_effective_miss_count(); let effective_miss_count = self.calculate_effective_miss_count();
@@ -289,8 +289,8 @@ impl<'m> OsuPP<'m> {
let mut aim_value = (5.0 * (raw_aim / 0.0675).max(1.0) - 4.0).powi(3) / 100_000.0; let mut aim_value = (5.0 * (raw_aim / 0.0675).max(1.0) - 4.0).powi(3) / 100_000.0;
// Longer maps are worth more // Longer maps are worth more
let len_bonus = 1.0 let len_bonus = 0.88
+ 0.35 * (total_hits / 2000.0).min(1.0) + 0.4 * (total_hits / 2000.0).min(1.0)
+ (total_hits > 2000.0) as u8 as f32 * 0.5 * (total_hits / 2000.0).log10(); + (total_hits > 2000.0) as u8 as f32 * 0.5 * (total_hits / 2000.0).log10();
aim_value *= len_bonus; aim_value *= len_bonus;
@@ -332,8 +332,8 @@ impl<'m> OsuPP<'m> {
(5.0 * (attributes.speed_strain as f32 / 0.0675).max(1.0) - 4.0).powi(3) / 100_000.0; (5.0 * (attributes.speed_strain as f32 / 0.0675).max(1.0) - 4.0).powi(3) / 100_000.0;
// Longer maps are worth more // Longer maps are worth more
let len_bonus = 1.0 let len_bonus = 0.88
+ 0.35 * (total_hits / 2000.0).min(1.0) + 0.4 * (total_hits / 2000.0).min(1.0)
+ (total_hits > 2000.0) as u8 as f32 * 0.5 * (total_hits / 2000.0).log10(); + (total_hits > 2000.0) as u8 as f32 * 0.5 * (total_hits / 2000.0).log10();
speed_value *= len_bonus; speed_value *= len_bonus;
@@ -356,7 +356,7 @@ impl<'m> OsuPP<'m> {
let n100 = self.n100.unwrap(); let n100 = self.n100.unwrap();
let n50 = self.n50.unwrap(); let n50 = self.n50.unwrap();
let relevant_total_diff = total_hits - attributes.speed_note_count as f32; let relevant_total_diff = total_hits - attributes.speed_note_count;
let relevant_n300 = (n300 as f32 - relevant_total_diff).max(0.0); let relevant_n300 = (n300 as f32 - relevant_total_diff).max(0.0);
let relevant_n100 = (n100 as f32 - (relevant_total_diff - n300 as f32).max(0.0)).max(0.0); let relevant_n100 = (n100 as f32 - (relevant_total_diff - n300 as f32).max(0.0)).max(0.0);
let relevant_n50 = let relevant_n50 =
@@ -366,7 +366,7 @@ impl<'m> OsuPP<'m> {
0.0 0.0
} else { } else {
(relevant_n300 * 6.0 + relevant_n100 * 2.0 + relevant_n50) (relevant_n300 * 6.0 + relevant_n100 * 2.0 + relevant_n50)
/ (attributes.speed_note_count as f32 * 6.0) / (attributes.speed_note_count * 6.0)
}; };
speed_value *= (0.95 + attributes.od as f32 * attributes.od as f32 / 750.0) speed_value *= (0.95 + attributes.od as f32 * attributes.od as f32 / 750.0)
@@ -392,10 +392,9 @@ impl<'m> OsuPP<'m> {
fn calculate_miss_penalty( fn calculate_miss_penalty(
&self, &self,
effective_miss_count: f32, effective_miss_count: f32,
difficult_strain_count: f64, difficult_strain_count: f32,
) -> f32 { ) -> f32 {
0.96 / ((effective_miss_count / (4.0 * (difficult_strain_count as f32).ln().powf(0.94))) 0.96 / ((effective_miss_count / (4.0 * difficult_strain_count.ln().powf(0.94))) + 1.0)
+ 1.0)
} }
#[inline] #[inline]
+27 -49
View File
@@ -1,48 +1,42 @@
use crate::util::strains_vec::StrainsVec;
use super::{DifficultyObject, SkillKind}; use super::{DifficultyObject, SkillKind};
const SPEED_SKILL_MULTIPLIER: f64 = 1400.0; use std::cmp::Ordering;
const SPEED_STRAIN_DECAY_BASE: f64 = 0.3;
const AIM_SKILL_MULTIPLIER: f64 = 26.4; const SPEED_SKILL_MULTIPLIER: f32 = 1400.0;
const AIM_STRAIN_DECAY_BASE: f64 = 0.15; const SPEED_STRAIN_DECAY_BASE: f32 = 0.3;
const DECAY_WEIGHT: f64 = 0.9; const AIM_SKILL_MULTIPLIER: f32 = 26.25;
const AIM_STRAIN_DECAY_BASE: f32 = 0.15;
const REDUCED_STRAIN_BASELINE: f64 = 0.75; const DECAY_WEIGHT: f32 = 0.9;
pub(crate) struct Skill { pub(crate) struct Skill {
current_strain: f64, current_strain: f32,
current_section_peak: f64, current_section_peak: f32,
kind: SkillKind, kind: SkillKind,
pub(crate) strain_peaks: StrainsVec, pub(crate) strain_peaks: Vec<f32>,
prev_time: Option<f64>, prev_time: Option<f32>,
pub(crate) object_strains: Vec<f64>, pub(crate) object_strains: Vec<f32>,
difficulty_value: Option<f64>, difficulty_value: Option<f32>,
section_length: f64,
} }
impl Skill { impl Skill {
#[inline] #[inline]
pub(crate) fn new(kind: SkillKind, section_length: f64) -> Self { pub(crate) fn new(kind: SkillKind) -> Self {
Self { Self {
current_strain: 1.0, current_strain: 1.0,
current_section_peak: 1.0, current_section_peak: 1.0,
kind, kind,
strain_peaks: StrainsVec::with_capacity(256), strain_peaks: Vec::with_capacity(128),
prev_time: None, prev_time: None,
object_strains: Vec::new(), object_strains: Vec::new(),
difficulty_value: None, difficulty_value: None,
section_length,
} }
} }
@@ -52,7 +46,7 @@ impl Skill {
} }
#[inline] #[inline]
pub(crate) fn start_new_section_from(&mut self, time: f64) { pub(crate) fn start_new_section_from(&mut self, time: f32) {
self.current_section_peak = self.peak_strain(time - self.prev_time.unwrap()); self.current_section_peak = self.peak_strain(time - self.prev_time.unwrap());
} }
@@ -67,26 +61,14 @@ impl Skill {
self.prev_time.replace(current.base.time); self.prev_time.replace(current.base.time);
} }
pub(crate) fn difficulty_value(&mut self) -> f64 { pub(crate) fn difficulty_value(&mut self) -> f32 {
let mut difficulty = 0.0; let mut difficulty = 0.0;
let mut weight = 1.0; let mut weight = 1.0;
let reduced_section_count = 30_000 / self.section_length as usize; self.strain_peaks
.sort_unstable_by(|a, b| b.partial_cmp(a).unwrap_or(Ordering::Equal));
let peaks_iter = self for &strain in self.strain_peaks.iter() {
.strain_peaks
.sorted_non_zero_iter_mut()
.take(reduced_section_count);
for (i, strain) in peaks_iter.enumerate() {
let clamped = f64::from((i as f32 / reduced_section_count as f32).clamp(0.0, 1.0));
let scale = (lerp(1.0, 10.0, clamped)).log10();
*strain *= lerp(REDUCED_STRAIN_BASELINE, 1.0, scale);
}
self.strain_peaks.sort_desc();
for strain in self.strain_peaks.iter() {
difficulty += strain * weight; difficulty += strain * weight;
weight *= DECAY_WEIGHT; weight *= DECAY_WEIGHT;
} }
@@ -96,21 +78,21 @@ impl Skill {
difficulty difficulty
} }
pub(crate) fn count_difficult_strains(&mut self) -> f64 { pub(crate) fn count_difficult_strains(&mut self) -> f32 {
let difficulty_value = self.difficulty_value.unwrap_or(self.difficulty_value()); let difficulty_value = self.difficulty_value.unwrap_or(self.difficulty_value());
let single_strain = difficulty_value / 10.0; let single_strain = difficulty_value / 10.0;
self.object_strains self.object_strains
.iter() .iter()
.map(|strain| 1.1 / (1.0 + (-10.0 * (strain / single_strain - 0.88)).exp())) .map(|strain| 1.1 / (1.0 + (-10.0 * (strain / single_strain - 0.88)).exp()))
.sum::<f64>() .sum::<f32>()
} }
pub(crate) fn relevant_note_count(&self) -> f64 { pub(crate) fn relevant_note_count(&self) -> f32 {
self.object_strains self.object_strains
.iter() .iter()
.copied() .copied()
.max_by(f64::total_cmp) .max_by(f32::total_cmp)
.filter(|&n| n > 0.0) .filter(|&n| n > 0.0)
.map_or(0.0, |max_strain| { .map_or(0.0, |max_strain| {
self.object_strains.iter().fold(0.0, |sum, strain| { self.object_strains.iter().fold(0.0, |sum, strain| {
@@ -120,7 +102,7 @@ impl Skill {
} }
#[inline] #[inline]
fn skill_multiplier(&self) -> f64 { fn skill_multiplier(&self) -> f32 {
match self.kind { match self.kind {
SkillKind::Aim => AIM_SKILL_MULTIPLIER, SkillKind::Aim => AIM_SKILL_MULTIPLIER,
SkillKind::Speed => SPEED_SKILL_MULTIPLIER, SkillKind::Speed => SPEED_SKILL_MULTIPLIER,
@@ -128,7 +110,7 @@ impl Skill {
} }
#[inline] #[inline]
fn strain_decay_base(&self) -> f64 { fn strain_decay_base(&self) -> f32 {
match self.kind { match self.kind {
SkillKind::Aim => AIM_STRAIN_DECAY_BASE, SkillKind::Aim => AIM_STRAIN_DECAY_BASE,
SkillKind::Speed => SPEED_STRAIN_DECAY_BASE, SkillKind::Speed => SPEED_STRAIN_DECAY_BASE,
@@ -136,16 +118,12 @@ impl Skill {
} }
#[inline] #[inline]
fn peak_strain(&self, delta_time: f64) -> f64 { fn peak_strain(&self, delta_time: f32) -> f32 {
self.current_strain * self.strain_decay(delta_time) self.current_strain * self.strain_decay(delta_time)
} }
#[inline] #[inline]
fn strain_decay(&self, ms: f64) -> f64 { fn strain_decay(&self, ms: f32) -> f32 {
self.strain_decay_base().powf(ms / 1000.0) self.strain_decay_base().powf(ms / 1000.0)
} }
} }
fn lerp(start: f64, end: f64, amount: f64) -> f64 {
start + (end - start) * amount
}
+12 -14
View File
@@ -5,12 +5,12 @@ const SPEED_ANGLE_BONUS_BEGIN: f32 = 5.0 * std::f32::consts::FRAC_PI_6;
const PI_OVER_4: f32 = std::f32::consts::FRAC_PI_4; const PI_OVER_4: f32 = std::f32::consts::FRAC_PI_4;
const PI_OVER_2: f32 = std::f32::consts::FRAC_PI_2; const PI_OVER_2: f32 = std::f32::consts::FRAC_PI_2;
const MIN_SPEED_BONUS: f64 = 75.0; const MIN_SPEED_BONUS: f32 = 75.0;
const MAX_SPEED_BONUS: f64 = 45.0; const MAX_SPEED_BONUS: f32 = 45.0;
const SPEED_BALANCING_FACTOR: f32 = 40.0; const SPEED_BALANCING_FACTOR: f32 = 40.0;
const AIM_ANGLE_BONUS_BEGIN: f32 = std::f32::consts::FRAC_PI_3; const AIM_ANGLE_BONUS_BEGIN: f32 = std::f32::consts::FRAC_PI_3;
const TIMING_THRESHOLD: f64 = 107.0; const TIMING_THRESHOLD: f32 = 107.0;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub(crate) enum SkillKind { pub(crate) enum SkillKind {
@@ -19,7 +19,7 @@ pub(crate) enum SkillKind {
} }
impl SkillKind { impl SkillKind {
pub(crate) fn strain_value_of(self, current: &DifficultyObject<'_>) -> f64 { pub(crate) fn strain_value_of(self, current: &DifficultyObject<'_>) -> f32 {
match self { match self {
Self::Aim => { Self::Aim => {
if current.base.is_spinner() { if current.base.is_spinner() {
@@ -37,7 +37,7 @@ impl SkillKind {
* (current.jump_dist - scale).max(0.0)) * (current.jump_dist - scale).max(0.0))
.sqrt(); .sqrt();
result = 1.5 * f64::from(apply_diminishing_exp(angle_bonus.max(0.0))) result = 1.5 * apply_diminishing_exp(angle_bonus.max(0.0))
/ (TIMING_THRESHOLD).max(prev_strain_time) / (TIMING_THRESHOLD).max(prev_strain_time)
} }
} }
@@ -45,9 +45,8 @@ impl SkillKind {
let jump_dist_exp = apply_diminishing_exp(current.jump_dist); let jump_dist_exp = apply_diminishing_exp(current.jump_dist);
let travel_dist_exp = apply_diminishing_exp(current.travel_dist); let travel_dist_exp = apply_diminishing_exp(current.travel_dist);
let dist_exp = f64::from( let dist_exp =
jump_dist_exp + travel_dist_exp + (travel_dist_exp * jump_dist_exp).sqrt(), jump_dist_exp + travel_dist_exp + (travel_dist_exp * jump_dist_exp).sqrt();
);
(result + dist_exp / (current.strain_time).max(TIMING_THRESHOLD)) (result + dist_exp / (current.strain_time).max(TIMING_THRESHOLD))
.max(dist_exp / current.strain_time) .max(dist_exp / current.strain_time)
@@ -63,7 +62,7 @@ impl SkillKind {
let mut speed_bonus = 1.0; let mut speed_bonus = 1.0;
if delta_time < MIN_SPEED_BONUS { if delta_time < MIN_SPEED_BONUS {
let exp_base = (MIN_SPEED_BONUS - delta_time) as f32 / SPEED_BALANCING_FACTOR; let exp_base = (MIN_SPEED_BONUS - delta_time) / SPEED_BALANCING_FACTOR;
speed_bonus += exp_base * exp_base; speed_bonus += exp_base * exp_base;
} }
@@ -86,11 +85,10 @@ impl SkillKind {
} }
} }
f64::from( (1.0 + (speed_bonus - 1.0) * 0.75)
(1.0 + (speed_bonus - 1.0) * 0.75) * angle_bonus
* angle_bonus * (0.95 + speed_bonus * (dist / SINGLE_SPACING_TRESHOLD).powf(3.5))
* (0.95 + speed_bonus * (dist / SINGLE_SPACING_TRESHOLD).powf(3.5)), / current.strain_time
) / current.strain_time
} }
} }
} }
+13 -15
View File
@@ -9,10 +9,8 @@ use crate::{Beatmap, GameMods};
use rosu_map::section::hit_objects::CurveBuffers; use rosu_map::section::hit_objects::CurveBuffers;
const OBJECT_RADIUS: f32 = 64.0; const OBJECT_RADIUS: f32 = 64.0;
const SECTION_LEN: f32 = 400.0;
pub(crate) const SECTION_LEN: f64 = 400.0; const DIFFICULTY_MULTIPLIER: f32 = 0.0675;
const DIFFICULTY_MULTIPLIER: f64 = 0.0675;
const NORMALIZED_RADIUS: f32 = 52.0; const NORMALIZED_RADIUS: f32 = 52.0;
/// Star calculation for osu!standard maps. /// Star calculation for osu!standard maps.
@@ -46,7 +44,7 @@ pub fn stars(
return diff_attributes; return diff_attributes;
} }
let section_len = SECTION_LEN * map_attributes.clock_rate; let section_len = SECTION_LEN * map_attributes.clock_rate as f32;
let radius = OBJECT_RADIUS * (1.0 - 0.7 * (map_attributes.cs as f32 - 5.0) / 5.0) / 2.0; let radius = OBJECT_RADIUS * (1.0 - 0.7 * (map_attributes.cs as f32 - 5.0) / 5.0) / 2.0;
let mut scaling_factor = NORMALIZED_RADIUS / radius; let mut scaling_factor = NORMALIZED_RADIUS / radius;
@@ -70,12 +68,12 @@ pub fn stars(
)) ))
}); });
let mut aim = Skill::new(SkillKind::Aim, section_len); let mut aim = Skill::new(SkillKind::Aim);
let mut speed = Skill::new(SkillKind::Speed, section_len); let mut speed = Skill::new(SkillKind::Speed);
// First object has no predecessor and thus no strain, handle distinctly // First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end = let mut current_section_end =
(map.hit_objects[0].start_time / section_len).ceil() * section_len; (map.hit_objects[0].start_time as f32 / section_len).ceil() * section_len;
let mut prev_prev = None; let mut prev_prev = None;
let mut prev = hit_objects.next().unwrap(); let mut prev = hit_objects.next().unwrap();
@@ -88,11 +86,11 @@ pub fn stars(
&prev, &prev,
prev_vals, prev_vals,
prev_prev, prev_prev,
map_attributes.clock_rate, map_attributes.clock_rate as f32,
scaling_factor, scaling_factor,
); );
while h.base.time > current_section_end { while h.base.time as f32 > current_section_end {
current_section_end += section_len; current_section_end += section_len;
} }
@@ -110,11 +108,11 @@ pub fn stars(
&prev, &prev,
prev_vals, prev_vals,
prev_prev, prev_prev,
map_attributes.clock_rate, map_attributes.clock_rate as f32,
scaling_factor, scaling_factor,
); );
while h.base.time > current_section_end { while h.base.time as f32 > current_section_end {
aim.save_current_peak(); aim.save_current_peak();
aim.start_new_section_from(current_section_end); aim.start_new_section_from(current_section_end);
speed.save_current_peak(); speed.save_current_peak();
@@ -167,11 +165,11 @@ pub struct OsuDifficultyAttributes {
pub n_spinners: usize, pub n_spinners: usize,
pub stars: f64, pub stars: f64,
pub max_combo: usize, pub max_combo: usize,
pub aim_difficult_strain_count: f64, pub aim_difficult_strain_count: f32,
pub speed_difficult_strain_count: f64, pub speed_difficult_strain_count: f32,
pub beatmap_id: i32, pub beatmap_id: i32,
pub beatmap_creator: String, pub beatmap_creator: String,
pub speed_note_count: f64, pub speed_note_count: f32,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]