minor cleanup for osu_fast
This commit is contained in:
+23
-85
@@ -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
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user