fix: adjust mania converts
This commit is contained in:
+24
-25
@@ -1,7 +1,4 @@
|
||||
use rosu_map::{
|
||||
section::{general::GameMode, hit_objects::CurveBuffers},
|
||||
util::Pos,
|
||||
};
|
||||
use rosu_map::{section::general::GameMode, util::Pos};
|
||||
|
||||
use crate::{
|
||||
model::{
|
||||
@@ -15,8 +12,8 @@ use crate::{
|
||||
use self::{
|
||||
pattern::Pattern,
|
||||
pattern_generator::{
|
||||
distance_object::DistanceObjectPatternGenerator,
|
||||
end_time_object::EndTimeObjectPatternGenerator, hit_object::HitObjectPatternGenerator,
|
||||
path_object::PathObjectPatternGenerator,
|
||||
},
|
||||
pattern_type::PatternType,
|
||||
};
|
||||
@@ -76,7 +73,6 @@ fn convert(map: &mut Beatmap) {
|
||||
|
||||
let total_columns = map.cs as i32;
|
||||
let mut last_values = PrevValues::default();
|
||||
let mut curve_bufs = CurveBuffers::default();
|
||||
|
||||
// mean=668.7 | median=512
|
||||
let mut new_hit_objects = Vec::with_capacity(512);
|
||||
@@ -108,9 +104,7 @@ fn convert(map: &mut Beatmap) {
|
||||
last_values.pattern = new_pattern;
|
||||
}
|
||||
HitObjectKind::Slider(ref slider) => {
|
||||
let curve = slider.curve(GameMode::Mania, &mut curve_bufs);
|
||||
|
||||
let mut gen = DistanceObjectPatternGenerator::new(
|
||||
let mut gen = PathObjectPatternGenerator::new(
|
||||
&mut random,
|
||||
obj,
|
||||
sound,
|
||||
@@ -118,7 +112,7 @@ fn convert(map: &mut Beatmap) {
|
||||
&last_values.pattern,
|
||||
map,
|
||||
slider.repeats,
|
||||
&curve,
|
||||
slider.expected_dist,
|
||||
&slider.node_sounds,
|
||||
);
|
||||
|
||||
@@ -195,24 +189,29 @@ fn target_columns(map: &Beatmap) -> f32 {
|
||||
let rounded_cs = map.cs.round_ties_even();
|
||||
let rounded_od = map.od.round_ties_even();
|
||||
|
||||
let slider_or_spinner_count = map
|
||||
.hit_objects
|
||||
.iter()
|
||||
.filter(|h| matches!(h.kind, HitObjectKind::Slider(_) | HitObjectKind::Spinner(_)))
|
||||
.count();
|
||||
if !map.hit_objects.is_empty() {
|
||||
let count_slider_or_spinner = map
|
||||
.hit_objects
|
||||
.iter()
|
||||
.filter(|h| matches!(h.kind, HitObjectKind::Slider(_) | HitObjectKind::Spinner(_)))
|
||||
.count();
|
||||
|
||||
let len = map.hit_objects.len();
|
||||
let percent_slider_or_spinner = f64::from(slider_or_spinner_count as f32 / len as f32);
|
||||
let len = map.hit_objects.len();
|
||||
|
||||
if percent_slider_or_spinner < 0.2 {
|
||||
7.0
|
||||
} else if percent_slider_or_spinner < 0.3 || rounded_cs >= 5.0 {
|
||||
f32::from(6 + u8::from(rounded_od > 5.0))
|
||||
} else if percent_slider_or_spinner > 0.6 {
|
||||
f32::from(4 + u8::from(rounded_od > 4.0))
|
||||
} else {
|
||||
(rounded_od + 1.0).clamp(4.0, 7.0)
|
||||
// * In osu!stable, this division appears as if it happens on floats, but due to release-mode
|
||||
// * optimisations, it actually ends up happening on doubles.
|
||||
let percent_slider_or_spinner = f64::from(count_slider_or_spinner as f64 / len as f64);
|
||||
|
||||
if percent_slider_or_spinner < 0.2 {
|
||||
return 7.0;
|
||||
} else if percent_slider_or_spinner < 0.3 || rounded_cs >= 5.0 {
|
||||
return f32::from(6 + u8::from(rounded_od > 5.0));
|
||||
} else if percent_slider_or_spinner > 0.6 {
|
||||
return f32::from(4 + u8::from(rounded_od > 4.0));
|
||||
}
|
||||
}
|
||||
|
||||
((rounded_od as i32) + 1).min(7).max(4) as f32
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -5,8 +5,8 @@ use rosu_map::util::Pos;
|
||||
use crate::model::hit_object::{HitObject, HitObjectKind, HoldNote};
|
||||
|
||||
use super::pattern_generator::{
|
||||
distance_object::DistanceObjectPatternGenerator,
|
||||
end_time_object::EndTimeObjectPatternGenerator, hit_object::HitObjectPatternGenerator,
|
||||
path_object::PathObjectPatternGenerator,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -87,7 +87,7 @@ impl Pattern {
|
||||
}
|
||||
|
||||
pub fn new_slider_note(
|
||||
generator: &DistanceObjectPatternGenerator<'_>,
|
||||
generator: &PathObjectPatternGenerator<'_>,
|
||||
column: u8,
|
||||
start_time: i32,
|
||||
end_time: i32,
|
||||
@@ -118,7 +118,7 @@ impl Pattern {
|
||||
|
||||
pub fn add_slider_note(
|
||||
&mut self,
|
||||
generator: &DistanceObjectPatternGenerator<'_>,
|
||||
generator: &PathObjectPatternGenerator<'_>,
|
||||
column: u8,
|
||||
start_time: i32,
|
||||
end_time: i32,
|
||||
|
||||
@@ -4,9 +4,9 @@ use crate::{
|
||||
util::random::Random,
|
||||
};
|
||||
|
||||
pub(super) mod distance_object;
|
||||
pub(super) mod end_time_object;
|
||||
pub(super) mod hit_object;
|
||||
pub(super) mod path_object;
|
||||
|
||||
pub struct PatternGenerator<'a> {
|
||||
pub hit_object: &'a HitObject,
|
||||
|
||||
+7
-5
@@ -1,6 +1,6 @@
|
||||
use std::cmp;
|
||||
|
||||
use rosu_map::section::hit_objects::{hit_samples::HitSoundType, BorrowedCurve};
|
||||
use rosu_map::section::hit_objects::hit_samples::HitSoundType;
|
||||
|
||||
use crate::{
|
||||
mania::{
|
||||
@@ -17,7 +17,7 @@ use crate::{
|
||||
|
||||
use super::PatternGenerator;
|
||||
|
||||
pub struct DistanceObjectPatternGenerator<'h> {
|
||||
pub struct PathObjectPatternGenerator<'h> {
|
||||
pub segment_duration: i32,
|
||||
pub sample: HitSoundType,
|
||||
pub inner: PatternGenerator<'h>,
|
||||
@@ -29,7 +29,7 @@ pub struct DistanceObjectPatternGenerator<'h> {
|
||||
node_sounds: &'h [HitSoundType],
|
||||
}
|
||||
|
||||
impl<'h> DistanceObjectPatternGenerator<'h> {
|
||||
impl<'h> PathObjectPatternGenerator<'h> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
random: &'h mut Random,
|
||||
@@ -39,7 +39,7 @@ impl<'h> DistanceObjectPatternGenerator<'h> {
|
||||
prev_pattern: &'h Pattern,
|
||||
orig: &'h Beatmap,
|
||||
repeats: usize,
|
||||
curve: &BorrowedCurve<'_>,
|
||||
expected_dist: Option<f64>,
|
||||
node_sounds: &'h [HitSoundType],
|
||||
) -> Self {
|
||||
let timing_beat_len = orig
|
||||
@@ -67,9 +67,11 @@ impl<'h> DistanceObjectPatternGenerator<'h> {
|
||||
let span_count = (repeats + 1) as i32;
|
||||
let start_time = hit_object.start_time.round_ties_even() as i32;
|
||||
|
||||
let dist = expected_dist.unwrap_or(0.0);
|
||||
|
||||
// * This matches stable's calculation.
|
||||
let end_time = (f64::from(start_time)
|
||||
+ curve.dist() * beat_len * f64::from(span_count) * 0.01 / orig.slider_multiplier)
|
||||
+ dist * beat_len * f64::from(span_count) * 0.01 / orig.slider_multiplier)
|
||||
.floor() as i32;
|
||||
|
||||
let segment_duration = (end_time - start_time) / span_count;
|
||||
Reference in New Issue
Block a user