minor cleanup for osu_fast

This commit is contained in:
MaxOhn
2021-11-09 05:22:44 +01:00
parent a01cd1f2a3
commit ab267fd648
2 changed files with 124 additions and 148 deletions
+23 -85
View File
@@ -7,6 +7,8 @@
use std::mem;
use self::osu_object::ObjectParameters;
use super::DifficultyAttributes;
mod difficulty_object;
@@ -21,7 +23,7 @@ use skill::Skill;
use skill_kind::SkillKind;
use slider_state::SliderState;
use crate::{parse::HitObjectKind, Beatmap, Mods, Strains};
use crate::{Beatmap, Mods, Strains};
const OBJECT_RADIUS: f32 = 64.0;
const SECTION_LEN: f32 = 400.0;
@@ -63,62 +65,19 @@ pub fn stars(
scaling_factor *= 1.0 + small_circle_bonus;
}
let clock_rate = attributes.clock_rate;
let mut max_combo = 0;
let mut state = SliderState::new(map);
let mut params = ObjectParameters {
map,
radius,
clock_rate: attributes.clock_rate,
max_combo: 0,
slider_state: SliderState::new(map),
};
let mut hit_objects = map
.hit_objects
.iter()
.take(take)
.filter_map(|h| match &h.kind {
HitObjectKind::Circle => {
max_combo += 1;
Some(OsuObject::circle(h, clock_rate))
}
#[cfg(feature = "sliders")]
HitObjectKind::Slider {
pixel_len,
repeats,
control_points,
} => {
max_combo += state.count_ticks(h.start_time, *pixel_len, *repeats, map);
Some(OsuObject::slider(
h,
clock_rate,
radius,
*repeats,
*pixel_len,
control_points,
))
}
#[cfg(not(feature = "sliders"))]
HitObjectKind::Slider {
pixel_len,
span_count,
last_control_point,
} => {
max_combo += state.count_ticks(h.start_time, *pixel_len, *span_count, map);
Some(OsuObject::slider(
h,
clock_rate,
radius,
*span_count,
*pixel_len,
*last_control_point,
))
}
HitObjectKind::Spinner { .. } => {
max_combo += 1;
Some(OsuObject::spinner(h, clock_rate))
}
HitObjectKind::Hold { .. } => None,
});
.filter_map(|h| OsuObject::new(h, &mut params));
let fl = mods.fl();
let mut skills = Vec::with_capacity(2 + fl as usize);
@@ -234,7 +193,7 @@ pub fn stars(
speed_strain: speed_rating,
aim_strain: aim_rating,
flashlight_rating,
max_combo,
max_combo: params.max_combo,
n_circles: map.n_circles as usize,
n_spinners: map.n_spinners as usize,
n_sliders: map.n_sliders as usize,
@@ -261,39 +220,18 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
scaling_factor *= 1.0 + small_circle_bonus;
}
let clock_rate = attributes.clock_rate;
let mut params = ObjectParameters {
map,
radius,
clock_rate: attributes.clock_rate,
max_combo: 0,
slider_state: SliderState::new(map),
};
let mut hit_objects = map.hit_objects.iter().filter_map(|h| match &h.kind {
HitObjectKind::Circle => Some(OsuObject::circle(h, clock_rate)),
#[cfg(feature = "sliders")]
HitObjectKind::Slider {
repeats,
control_points,
pixel_len,
} => Some(OsuObject::slider(
h,
clock_rate,
radius,
*repeats,
*pixel_len,
control_points,
)),
#[cfg(not(feature = "sliders"))]
HitObjectKind::Slider {
span_count,
last_control_point,
pixel_len,
} => Some(OsuObject::slider(
h,
clock_rate,
radius,
*span_count,
*pixel_len,
*last_control_point,
)),
HitObjectKind::Spinner { .. } => Some(OsuObject::spinner(h, clock_rate)),
HitObjectKind::Hold { .. } => None,
});
let mut hit_objects = map
.hit_objects
.iter()
.filter_map(|h| OsuObject::new(h, &mut params));
let fl = mods.fl();
let mut skills = Vec::with_capacity(2 + fl as usize);
+101 -63
View File
@@ -1,4 +1,9 @@
use crate::parse::{HitObject, Pos2};
use crate::{
parse::{HitObject, HitObjectKind, Pos2},
Beatmap,
};
use super::slider_state::SliderState;
pub(crate) struct OsuObject {
pub(crate) pos: Pos2,
@@ -12,89 +17,122 @@ pub(crate) enum OsuObjectKind {
Spinner,
}
pub(crate) struct ObjectParameters<'a> {
pub(crate) map: &'a Beatmap,
pub(crate) radius: f32,
pub(crate) clock_rate: f32,
pub(crate) max_combo: usize,
pub(crate) slider_state: SliderState<'a>,
}
impl OsuObject {
pub(crate) fn circle(h: &HitObject, clock_rate: f32) -> Self {
Self {
pos: h.pos,
time: h.start_time / clock_rate,
kind: OsuObjectKind::Circle,
}
}
pub(crate) fn new(h: &HitObject, params: &mut ObjectParameters<'_>) -> Option<Self> {
let time = h.start_time / params.clock_rate;
#[cfg(feature = "sliders")]
pub(crate) fn slider(
h: &HitObject,
clock_rate: f32,
radius: f32,
repeats: usize,
pixel_len: f32,
control_points: &[crate::parse::PathControlPoint],
) -> Self {
match control_points.last() {
Some(point) => {
let follow_circle_radius = radius * 3.0;
let span_count = (repeats + 1) as f32;
let obj = match &h.kind {
HitObjectKind::Circle => {
params.max_combo += 1;
let travel_dist =
Self::approximate_travel_dist(follow_circle_radius, span_count, point.pos);
Self::circle(h.pos, time)
}
#[cfg(feature = "sliders")]
HitObjectKind::Slider {
pixel_len,
repeats,
control_points,
} => {
let span_count = *repeats + 1;
let mut end_pos = h.pos;
params.max_combo += params.slider_state.count_ticks(
h.start_time,
*pixel_len,
span_count,
params.map,
);
if repeats % 2 == 0 && pixel_len > follow_circle_radius {
end_pos += point.pos
match control_points.last() {
Some(point) => {
let follow_circle_radius = params.radius * 3.0;
let travel_dist = Self::approximate_travel_dist(
follow_circle_radius,
span_count as f32,
point.pos,
);
let mut end_pos = h.pos;
if repeats % 2 == 0 && *pixel_len > follow_circle_radius {
end_pos += point.pos
}
Self {
pos: h.pos,
time,
kind: OsuObjectKind::Slider {
end_pos,
travel_dist,
},
}
}
None => Self::circle(h.pos, time),
}
}
#[cfg(not(feature = "sliders"))]
HitObjectKind::Slider {
pixel_len,
span_count,
last_control_point,
} => {
params.max_combo += params.slider_state.count_ticks(
h.start_time,
*pixel_len,
*span_count,
params.map,
);
let follow_circle_radius = params.radius * 3.0;
let travel_dist = Self::approximate_travel_dist(
follow_circle_radius,
*span_count as f32,
*last_control_point - h.pos,
);
let end_pos = if span_count % 2 == 1 && *pixel_len > follow_circle_radius {
*last_control_point
} else {
h.pos
};
Self {
pos: h.pos,
time: h.start_time / clock_rate,
time,
kind: OsuObjectKind::Slider {
end_pos,
travel_dist,
},
}
}
None => Self::circle(h, clock_rate),
}
}
HitObjectKind::Spinner { .. } => {
params.max_combo += 1;
#[cfg(not(feature = "sliders"))]
pub(crate) fn slider(
h: &HitObject,
clock_rate: f32,
radius: f32,
span_count: usize,
pixel_len: f32,
last_control_point: Pos2,
) -> Self {
let follow_circle_radius = radius * 3.0;
let travel_dist = Self::approximate_travel_dist(
follow_circle_radius,
span_count as f32,
point.pos - h.pos,
);
let end_pos = if span_count % 2 == 1 && pixel_len > follow_circle_radius {
last_control_point
} else {
h.pos
Self {
pos: h.pos,
time,
kind: OsuObjectKind::Spinner,
}
}
HitObjectKind::Hold { .. } => return None,
};
Self {
pos: h.pos,
time: h.start_time / clock_rate,
kind: OsuObjectKind::Slider {
end_pos,
travel_dist,
},
}
Some(obj)
}
pub(crate) fn spinner(h: &HitObject, clock_rate: f32) -> Self {
fn circle(pos: Pos2, time: f32) -> Self {
Self {
pos: h.pos,
time: h.start_time / clock_rate,
kind: OsuObjectKind::Spinner,
pos,
time,
kind: OsuObjectKind::Circle,
}
}