minor cleanup for osu_fast
This commit is contained in:
+23
-85
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
use self::osu_object::ObjectParameters;
|
||||||
|
|
||||||
use super::DifficultyAttributes;
|
use super::DifficultyAttributes;
|
||||||
|
|
||||||
mod difficulty_object;
|
mod difficulty_object;
|
||||||
@@ -21,7 +23,7 @@ use skill::Skill;
|
|||||||
use skill_kind::SkillKind;
|
use skill_kind::SkillKind;
|
||||||
use slider_state::SliderState;
|
use slider_state::SliderState;
|
||||||
|
|
||||||
use crate::{parse::HitObjectKind, Beatmap, Mods, Strains};
|
use crate::{Beatmap, Mods, Strains};
|
||||||
|
|
||||||
const OBJECT_RADIUS: f32 = 64.0;
|
const OBJECT_RADIUS: f32 = 64.0;
|
||||||
const SECTION_LEN: f32 = 400.0;
|
const SECTION_LEN: f32 = 400.0;
|
||||||
@@ -63,62 +65,19 @@ pub fn stars(
|
|||||||
scaling_factor *= 1.0 + small_circle_bonus;
|
scaling_factor *= 1.0 + small_circle_bonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
let clock_rate = attributes.clock_rate;
|
let mut params = ObjectParameters {
|
||||||
|
map,
|
||||||
let mut max_combo = 0;
|
radius,
|
||||||
let mut state = SliderState::new(map);
|
clock_rate: attributes.clock_rate,
|
||||||
|
max_combo: 0,
|
||||||
|
slider_state: SliderState::new(map),
|
||||||
|
};
|
||||||
|
|
||||||
let mut hit_objects = map
|
let mut hit_objects = map
|
||||||
.hit_objects
|
.hit_objects
|
||||||
.iter()
|
.iter()
|
||||||
.take(take)
|
.take(take)
|
||||||
.filter_map(|h| match &h.kind {
|
.filter_map(|h| OsuObject::new(h, &mut params));
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
let fl = mods.fl();
|
let fl = mods.fl();
|
||||||
let mut skills = Vec::with_capacity(2 + fl as usize);
|
let mut skills = Vec::with_capacity(2 + fl as usize);
|
||||||
@@ -234,7 +193,7 @@ pub fn stars(
|
|||||||
speed_strain: speed_rating,
|
speed_strain: speed_rating,
|
||||||
aim_strain: aim_rating,
|
aim_strain: aim_rating,
|
||||||
flashlight_rating,
|
flashlight_rating,
|
||||||
max_combo,
|
max_combo: params.max_combo,
|
||||||
n_circles: map.n_circles as usize,
|
n_circles: map.n_circles as usize,
|
||||||
n_spinners: map.n_spinners as usize,
|
n_spinners: map.n_spinners as usize,
|
||||||
n_sliders: map.n_sliders 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;
|
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 {
|
let mut hit_objects = map
|
||||||
HitObjectKind::Circle => Some(OsuObject::circle(h, clock_rate)),
|
.hit_objects
|
||||||
#[cfg(feature = "sliders")]
|
.iter()
|
||||||
HitObjectKind::Slider {
|
.filter_map(|h| OsuObject::new(h, &mut params));
|
||||||
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 fl = mods.fl();
|
let fl = mods.fl();
|
||||||
let mut skills = Vec::with_capacity(2 + fl as usize);
|
let mut skills = Vec::with_capacity(2 + fl as usize);
|
||||||
|
|||||||
+78
-40
@@ -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) struct OsuObject {
|
||||||
pub(crate) pos: Pos2,
|
pub(crate) pos: Pos2,
|
||||||
@@ -12,91 +17,124 @@ pub(crate) enum OsuObjectKind {
|
|||||||
Spinner,
|
Spinner,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OsuObject {
|
pub(crate) struct ObjectParameters<'a> {
|
||||||
pub(crate) fn circle(h: &HitObject, clock_rate: f32) -> Self {
|
pub(crate) map: &'a Beatmap,
|
||||||
Self {
|
pub(crate) radius: f32,
|
||||||
pos: h.pos,
|
pub(crate) clock_rate: f32,
|
||||||
time: h.start_time / clock_rate,
|
pub(crate) max_combo: usize,
|
||||||
kind: OsuObjectKind::Circle,
|
pub(crate) slider_state: SliderState<'a>,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl OsuObject {
|
||||||
|
pub(crate) fn new(h: &HitObject, params: &mut ObjectParameters<'_>) -> Option<Self> {
|
||||||
|
let time = h.start_time / params.clock_rate;
|
||||||
|
|
||||||
|
let obj = match &h.kind {
|
||||||
|
HitObjectKind::Circle => {
|
||||||
|
params.max_combo += 1;
|
||||||
|
|
||||||
|
Self::circle(h.pos, time)
|
||||||
|
}
|
||||||
#[cfg(feature = "sliders")]
|
#[cfg(feature = "sliders")]
|
||||||
pub(crate) fn slider(
|
HitObjectKind::Slider {
|
||||||
h: &HitObject,
|
pixel_len,
|
||||||
clock_rate: f32,
|
repeats,
|
||||||
radius: f32,
|
control_points,
|
||||||
repeats: usize,
|
} => {
|
||||||
pixel_len: f32,
|
let span_count = *repeats + 1;
|
||||||
control_points: &[crate::parse::PathControlPoint],
|
|
||||||
) -> Self {
|
params.max_combo += params.slider_state.count_ticks(
|
||||||
|
h.start_time,
|
||||||
|
*pixel_len,
|
||||||
|
span_count,
|
||||||
|
params.map,
|
||||||
|
);
|
||||||
|
|
||||||
match control_points.last() {
|
match control_points.last() {
|
||||||
Some(point) => {
|
Some(point) => {
|
||||||
let follow_circle_radius = radius * 3.0;
|
let follow_circle_radius = params.radius * 3.0;
|
||||||
let span_count = (repeats + 1) as f32;
|
|
||||||
|
|
||||||
let travel_dist =
|
let travel_dist = Self::approximate_travel_dist(
|
||||||
Self::approximate_travel_dist(follow_circle_radius, span_count, point.pos);
|
follow_circle_radius,
|
||||||
|
span_count as f32,
|
||||||
|
point.pos,
|
||||||
|
);
|
||||||
|
|
||||||
let mut end_pos = h.pos;
|
let mut end_pos = h.pos;
|
||||||
|
|
||||||
if repeats % 2 == 0 && pixel_len > follow_circle_radius {
|
if repeats % 2 == 0 && *pixel_len > follow_circle_radius {
|
||||||
end_pos += point.pos
|
end_pos += point.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
pos: h.pos,
|
pos: h.pos,
|
||||||
time: h.start_time / clock_rate,
|
time,
|
||||||
kind: OsuObjectKind::Slider {
|
kind: OsuObjectKind::Slider {
|
||||||
end_pos,
|
end_pos,
|
||||||
travel_dist,
|
travel_dist,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Self::circle(h, clock_rate),
|
None => Self::circle(h.pos, time),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "sliders"))]
|
#[cfg(not(feature = "sliders"))]
|
||||||
pub(crate) fn slider(
|
HitObjectKind::Slider {
|
||||||
h: &HitObject,
|
pixel_len,
|
||||||
clock_rate: f32,
|
span_count,
|
||||||
radius: f32,
|
last_control_point,
|
||||||
span_count: usize,
|
} => {
|
||||||
pixel_len: f32,
|
params.max_combo += params.slider_state.count_ticks(
|
||||||
last_control_point: Pos2,
|
h.start_time,
|
||||||
) -> Self {
|
*pixel_len,
|
||||||
let follow_circle_radius = radius * 3.0;
|
*span_count,
|
||||||
|
params.map,
|
||||||
|
);
|
||||||
|
let follow_circle_radius = params.radius * 3.0;
|
||||||
|
|
||||||
let travel_dist = Self::approximate_travel_dist(
|
let travel_dist = Self::approximate_travel_dist(
|
||||||
follow_circle_radius,
|
follow_circle_radius,
|
||||||
span_count as f32,
|
*span_count as f32,
|
||||||
point.pos - h.pos,
|
*last_control_point - h.pos,
|
||||||
);
|
);
|
||||||
|
|
||||||
let end_pos = if span_count % 2 == 1 && pixel_len > follow_circle_radius {
|
let end_pos = if span_count % 2 == 1 && *pixel_len > follow_circle_radius {
|
||||||
last_control_point
|
*last_control_point
|
||||||
} else {
|
} else {
|
||||||
h.pos
|
h.pos
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
pos: h.pos,
|
pos: h.pos,
|
||||||
time: h.start_time / clock_rate,
|
time,
|
||||||
kind: OsuObjectKind::Slider {
|
kind: OsuObjectKind::Slider {
|
||||||
end_pos,
|
end_pos,
|
||||||
travel_dist,
|
travel_dist,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
HitObjectKind::Spinner { .. } => {
|
||||||
|
params.max_combo += 1;
|
||||||
|
|
||||||
pub(crate) fn spinner(h: &HitObject, clock_rate: f32) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
pos: h.pos,
|
pos: h.pos,
|
||||||
time: h.start_time / clock_rate,
|
time,
|
||||||
kind: OsuObjectKind::Spinner,
|
kind: OsuObjectKind::Spinner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
HitObjectKind::Hold { .. } => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn circle(pos: Pos2, time: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
pos,
|
||||||
|
time,
|
||||||
|
kind: OsuObjectKind::Circle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn is_slider(&self) -> bool {
|
pub(crate) fn is_slider(&self) -> bool {
|
||||||
matches!(self.kind, OsuObjectKind::Slider { .. })
|
matches!(self.kind, OsuObjectKind::Slider { .. })
|
||||||
|
|||||||
Reference in New Issue
Block a user