restructured StarResult to unify modes
This commit is contained in:
+9
-2
@@ -34,7 +34,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
|
||||
let take = passed_objects.unwrap_or_else(|| map.hit_objects.len());
|
||||
|
||||
if take < 2 {
|
||||
return StarResult::Taiko { stars: 0.0 };
|
||||
return StarResult::Taiko(DifficultyAttributes { stars: 0.0 });
|
||||
}
|
||||
|
||||
// True if the object at that index is stamina cheese
|
||||
@@ -114,7 +114,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> S
|
||||
|
||||
let stars = rescale(1.4 * separate_rating + 0.5 * combined_rating);
|
||||
|
||||
StarResult::Taiko { stars }
|
||||
StarResult::Taiko(DifficultyAttributes { stars })
|
||||
}
|
||||
|
||||
/// Essentially the same as the `stars` function but instead of
|
||||
@@ -257,6 +257,13 @@ fn norm(p: f32, a: f32, b: f32, c: f32) -> f32 {
|
||||
(a.powf(p) + b.powf(p) + c.powf(p)).powf(p.recip())
|
||||
}
|
||||
|
||||
/// Various data created through the star calculation.
|
||||
/// This data is necessary to calculate PP.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct DifficultyAttributes {
|
||||
pub stars: f32,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
+29
-9
@@ -1,3 +1,4 @@
|
||||
use super::{stars, DifficultyAttributes};
|
||||
use crate::{Beatmap, Mods, PpResult, StarResult};
|
||||
|
||||
pub trait TaikoStarProvider {
|
||||
@@ -10,10 +11,16 @@ impl TaikoStarProvider for f32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl TaikoStarProvider for DifficultyAttributes {
|
||||
fn attributes(self) -> Option<f32> {
|
||||
Some(self.stars)
|
||||
}
|
||||
}
|
||||
|
||||
impl TaikoStarProvider for StarResult {
|
||||
fn attributes(self) -> Option<f32> {
|
||||
if let StarResult::Taiko { stars } = self {
|
||||
Some(stars)
|
||||
if let StarResult::Taiko(attributes) = self {
|
||||
Some(attributes.stars)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -38,7 +45,6 @@ pub struct TaikoPP<'m> {
|
||||
passed_objects: Option<usize>,
|
||||
}
|
||||
|
||||
// TODO: n300 & n100
|
||||
impl<'m> TaikoPP<'m> {
|
||||
#[inline]
|
||||
pub fn new(map: &'m Beatmap) -> Self {
|
||||
@@ -57,13 +63,13 @@ impl<'m> TaikoPP<'m> {
|
||||
}
|
||||
|
||||
/// [`TaikoStarProvider`] is implemented by `f32`, [`StarResult`](crate::StarResult),
|
||||
/// and by [`PpResult`](crate::PpResult) meaning you can give the
|
||||
/// result of a star calculation or a pp calculation.
|
||||
/// and by [`PpResult`](crate::PpResult) meaning you can give the star rating,
|
||||
/// the result of a star calculation, or the result of a pp calculation.
|
||||
/// If you already calculated the stars for the current map-mod combination,
|
||||
/// be sure to put them in here so that they don't have to be recalculated.
|
||||
#[inline]
|
||||
pub fn stars(mut self, stars: impl TaikoStarProvider) -> Self {
|
||||
if let Some(stars) = stars.attributes() {
|
||||
pub fn attributes(mut self, attributes: impl TaikoStarProvider) -> Self {
|
||||
if let Some(stars) = attributes.attributes() {
|
||||
self.stars.replace(stars);
|
||||
}
|
||||
|
||||
@@ -88,6 +94,20 @@ impl<'m> TaikoPP<'m> {
|
||||
self
|
||||
}
|
||||
|
||||
/// osu!taiko pp calculation does not require specific hit results, but only accuracy.
|
||||
/// If the accuracy is already available, provide it through the `accuracy` method,
|
||||
/// otherwise use this method to calculate and set the accuracy through the hit results.
|
||||
#[inline]
|
||||
pub fn hit_results(mut self, n300: usize, n100: usize, misses: usize) -> Self {
|
||||
let hits = 2 * n300 + n100;
|
||||
let acc = hits as f32 / (hits + misses) as f32;
|
||||
|
||||
self.acc = acc;
|
||||
self.n_misses = misses;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify the amount of misses of the play.
|
||||
#[inline]
|
||||
pub fn misses(mut self, n_misses: usize) -> Self {
|
||||
@@ -116,7 +136,7 @@ impl<'m> TaikoPP<'m> {
|
||||
pub fn calculate(self) -> PpResult {
|
||||
let stars = self
|
||||
.stars
|
||||
.unwrap_or_else(|| super::stars(self.map, self.mods, self.passed_objects).stars());
|
||||
.unwrap_or_else(|| stars(self.map, self.mods, self.passed_objects).stars());
|
||||
|
||||
let mut multiplier = 1.1;
|
||||
|
||||
@@ -135,7 +155,7 @@ impl<'m> TaikoPP<'m> {
|
||||
|
||||
PpResult {
|
||||
pp,
|
||||
attributes: StarResult::Taiko { stars },
|
||||
attributes: StarResult::Taiko(DifficultyAttributes { stars }),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user