use the same StarResult type for all modes

This commit is contained in:
MaxOhn
2021-01-18 12:55:46 +01:00
parent aae601a91e
commit 44538a7022
11 changed files with 170 additions and 120 deletions
+9 -9
View File
@@ -11,7 +11,7 @@ use movement::Movement;
pub use pp::*;
use slider_state::SliderState;
use crate::{curve::Curve, Beatmap, HitObjectKind, Mods, PathType, Pos2};
use crate::{curve::Curve, Beatmap, HitObjectKind, Mods, PathType, Pos2, StarResult};
use std::convert::identity;
@@ -27,15 +27,13 @@ const LEGACY_LAST_TICK_OFFSET: f32 = 36.0;
///
/// 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,
passed_objects: Option<usize>,
) -> DifficultyAttributes {
pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> StarResult {
let take = passed_objects.unwrap_or_else(|| map.hit_objects.len());
if take < 2 {
return DifficultyAttributes::default();
return StarResult::Fruits {
attributes: DifficultyAttributes::default(),
};
}
let attributes = map.attributes().mods(mods);
@@ -268,14 +266,16 @@ pub fn stars(
let stars = movement.difficulty_value().sqrt() * STAR_SCALING_FACTOR;
DifficultyAttributes {
let attributes = DifficultyAttributes {
stars,
ar: attributes.ar,
n_fruits: fruits,
n_droplets: droplets,
n_tiny_droplets: tiny_droplets,
max_combo: fruits + droplets,
}
};
StarResult::Fruits { attributes }
}
fn tiny_droplet_count(
+26 -13
View File
@@ -1,5 +1,5 @@
use super::{stars, DifficultyAttributes};
use crate::{Beatmap, Mods, PpResult};
use crate::{Beatmap, Mods, PpResult, StarResult};
pub trait FruitsAttributeProvider {
fn attributes(self) -> Option<DifficultyAttributes>;
@@ -11,9 +11,9 @@ impl FruitsAttributeProvider for DifficultyAttributes {
}
}
impl FruitsAttributeProvider for PpResult {
impl FruitsAttributeProvider for StarResult {
fn attributes(self) -> Option<DifficultyAttributes> {
if let PpResult::Fruits { attributes, .. } = self {
if let Self::Fruits { attributes } = self {
Some(attributes)
} else {
None
@@ -21,6 +21,12 @@ impl FruitsAttributeProvider for PpResult {
}
}
impl FruitsAttributeProvider for PpResult {
fn attributes(self) -> Option<DifficultyAttributes> {
self.attributes.attributes()
}
}
/// Calculator for pp on osu!ctb maps.
pub struct FruitsPP<'m> {
map: &'m Beatmap,
@@ -54,8 +60,8 @@ impl<'m> FruitsPP<'m> {
}
}
/// [`FruitsAttributeProvider`] is implemented by [`DifficultyAttributes`](crate::fruits::DifficultyAttributes)
/// and by [`PpResult`](crate::PpResult) meaning you can give the
/// [`FruitsAttributeProvider`] is implemented by [`DifficultyAttributes`](crate::fruits::DifficultyAttributes),
/// [`StarResult`](crate::StarResult), and by [`PpResult`](crate::PpResult) meaning you can give the
/// result of a star calculation or a pp calculation.
/// If you already calculated the attributes for the current map-mod combination,
/// be sure to put them in here so that they don't have to be recalculated.
@@ -139,8 +145,11 @@ impl<'m> FruitsPP<'m> {
/// 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.passed_objects));
self.attributes.replace(
stars(self.map, self.mods, self.passed_objects)
.attributes()
.unwrap(),
);
}
let attributes = self.attributes.as_ref().unwrap();
@@ -163,7 +172,7 @@ impl<'m> FruitsPP<'m> {
.saturating_sub(n_droplets)
});
let n_tiny_droplet_misses = max_tiny_droplets - n_tiny_droplets;
let n_tiny_droplet_misses = max_tiny_droplets.saturating_sub(n_tiny_droplets);
self.n_fruits.replace(n_fruits);
self.n_droplets.replace(n_droplets);
@@ -176,10 +185,11 @@ impl<'m> FruitsPP<'m> {
/// Returns an object which contains the pp and [`DifficultyAttributes`](crate::fruits::DifficultyAttributes)
/// containing stars and other attributes.
pub fn calculate(mut self) -> PpResult {
let attributes = self
.attributes
.take()
.unwrap_or_else(|| stars(self.map, self.mods, self.passed_objects));
let attributes = self.attributes.take().unwrap_or_else(|| {
stars(self.map, self.mods, self.passed_objects)
.attributes()
.unwrap()
});
let stars = attributes.stars;
@@ -239,7 +249,10 @@ impl<'m> FruitsPP<'m> {
pp *= 0.9;
}
PpResult::Fruits { pp, attributes }
PpResult {
pp,
attributes: StarResult::Fruits { attributes },
}
}
#[inline]