updated osu tests & more bugfixing for osu

This commit is contained in:
MaxOhn
2021-07-24 18:18:18 +02:00
parent 9ffd6ad1b6
commit 61620d6b25
11 changed files with 186 additions and 270 deletions
+3 -4
View File
@@ -334,7 +334,7 @@ impl<'m> OsuPP<'m> {
}
// AR bonus
let mut ar_factor = if attributes.ar > 10.33 {
let ar_factor = if attributes.ar > 10.33 {
attributes.ar - 10.33
} else if attributes.ar < 8.0 {
0.025 * (8.0 - attributes.ar)
@@ -343,8 +343,7 @@ impl<'m> OsuPP<'m> {
};
let ar_total_hits_factor = (1.0 + (-(0.007 * (total_hits - 400.0))).exp()).recip();
ar_factor *= 1.0 + (0.03 + 0.37 * ar_total_hits_factor) * ar_factor;
let ar_bonus = 1.0 + (0.03 + 0.37 * ar_total_hits_factor) * ar_factor;
// HD bonus
if self.mods.hd() {
@@ -360,7 +359,7 @@ impl<'m> OsuPP<'m> {
1.0
};
aim_value *= ar_factor.max(fl_bonus);
aim_value *= ar_bonus.max(fl_bonus);
// Scale with accuracy
aim_value *= 0.5 + self.acc.unwrap() / 2.0;
@@ -18,10 +18,9 @@ impl<'h> DifficultyObject<'h> {
prev: &OsuObject,
prev_vals: Option<(f32, f32)>, // (jump_dist, strain_time)
prev_prev: Option<OsuObject>,
clock_rate: f32,
scaling_factor: f32,
) -> Self {
let delta = (base.time - prev.time) / clock_rate;
let delta = base.time - prev.time;
let strain_time = delta.max(50.0);
let pos = base.pos; // stacked position
+47 -82
View File
@@ -62,8 +62,6 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
}
let time_preempt = difficulty_range_ar(raw_ar);
let section_len = SECTION_LEN * map_attributes.clock_rate;
let scale = (1.0 - 0.7 * (map_attributes.cs - 5.0) / 5.0) / 2.0;
let radius = OBJECT_RADIUS * scale;
let mut scaling_factor = NORMALIZED_RADIUS / radius;
@@ -76,23 +74,21 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
let mut slider_state = SliderState::new(map);
let mut ticks_buf = Vec::new();
let mut hit_objects: Vec<_> = map
.hit_objects
.iter()
.take(take)
.filter_map(|h| {
OsuObject::new(
h,
map,
radius,
scaling_factor,
hr,
&mut ticks_buf,
&mut diff_attributes,
&mut slider_state,
)
})
.collect();
let hit_objects_iter = map.hit_objects.iter().take(take).filter_map(|h| {
OsuObject::new(
h,
map,
radius,
scaling_factor,
hr,
&mut ticks_buf,
&mut diff_attributes,
&mut slider_state,
)
});
let mut hit_objects = Vec::with_capacity(take);
hit_objects.extend(hit_objects_iter);
let stack_threshold = time_preempt * map.stack_leniency;
@@ -107,6 +103,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
let mut hit_objects = hit_objects.into_iter().map(|mut h| {
let stack_offset = h.stack_height * scale_factor;
h.time /= map_attributes.clock_rate;
h.pos += Pos2 {
x: stack_offset,
y: stack_offset,
@@ -118,27 +115,19 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
let mut aim = Skill::new(SkillKind::Aim);
let mut speed = Skill::new(SkillKind::Speed);
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end =
(map.hit_objects[0].start_time / section_len).ceil() * section_len;
let mut prev_prev = None;
let mut prev = hit_objects.next().unwrap();
let mut prev_vals = None;
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end = (prev.time / SECTION_LEN).ceil() * SECTION_LEN;
// Handle second object separately to remove later if-branching
let curr = hit_objects.next().unwrap();
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -150,14 +139,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
// Handle all other objects
for curr in hit_objects {
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
aim.save_current_peak();
@@ -165,7 +147,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
speed.save_current_peak();
speed.start_new_section_from(current_section_end);
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -222,8 +204,6 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
}
let time_preempt = difficulty_range_ar(raw_ar);
let section_len = SECTION_LEN * map_attributes.clock_rate;
let scale = (1.0 - 0.7 * (map_attributes.cs - 5.0) / 5.0) / 2.0;
let radius = OBJECT_RADIUS * scale;
let mut scaling_factor = NORMALIZED_RADIUS / radius;
@@ -236,22 +216,21 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
let mut slider_state = SliderState::new(map);
let mut ticks_buf = Vec::new();
let mut hit_objects: Vec<_> = map
.hit_objects
.iter()
.filter_map(|h| {
OsuObject::new(
h,
map,
radius,
scaling_factor,
hr,
&mut ticks_buf,
&mut diff_attributes,
&mut slider_state,
)
})
.collect();
let hit_objects_iter = map.hit_objects.iter().filter_map(|h| {
OsuObject::new(
h,
map,
radius,
scaling_factor,
hr,
&mut ticks_buf,
&mut diff_attributes,
&mut slider_state,
)
});
let mut hit_objects = Vec::with_capacity(map.hit_objects.len());
hit_objects.extend(hit_objects_iter);
let stack_threshold = time_preempt * map.stack_leniency;
@@ -266,6 +245,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
let mut hit_objects = hit_objects.into_iter().map(|mut h| {
let stack_offset = h.stack_height * scale_factor;
h.time /= map_attributes.clock_rate;
h.pos += Pos2 {
x: stack_offset,
y: stack_offset,
@@ -277,27 +257,19 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
let mut aim = Skill::new(SkillKind::Aim);
let mut speed = Skill::new(SkillKind::Speed);
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end =
(map.hit_objects[0].start_time / section_len).ceil() * section_len;
let mut prev_prev = None;
let mut prev = hit_objects.next().unwrap();
let mut prev_vals = None;
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end = (prev.time / SECTION_LEN).ceil() * SECTION_LEN;
// Handle second object separately to remove later if-branching
let curr = hit_objects.next().unwrap();
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -309,14 +281,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
// Handle all other objects
for curr in hit_objects {
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
aim.save_current_peak();
@@ -324,7 +289,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
speed.save_current_peak();
speed.start_new_section_from(current_section_end);
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -346,7 +311,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
.collect();
Strains {
section_length: section_len,
section_length: SECTION_LEN,
strains,
}
}
@@ -18,10 +18,9 @@ impl<'h> DifficultyObject<'h> {
prev: &OsuObject,
prev_vals: Option<(f32, f32)>, // (jump_dist, strain_time)
prev_prev: Option<OsuObject>,
clock_rate: f32,
scaling_factor: f32,
) -> Self {
let delta = (base.time - prev.time) / clock_rate;
let delta = base.time - prev.time;
let strain_time = delta.max(50.0);
let pos = base.pos;
+35 -58
View File
@@ -52,7 +52,6 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
return StarResult::Osu(diff_attributes);
}
let section_len = SECTION_LEN * map_attributes.clock_rate;
let radius = OBJECT_RADIUS * (1.0 - 0.7 * (map_attributes.cs - 5.0) / 5.0) / 2.0;
let mut scaling_factor = NORMALIZED_RADIUS / radius;
@@ -64,42 +63,43 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
let mut slider_state = SliderState::new(map);
let mut ticks_buf = Vec::new();
let mut hit_objects = map.hit_objects.iter().take(take).filter_map(|h| {
OsuObject::new(
h,
map,
radius,
scaling_factor,
&mut ticks_buf,
&mut diff_attributes,
&mut slider_state,
)
});
let mut hit_objects = map
.hit_objects
.iter()
.take(take)
.filter_map(|h| {
OsuObject::new(
h,
map,
radius,
scaling_factor,
&mut ticks_buf,
&mut diff_attributes,
&mut slider_state,
)
})
.map(|mut h| {
h.time /= map_attributes.clock_rate;
h
});
let mut aim = Skill::new(SkillKind::Aim);
let mut speed = Skill::new(SkillKind::Speed);
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end =
(map.hit_objects[0].start_time / section_len).ceil() * section_len;
let mut prev_prev = None;
let mut prev = hit_objects.next().unwrap();
let mut prev_vals = None;
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end = (prev.time / SECTION_LEN).ceil() * SECTION_LEN;
// Handle second object separately to remove later if-branching
let curr = hit_objects.next().unwrap();
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -111,14 +111,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
// Handle all other objects
for curr in hit_objects {
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
aim.save_current_peak();
@@ -126,7 +119,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
speed.save_current_peak();
speed.start_new_section_from(current_section_end);
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -173,7 +166,6 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
return Strains::default();
}
let section_len = SECTION_LEN * map_attributes.clock_rate;
let radius = OBJECT_RADIUS * (1.0 - 0.7 * (map_attributes.cs - 5.0) / 5.0) / 2.0;
let mut scaling_factor = NORMALIZED_RADIUS / radius;
@@ -200,27 +192,19 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
let mut aim = Skill::new(SkillKind::Aim);
let mut speed = Skill::new(SkillKind::Speed);
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end =
(map.hit_objects[0].start_time / section_len).ceil() * section_len;
let mut prev_prev = None;
let mut prev = hit_objects.next().unwrap();
let mut prev_vals = None;
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end = (prev.time / SECTION_LEN).ceil() * SECTION_LEN;
// Handle second object separately to remove later if-branching
let curr = hit_objects.next().unwrap();
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -232,14 +216,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
// Handle all other objects
for curr in hit_objects {
let h = DifficultyObject::new(
&curr,
&prev,
prev_vals,
prev_prev,
map_attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.time > current_section_end {
aim.save_current_peak();
@@ -247,7 +224,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
speed.save_current_peak();
speed.start_new_section_from(current_section_end);
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -269,7 +246,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
.collect();
Strains {
section_length: section_len,
section_length: SECTION_LEN,
strains,
}
}
@@ -1,9 +1,7 @@
use crate::parse::HitObject;
use std::borrow::Cow;
use super::OsuObject;
pub(crate) struct DifficultyObject<'h> {
pub(crate) base: &'h HitObject,
pub(crate) base: &'h OsuObject,
pub(crate) prev: Option<(f32, f32)>, // (jump_dist, strain_time)
pub(crate) jump_dist: f32,
@@ -15,17 +13,16 @@ pub(crate) struct DifficultyObject<'h> {
impl<'h> DifficultyObject<'h> {
pub(crate) fn new(
base: &'h HitObject,
prev: &HitObject,
base: &'h OsuObject,
prev: &OsuObject,
prev_vals: Option<(f32, f32)>, // (jump_dist, strain_time)
prev_prev: Option<Cow<HitObject>>,
clock_rate: f32,
prev_prev: Option<OsuObject>,
scaling_factor: f32,
) -> Self {
let delta = (base.start_time - prev.start_time) / clock_rate;
let delta = base.time - prev.time;
let strain_time = delta.max(50.0);
let jump_dist = if base.is_spinner() {
let jump_dist = if base.is_spinner {
0.0
} else {
((base.pos - prev.pos) * scaling_factor).length()
+35 -73
View File
@@ -7,21 +7,18 @@
use super::super::DifficultyAttributes;
mod difficulty_object;
mod osu_object;
mod skill;
mod skill_kind;
mod slider_state;
use difficulty_object::DifficultyObject;
use osu_object::OsuObject;
use skill::Skill;
use skill_kind::SkillKind;
use slider_state::SliderState;
use crate::{
parse::{HitObject, HitObjectKind},
Beatmap, Mods, StarResult, Strains,
};
use std::borrow::Cow;
use crate::{parse::HitObjectKind, Beatmap, Mods, StarResult, Strains};
const OBJECT_RADIUS: f32 = 64.0;
const SECTION_LEN: f32 = 400.0;
@@ -50,7 +47,6 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
});
}
let section_len = SECTION_LEN * attributes.clock_rate;
let radius = OBJECT_RADIUS * (1.0 - 0.7 * (attributes.cs - 5.0) / 5.0) / 2.0;
let mut scaling_factor = NORMALIZED_RADIUS / radius;
@@ -59,6 +55,8 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
scaling_factor *= 1.0 + small_circle_bonus;
}
let clock_rate = attributes.clock_rate;
let mut max_combo = 0;
let mut state = SliderState::new(&map);
@@ -70,24 +68,19 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
HitObjectKind::Circle => {
max_combo += 1;
Some(Cow::Borrowed(h))
Some(OsuObject::new(h.pos, h.start_time, false, clock_rate))
}
HitObjectKind::Slider {
pixel_len, repeats, ..
} => {
max_combo += state.count_ticks(h.start_time, *pixel_len, *repeats, &map);
Some(Cow::Owned(HitObject {
pos: h.pos,
start_time: h.start_time,
kind: HitObjectKind::Circle,
sound: h.sound,
}))
Some(OsuObject::new(h.pos, h.start_time, false, clock_rate))
}
HitObjectKind::Spinner { .. } => {
max_combo += 1;
Some(Cow::Borrowed(h))
Some(OsuObject::new(h.pos, h.start_time, true, clock_rate))
}
HitObjectKind::Hold { .. } => None,
});
@@ -95,27 +88,19 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
let mut aim = Skill::new(SkillKind::Aim);
let mut speed = Skill::new(SkillKind::Speed);
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end =
(map.hit_objects[0].start_time / section_len).ceil() * section_len;
let mut prev_prev = None;
let mut prev = hit_objects.next().unwrap();
let mut prev_vals = None;
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end = (prev.time / SECTION_LEN).ceil() * SECTION_LEN;
// Handle second object separately to remove later if-branching
let curr = hit_objects.next().unwrap();
let h = DifficultyObject::new(
curr.as_ref(),
prev.as_ref(),
prev_vals,
prev_prev,
attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.start_time > current_section_end {
current_section_end += section_len;
while h.base.time > current_section_end {
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -127,22 +112,15 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
// Handle all other objects
for curr in hit_objects {
let h = DifficultyObject::new(
curr.as_ref(),
prev.as_ref(),
prev_vals,
prev_prev,
attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.start_time > current_section_end {
while h.base.time > current_section_end {
aim.save_current_peak();
aim.start_new_section_from(current_section_end);
speed.save_current_peak();
speed.start_new_section_from(current_section_end);
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -184,7 +162,6 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
return Strains::default();
}
let section_len = SECTION_LEN * attributes.clock_rate;
let radius = OBJECT_RADIUS * (1.0 - 0.7 * (attributes.cs - 5.0) / 5.0) / 2.0;
let mut scaling_factor = NORMALIZED_RADIUS / radius;
@@ -193,42 +170,34 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
scaling_factor *= 1.0 + small_circle_bonus;
}
let clock_rate = attributes.clock_rate;
let mut hit_objects = map.hit_objects.iter().filter_map(|h| match &h.kind {
HitObjectKind::Circle => Some(Cow::Borrowed(h)),
HitObjectKind::Slider { .. } => Some(Cow::Owned(HitObject {
pos: h.pos,
start_time: h.start_time,
kind: HitObjectKind::Circle,
sound: h.sound,
})),
HitObjectKind::Spinner { .. } => Some(Cow::Borrowed(h)),
HitObjectKind::Circle | HitObjectKind::Slider { .. } => {
Some(OsuObject::new(h.pos, h.start_time, false, clock_rate))
}
HitObjectKind::Spinner { .. } => {
Some(OsuObject::new(h.pos, h.start_time, true, clock_rate))
}
HitObjectKind::Hold { .. } => None,
});
let mut aim = Skill::new(SkillKind::Aim);
let mut speed = Skill::new(SkillKind::Speed);
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end =
(map.hit_objects[0].start_time / section_len).ceil() * section_len;
let mut prev_prev = None;
let mut prev = hit_objects.next().unwrap();
let mut prev_vals = None;
// First object has no predecessor and thus no strain, handle distinctly
let mut current_section_end = (prev.time / SECTION_LEN).ceil() * SECTION_LEN;
// Handle second object separately to remove later if-branching
let curr = hit_objects.next().unwrap();
let h = DifficultyObject::new(
curr.as_ref(),
prev.as_ref(),
prev_vals,
prev_prev,
attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.start_time > current_section_end {
current_section_end += section_len;
while h.base.time > current_section_end {
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -240,22 +209,15 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
// Handle all other objects
for curr in hit_objects {
let h = DifficultyObject::new(
curr.as_ref(),
prev.as_ref(),
prev_vals,
prev_prev,
attributes.clock_rate,
scaling_factor,
);
let h = DifficultyObject::new(&curr, &prev, prev_vals, prev_prev, scaling_factor);
while h.base.start_time > current_section_end {
while h.base.time > current_section_end {
aim.save_current_peak();
aim.start_new_section_from(current_section_end);
speed.save_current_peak();
speed.start_new_section_from(current_section_end);
current_section_end += section_len;
current_section_end += SECTION_LEN;
}
aim.process(&h);
@@ -277,7 +239,7 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
.collect();
Strains {
section_length: section_len,
section_length: SECTION_LEN,
strains,
}
}
@@ -0,0 +1,18 @@
use crate::parse::Pos2;
pub(crate) struct OsuObject {
pub(crate) pos: Pos2,
pub(crate) time: f32,
pub(crate) is_spinner: bool,
}
impl OsuObject {
#[inline]
pub(crate) fn new(pos: Pos2, time: f32, is_spinner: bool, clock_rate: f32) -> Self {
Self {
pos,
time: time / clock_rate,
is_spinner,
}
}
}
@@ -52,7 +52,7 @@ impl Skill {
self.current_strain *= self.strain_decay(current.delta);
self.current_strain += self.kind.strain_value_of(&current) * self.skill_multiplier();
self.current_section_peak = self.current_section_peak.max(self.current_strain);
self.prev_time.replace(current.base.start_time);
self.prev_time.replace(current.base.time);
}
pub(crate) fn difficulty_value(&mut self) -> f32 {
@@ -28,7 +28,7 @@ impl SkillKind {
pub(crate) fn strain_value_of(self, current: &DifficultyObject) -> f32 {
match self {
Self::Aim => {
if current.base.is_spinner() {
if current.base.is_spinner {
return 0.0;
}
@@ -54,7 +54,7 @@ impl SkillKind {
.max(jump_dist_exp / current.strain_time)
}
Self::Speed => {
if current.base.is_spinner() {
if current.base.is_spinner {
return 0.0;
}
+36 -36
View File
@@ -128,111 +128,111 @@ const RESULTS: &[MapResult] = &[
MapResult {
map_id: 1851299,
mods: 256,
stars: 4.23514130038547,
pp: 96.59532540603362,
stars: 4.19951953364192,
pp: 95.35544846090738,
},
MapResult {
map_id: 1851299,
mods: 0,
stars: 5.356786475158158,
pp: 191.72186087468594,
stars: 5.305946555352317,
pp: 188.7611225698759,
},
MapResult {
map_id: 1851299,
mods: 8,
stars: 5.356786475158158,
pp: 211.17333597663404,
stars: 5.305946555352317,
pp: 207.87782991080368,
},
MapResult {
map_id: 1851299,
mods: 64,
stars: 7.450616908751305,
pp: 476.39199443787675,
stars: 7.352573837272898,
pp: 465.60165096277717,
},
MapResult {
map_id: 1851299,
mods: 16,
stars: 5.6834681957637665,
pp: 243.32730989490153,
stars: 5.628029058321052,
pp: 239.33966091681467,
},
MapResult {
map_id: 1851299,
mods: 2,
stars: 4.937817303399699,
pp: 110.44350158714633,
stars: 4.892665488817249,
pp: 108.66545494037493,
},
// -----
MapResult {
map_id: 70090,
mods: 256,
stars: 2.2929922580201803,
pp: 17.530571082228978,
stars: 2.2531214736733975,
pp: 17.064864347414005,
},
MapResult {
map_id: 70090,
mods: 0,
stars: 2.8322940761833983,
pp: 40.611760049886534,
stars: 2.7853401027561353,
pp: 39.80360462535964,
},
MapResult {
map_id: 70090,
mods: 8,
stars: 2.8322940761833983,
pp: 46.252172598153074,
stars: 2.7853401027561353,
pp: 45.27724541951056,
},
MapResult {
map_id: 70090,
mods: 64,
stars: 3.8338563325375485,
pp: 110.32389105793393,
stars: 3.7775299223395877,
pp: 108.27132697867293,
},
MapResult {
map_id: 70090,
mods: 16,
stars: 3.0617492228478174,
pp: 84.67846960014381,
stars: 3.0128373294988626,
pp: 83.70428900396428,
},
MapResult {
map_id: 70090,
mods: 2,
stars: 2.698823231324141,
pp: 21.861918597227252,
stars: 2.673167484837261,
pp: 21.254867316318986,
},
// -----
MapResult {
map_id: 1241370,
mods: 256,
stars: 5.662809600985943,
pp: 346.1069865511771,
stars: 5.558026586611704,
pp: 334.51647189180727,
},
MapResult {
map_id: 1241370,
mods: 0,
stars: 7.0367002127481975,
pp: 658.4944314112954,
stars: 6.983848076867755,
pp: 649.1653315906666,
},
MapResult {
map_id: 1241370,
mods: 8,
stars: 7.0367002127481975,
pp: 720.8614284211293,
stars: 6.983848076867755,
pp: 710.594432790455,
},
MapResult {
map_id: 1241370,
mods: 64,
stars: 11.144720506574934,
pp: 2414.665180655108,
stars: 11.076248857241552,
pp: 2378.593642686663,
},
MapResult {
map_id: 1241370,
mods: 16,
stars: 7.641688110458715,
pp: 853.7411405318841,
stars: 7.616427878599069,
pp: 843.421001465897,
},
MapResult {
map_id: 1241370,
mods: 2,
stars: 6.316288616688052,
pp: 357.3089261481221,
stars: 6.289772601786212,
pp: 354.960619132034,
},
];