fix: adjust mania converts

This commit is contained in:
MaxOhn
2024-10-11 16:06:32 +02:00
committed by tsunyoku
parent 705f3f8c9c
commit 6fb753cd9c
4 changed files with 35 additions and 34 deletions
+24 -25
View File
@@ -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,22 +189,27 @@ 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
}
+3 -3
View File
@@ -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,
+1 -1
View File
@@ -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,
@@ -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;