sort nested objects

This commit is contained in:
MaxOhn
2024-02-14 15:27:24 +01:00
parent e99c134a5b
commit 47dd020bfc
2 changed files with 50 additions and 28 deletions
+1 -5
View File
@@ -121,11 +121,7 @@ impl<'a> OsuDifficultyObject<'a> {
self.min_jump_time = self.min_jump_time =
(self.strain_time - last_travel_time).max(OsuDifficultyObject::MIN_DELTA_TIME); (self.strain_time - last_travel_time).max(OsuDifficultyObject::MIN_DELTA_TIME);
let tail_pos = last_slider let tail_pos = last_slider.tail().map_or(last_object.pos, |tail| tail.pos);
.nested_objects
.last()
.map_or(last_object.pos, |nested| nested.pos);
let stacked_tail_pos = tail_pos + last_object.stack_offset; let stacked_tail_pos = tail_pos + last_object.stack_offset;
let tail_jump_dist = let tail_jump_dist =
+49 -23
View File
@@ -65,22 +65,30 @@ impl OsuObject {
let mut nested_iter = slider.nested_objects.iter_mut(); let mut nested_iter = slider.nested_objects.iter_mut();
// The tail is adjusted differently than ticks and repeats for nested in nested_iter.by_ref() {
if let Some(tail) = nested_iter.next_back() { // The tail is adjusted differently than ticks and repeats
let mut tail_pos = self.pos; // already reflected at this point if let NestedSliderObjectKind::Tail = nested.kind {
tail_pos += Pos::new(tail.pos.x, -tail.pos.y); let mut tail_pos = self.pos; // already reflected at this point
tail.pos = tail_pos; tail_pos += Pos::new(nested.pos.x, -nested.pos.y);
nested.pos = tail_pos;
for nested in nested_iter { break;
reflect_y(&mut nested.pos.y);
} }
reflect_y(&mut nested.pos.y);
}
// In case the tail is not the last nested object, process the
// remaining objects
for nested in nested_iter {
reflect_y(&mut nested.pos.y);
} }
} }
} }
pub fn finalize_tail(&mut self) { pub fn finalize_tail(&mut self) {
if let OsuObjectKind::Slider(ref mut slider) = self.kind { if let OsuObjectKind::Slider(ref mut slider) = self.kind {
if let Some(tail) = slider.nested_objects.last_mut() { if let Some(tail) = slider.tail_mut() {
tail.pos += self.pos; tail.pos += self.pos;
} }
} }
@@ -102,7 +110,7 @@ impl OsuObject {
match self.kind { match self.kind {
OsuObjectKind::Circle | OsuObjectKind::Spinner(_) => self.pos, OsuObjectKind::Circle | OsuObjectKind::Spinner(_) => self.pos,
OsuObjectKind::Slider(ref slider) => { OsuObjectKind::Slider(ref slider) => {
slider.nested_objects[slider.nested_objects.len() - 1].pos slider.tail().map_or(Pos::default(), |nested| nested.pos)
} }
} }
} }
@@ -114,13 +122,12 @@ impl OsuObject {
pub fn lazy_travel_time(&self) -> f64 { pub fn lazy_travel_time(&self) -> f64 {
match self.kind { match self.kind {
OsuObjectKind::Circle | OsuObjectKind::Spinner(_) => 0.0, OsuObjectKind::Circle | OsuObjectKind::Spinner(_) => 0.0,
OsuObjectKind::Slider(ref slider) => { OsuObjectKind::Slider(ref slider) => slider
slider .nested_objects
.nested_objects // Here we really want the last nested object which is not
.last() // necessarily the tail
.map_or(0.0, |nested| nested.start_time) .last()
- self.start_time .map_or(0.0, |nested| nested.start_time - self.start_time),
}
} }
} }
@@ -225,7 +232,7 @@ impl OsuSlider {
let end_path_pos = path.position_at(obj_progress_at(1.0)); let end_path_pos = path.position_at(obj_progress_at(1.0));
let nested_objects: Vec<_> = events let mut nested_objects: Vec<_> = events
.filter_map(|e| { .filter_map(|e| {
let obj = match e.kind { let obj = match e.kind {
SliderEventType::Tick => NestedSliderObject { SliderEventType::Tick => NestedSliderObject {
@@ -238,11 +245,13 @@ impl OsuSlider {
start_time: start_time + f64::from(e.span_idx + 1) * span_duration, start_time: start_time + f64::from(e.span_idx + 1) * span_duration,
kind: NestedSliderObjectKind::Repeat, kind: NestedSliderObjectKind::Repeat,
}, },
SliderEventType::LastTick => NestedSliderObject { SliderEventType::LastTick => {
pos: end_path_pos, // no `h.pos` yet to keep order of float operations NestedSliderObject {
start_time: e.time, pos: end_path_pos, // no `h.pos` yet to keep order of float operations
kind: NestedSliderObjectKind::Tail, start_time: e.time,
}, kind: NestedSliderObjectKind::Tail,
}
}
SliderEventType::Head | SliderEventType::Tail => return None, SliderEventType::Head | SliderEventType::Tail => return None,
}; };
@@ -250,6 +259,8 @@ impl OsuSlider {
}) })
.collect(); .collect();
nested_objects.sort_unstable_by(|a, b| a.start_time.total_cmp(&b.start_time));
let lazy_travel_time = nested_objects let lazy_travel_time = nested_objects
.last() .last()
.map_or(0.0, |nested| nested.start_time - h.start_time); .map_or(0.0, |nested| nested.start_time - h.start_time);
@@ -278,6 +289,22 @@ impl OsuSlider {
.filter(|nested| matches!(nested.kind, NestedSliderObjectKind::Repeat)) .filter(|nested| matches!(nested.kind, NestedSliderObjectKind::Repeat))
.count() .count()
} }
pub fn tail(&self) -> Option<&NestedSliderObject> {
self.nested_objects
.iter()
// The tail is not necessarily the last nested object, e.g. on very
// short and fast buzz sliders (/b/1001757)
.rfind(|nested| matches!(nested.kind, NestedSliderObjectKind::Tail))
}
fn tail_mut(&mut self) -> Option<&mut NestedSliderObject> {
self.nested_objects
.iter_mut()
// The tail is not necessarily the last nested object, e.g. on very
// short and fast buzz sliders (/b/1001757)
.rfind(|nested| matches!(nested.kind, NestedSliderObjectKind::Tail))
}
} }
pub struct NestedSliderObject { pub struct NestedSliderObject {
@@ -292,7 +319,6 @@ impl NestedSliderObject {
} }
} }
#[derive(Debug)]
pub enum NestedSliderObjectKind { pub enum NestedSliderObjectKind {
Repeat, Repeat,
Tail, Tail,