provided a way for partial plays

This commit is contained in:
MaxOhn
2021-01-17 19:43:18 +01:00
parent 12bf2f01b6
commit bbc6698fc7
13 changed files with 143 additions and 47 deletions
+11 -2
View File
@@ -24,9 +24,17 @@ const CATCHER_SIZE: f32 = 106.75;
const LEGACY_LAST_TICK_OFFSET: f32 = 36.0;
/// Star calculation for osu!ctb maps
///
/// In case of a partial play, e.g. a fail, one can specify the amount of passed objects.
// Slider parsing based on https://github.com/osufx/catch-the-pp
pub fn stars(map: &Beatmap, mods: impl Mods) -> DifficultyAttributes {
if map.hit_objects.len() < 2 {
pub fn stars(
map: &Beatmap,
mods: impl Mods,
passed_objects: Option<usize>,
) -> DifficultyAttributes {
let take = passed_objects.unwrap_or_else(|| map.hit_objects.len());
if take < 2 {
return DifficultyAttributes::default();
}
@@ -43,6 +51,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods) -> DifficultyAttributes {
let mut hit_objects = map
.hit_objects
.iter()
.take(take)
.scan((None, 0.0), |(last_pos, last_time), h| match &h.kind {
HitObjectKind::Circle => {
let mut h = CatchObject::new((h.pos, h.start_time));
+13 -3
View File
@@ -17,7 +17,6 @@ impl PpProvider for Beatmap {
}
}
// TODO: Allow partial plays
pub struct PpCalculator<'m> {
map: &'m Beatmap,
attributes: Option<DifficultyAttributes>,
@@ -29,6 +28,7 @@ pub struct PpCalculator<'m> {
n_tiny_droplets: Option<usize>,
n_tiny_droplet_misses: Option<usize>,
n_misses: usize,
passed_objects: Option<usize>,
}
impl<'m> PpCalculator<'m> {
@@ -45,6 +45,7 @@ impl<'m> PpCalculator<'m> {
n_tiny_droplets: None,
n_tiny_droplet_misses: None,
n_misses: 0,
passed_objects: None,
}
}
@@ -104,12 +105,21 @@ impl<'m> PpCalculator<'m> {
self
}
/// Amount of passed objects for partial plays, e.g. a fail.
#[inline]
pub fn passed_objects(mut self, passed_objects: usize) -> Self {
self.passed_objects.replace(passed_objects);
self
}
/// Generate the hit results with respect to the given accuracy between `0` and `100`.
///
/// Be sure to set `misses` beforehand! Also, if available, set `attributes` beforehand.
pub fn accuracy(mut self, acc: f32) -> Self {
if self.attributes.is_none() {
self.attributes.replace(stars(self.map, self.mods));
self.attributes
.replace(stars(self.map, self.mods, self.passed_objects));
}
let attributes = self.attributes.as_ref().unwrap();
@@ -146,7 +156,7 @@ impl<'m> PpCalculator<'m> {
let attributes = self
.attributes
.take()
.unwrap_or_else(|| stars(self.map, self.mods));
.unwrap_or_else(|| stars(self.map, self.mods, self.passed_objects));
let stars = attributes.stars;