wip osu pp update

This commit is contained in:
MaxOhn
2022-10-07 18:46:17 +02:00
parent fae3a0359c
commit 5eb8dab588
34 changed files with 2415 additions and 1931 deletions
+24 -26
View File
@@ -6,7 +6,7 @@ use crate::{
Beatmap,
};
use super::{catch_object::CatchObject, slider_state::SliderState, CatchDifficultyAttributes};
use super::{catch_object::CatchObject, CatchDifficultyAttributes};
const LEGACY_LAST_TICK_OFFSET: f64 = 36.0;
const BASE_SCORING_DISTANCE: f64 = 100.0;
@@ -18,7 +18,6 @@ pub(crate) struct FruitParams<'a> {
pub(crate) last_pos: Option<f32>,
pub(crate) last_time: f64,
pub(crate) map: &'a Beatmap,
pub(crate) slider_state: SliderState<'a>,
pub(crate) ticks: Vec<(Pos2, f64)>,
pub(crate) with_hr: bool,
}
@@ -55,31 +54,29 @@ impl FruitOrJuice {
params.last_pos = Some(h.pos.x + control_points[control_points.len() - 1].pos.x);
params.last_time = h.start_time;
// Responsible for timing point values
params.slider_state.update(h.start_time);
let timing_point = params.map.timing_point_at(h.start_time);
let difficulty_point = params
.map
.difficulty_point_at(h.start_time)
.unwrap_or_default();
let vel_factor =
BASE_SCORING_DISTANCE * params.map.slider_mult / timing_point.beat_len;
let tick_dist_factor =
BASE_SCORING_DISTANCE * params.map.slider_mult / params.map.tick_rate;
let vel = vel_factor * difficulty_point.slider_vel;
let mut tick_dist = tick_dist_factor * difficulty_point.slider_vel;
let span_count = (*repeats + 1) as f64;
let mut tick_dist = 100.0 * params.map.slider_mult / params.map.tick_rate;
if params.map.version >= 8 {
tick_dist /= (100.0 / params.slider_state.slider_velocity)
.max(10.0)
.min(1000.0)
/ 100.0;
}
// Build the curve w.r.t. the control points
let curve = Curve::new(control_points, *pixel_len, &mut params.curve_bufs);
let velocity = (BASE_SCORING_DISTANCE
* params.map.slider_mult
* params.slider_state.slider_velocity)
/ params.slider_state.beat_len;
let end_time = h.start_time + span_count * curve.dist() / velocity;
let duration = end_time - h.start_time;
let span_duration = duration / span_count;
let total_duration = span_count * curve.dist() / vel;
let span_duration = total_duration / span_count;
// * A very lenient maximum length of a slider for ticks to be generated.
// * This exists for edge cases such as /b/1573664 where the beatmap has
@@ -88,12 +85,13 @@ impl FruitOrJuice {
let len = curve.dist().min(max_len);
tick_dist = tick_dist.clamp(0.0, len);
let min_dist_from_end = velocity * 10.0;
let min_dist_from_end = vel * 10.0;
let mut curr_dist = tick_dist;
let time_add = duration * tick_dist / (*pixel_len * span_count);
let pixel_len = pixel_len.unwrap_or(0.0);
let time_add = total_duration * tick_dist / (pixel_len * span_count);
let target = *pixel_len - tick_dist / 8.0;
let target = pixel_len - tick_dist / 8.0;
let mut slider_objects = vec![(h.pos, h.start_time)];
@@ -112,7 +110,7 @@ impl FruitOrJuice {
params.attributes.n_tiny_droplets += tiny_droplet_count(
h.start_time,
time_add,
duration,
total_duration,
span_count as usize,
&params.ticks,
);
@@ -160,7 +158,7 @@ impl FruitOrJuice {
// Slider tail
let progress = (*repeats % 2 == 0) as u8 as f64;
let pos = h.pos + curve.position_at(progress);
slider_objects.push((pos, h.start_time + duration));
slider_objects.push((pos, h.start_time + total_duration));
let new_fruits = 2 + (tick_dist > 0.0) as usize * *repeats;
params.attributes.n_fruits += new_fruits;
+1 -5
View File
@@ -1,10 +1,7 @@
use std::{iter, slice::Iter};
use crate::{
catch::{
difficulty_object::DifficultyObject, slider_state::SliderState, SECTION_LENGTH,
STAR_SCALING_FACTOR,
},
catch::{difficulty_object::DifficultyObject, SECTION_LENGTH, STAR_SCALING_FACTOR},
curve::CurveBuffers,
parse::{HitObject, Pos2},
Beatmap, Mods,
@@ -179,7 +176,6 @@ impl<'map> CatchObjectIter<'map> {
last_pos: None,
last_time: 0.0,
map,
slider_state: SliderState::new(map),
ticks: Vec::new(),
with_hr: mods.hr(),
};
-3
View File
@@ -5,7 +5,6 @@ mod gradual_difficulty;
mod gradual_performance;
mod movement;
mod pp;
mod slider_state;
use catch_object::CatchObject;
use difficulty_object::DifficultyObject;
@@ -14,7 +13,6 @@ pub use gradual_difficulty::*;
pub use gradual_performance::*;
use movement::Movement;
pub use pp::*;
use slider_state::SliderState;
use crate::{catch::fruit_or_juice::FruitParams, curve::CurveBuffers, Beatmap, Mods, OsuStars};
@@ -161,7 +159,6 @@ fn calculate_movement(params: CatchStars<'_>) -> (Movement, CatchDifficultyAttri
last_pos: None,
last_time: 0.0,
map,
slider_state: SliderState::new(map),
ticks: Vec::new(), // using the same buffer for all sliders
with_hr: mods.hr(),
};
-100
View File
@@ -1,100 +0,0 @@
use crate::beatmap::{Beatmap, ControlPoint, ControlPointIter};
#[derive(Clone, Debug)]
pub(crate) struct SliderState<'p> {
control_points: ControlPointIter<'p>,
next: Option<ControlPoint>,
pub(crate) beat_len: f64,
pub(crate) slider_velocity: f64,
}
impl<'p> SliderState<'p> {
#[inline]
pub(crate) fn new(map: &'p Beatmap) -> Self {
let mut control_points = ControlPointIter::new(map);
let (beat_len, slider_velocity) = match control_points.next() {
Some(ControlPoint::Timing(point)) => (point.beat_len, 1.0),
Some(ControlPoint::Difficulty(point)) => (1000.0, point.speed_multiplier),
None => (1000.0, 1.0),
};
Self {
next: control_points.next(),
control_points,
beat_len,
slider_velocity,
}
}
#[inline]
pub(crate) fn update(&mut self, time: f64) {
while let Some(next) = self.next.as_ref().filter(|n| time >= n.time()) {
match next {
ControlPoint::Timing(point) => {
self.beat_len = point.beat_len;
self.slider_velocity = 1.0;
}
ControlPoint::Difficulty(point) => self.slider_velocity = point.speed_multiplier,
}
self.next = self.control_points.next();
}
}
}
#[cfg(test)]
mod test {
use crate::beatmap::{Beatmap, DifficultyPoint, TimingPoint};
use super::SliderState;
#[test]
fn catch_slider_state() {
let map = Beatmap {
timing_points: vec![
TimingPoint {
time: 1.0,
beat_len: 10.0,
kiai: false,
},
TimingPoint {
time: 3.0,
beat_len: 20.0,
kiai: false,
},
TimingPoint {
time: 4.0,
beat_len: 30.0,
kiai: false,
},
],
difficulty_points: vec![
DifficultyPoint {
time: 2.0,
speed_multiplier: 15.0,
kiai: false,
},
DifficultyPoint {
time: 5.0,
speed_multiplier: 45.0,
kiai: false,
},
],
..Default::default()
};
let mut state = SliderState::new(&map);
state.update(2.0);
assert!((state.beat_len - 10.0).abs() <= f64::EPSILON);
state.update(3.0);
assert!((state.beat_len - 20.0).abs() <= f64::EPSILON);
assert!((state.slider_velocity - 1.0).abs() <= f64::EPSILON);
state.update(5.0);
assert!((state.beat_len - 30.0).abs() <= f64::EPSILON);
assert!((state.slider_velocity - 45.0).abs() <= f64::EPSILON);
}
}