slight restructing & commenting
This commit is contained in:
+30
-30
@@ -1,36 +1,6 @@
|
|||||||
use super::{stars, DifficultyAttributes};
|
use super::{stars, DifficultyAttributes};
|
||||||
use crate::{Beatmap, Mods, PpResult, StarResult};
|
use crate::{Beatmap, Mods, PpResult, StarResult};
|
||||||
|
|
||||||
pub trait FruitsAttributeProvider {
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FruitsAttributeProvider for DifficultyAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes> {
|
|
||||||
Some(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FruitsAttributeProvider for StarResult {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes> {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
if let Self::Fruits(attributes) = self {
|
|
||||||
Some(attributes)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FruitsAttributeProvider for PpResult {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes> {
|
|
||||||
self.attributes.attributes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculator for pp on osu!ctb maps.
|
/// Calculator for pp on osu!ctb maps.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct FruitsPP<'m> {
|
pub struct FruitsPP<'m> {
|
||||||
@@ -350,6 +320,36 @@ impl<'m> FruitsPP<'m> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait FruitsAttributeProvider {
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FruitsAttributeProvider for DifficultyAttributes {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FruitsAttributeProvider for StarResult {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes> {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let Self::Fruits(attributes) = self {
|
||||||
|
Some(attributes)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FruitsAttributeProvider for PpResult {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes> {
|
||||||
|
self.attributes.attributes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+36
-36
@@ -1,42 +1,6 @@
|
|||||||
use super::{stars, DifficultyAttributes};
|
use super::{stars, DifficultyAttributes};
|
||||||
use crate::{Beatmap, Mods, PpResult, StarResult};
|
use crate::{Beatmap, Mods, PpResult, StarResult};
|
||||||
|
|
||||||
pub trait ManiaAttributeProvider {
|
|
||||||
fn attributes(self) -> Option<f32>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ManiaAttributeProvider for f32 {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
Some(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ManiaAttributeProvider for DifficultyAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
Some(self.stars)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ManiaAttributeProvider for StarResult {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
if let Self::Mania(attributes) = self {
|
|
||||||
Some(attributes.stars)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ManiaAttributeProvider for PpResult {
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
self.attributes.attributes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculator for pp on osu!mania maps.
|
/// Calculator for pp on osu!mania maps.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ManiaPP<'m> {
|
pub struct ManiaPP<'m> {
|
||||||
@@ -185,3 +149,39 @@ impl<'m> ManiaPP<'m> {
|
|||||||
* ((score - 960_000.0).max(0.0) / 40_000.0).powf(1.1)
|
* ((score - 960_000.0).max(0.0) / 40_000.0).powf(1.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ManiaAttributeProvider {
|
||||||
|
fn attributes(self) -> Option<f32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ManiaAttributeProvider for f32 {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ManiaAttributeProvider for DifficultyAttributes {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
Some(self.stars)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ManiaAttributeProvider for StarResult {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let Self::Mania(attributes) = self {
|
||||||
|
Some(attributes.stars)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ManiaAttributeProvider for PpResult {
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
self.attributes.attributes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+43
-30
@@ -1,36 +1,6 @@
|
|||||||
use super::DifficultyAttributes;
|
use super::DifficultyAttributes;
|
||||||
use crate::{Beatmap, Mods, PpResult, StarResult};
|
use crate::{Beatmap, Mods, PpResult, StarResult};
|
||||||
|
|
||||||
pub trait OsuAttributeProvider {
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OsuAttributeProvider for DifficultyAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes> {
|
|
||||||
Some(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OsuAttributeProvider for StarResult {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes> {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
if let Self::Osu(attributes) = self {
|
|
||||||
Some(attributes)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OsuAttributeProvider for PpResult {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<DifficultyAttributes> {
|
|
||||||
self.attributes.attributes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculator for pp on osu!standard maps.
|
/// Calculator for pp on osu!standard maps.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct OsuPP<'m> {
|
pub struct OsuPP<'m> {
|
||||||
@@ -253,6 +223,16 @@ impl<'m> OsuPP<'m> {
|
|||||||
self.calculate_with_func(super::all_included::stars)
|
self.calculate_with_func(super::all_included::stars)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Omits an unnecessary error when enabled features are invalid
|
||||||
|
#[cfg(not(any(
|
||||||
|
feature = "no_leniency",
|
||||||
|
feature = "no_sliders_no_leniency",
|
||||||
|
feature = "all_included"
|
||||||
|
)))]
|
||||||
|
pub(crate) fn calculate(self) -> PpResult {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an object which contains the pp and [`DifficultyAttributes`](crate::osu::DifficultyAttributes)
|
/// Returns an object which contains the pp and [`DifficultyAttributes`](crate::osu::DifficultyAttributes)
|
||||||
/// containing stars and other attributes.
|
/// containing stars and other attributes.
|
||||||
///
|
///
|
||||||
@@ -268,15 +248,18 @@ impl<'m> OsuPP<'m> {
|
|||||||
self.attributes.replace(attributes);
|
self.attributes.replace(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the hitresults and accuracy are set
|
||||||
self.assert_hitresults();
|
self.assert_hitresults();
|
||||||
|
|
||||||
let total_hits = self.total_hits();
|
let total_hits = self.total_hits();
|
||||||
let mut multiplier = 1.12;
|
let mut multiplier = 1.12;
|
||||||
|
|
||||||
|
// NF penalty
|
||||||
if self.mods.nf() {
|
if self.mods.nf() {
|
||||||
multiplier *= (1.0 - 0.02 * self.n_misses as f32).max(0.9);
|
multiplier *= (1.0 - 0.02 * self.n_misses as f32).max(0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SO penalty
|
||||||
if self.mods.so() {
|
if self.mods.so() {
|
||||||
let n_spinners = self.attributes.as_ref().unwrap().n_spinners;
|
let n_spinners = self.attributes.as_ref().unwrap().n_spinners;
|
||||||
multiplier *= 1.0 - (n_spinners as f32 / total_hits as f32).powf(0.85);
|
multiplier *= 1.0 - (n_spinners as f32 / total_hits as f32).powf(0.85);
|
||||||
@@ -441,6 +424,36 @@ impl<'m> OsuPP<'m> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait OsuAttributeProvider {
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OsuAttributeProvider for DifficultyAttributes {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OsuAttributeProvider for StarResult {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes> {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let Self::Osu(attributes) = self {
|
||||||
|
Some(attributes)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OsuAttributeProvider for PpResult {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<DifficultyAttributes> {
|
||||||
|
self.attributes.attributes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+36
-36
@@ -1,42 +1,6 @@
|
|||||||
use super::{stars, DifficultyAttributes};
|
use super::{stars, DifficultyAttributes};
|
||||||
use crate::{Beatmap, Mods, PpResult, StarResult};
|
use crate::{Beatmap, Mods, PpResult, StarResult};
|
||||||
|
|
||||||
pub trait TaikoAttributeProvider {
|
|
||||||
fn attributes(self) -> Option<f32>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TaikoAttributeProvider for f32 {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
Some(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TaikoAttributeProvider for DifficultyAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
Some(self.stars)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TaikoAttributeProvider for StarResult {
|
|
||||||
#[inline]
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
if let StarResult::Taiko(attributes) = self {
|
|
||||||
Some(attributes.stars)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TaikoAttributeProvider for PpResult {
|
|
||||||
fn attributes(self) -> Option<f32> {
|
|
||||||
self.attributes.attributes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculator for pp on osu!taiko maps.
|
/// Calculator for pp on osu!taiko maps.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TaikoPP<'m> {
|
pub struct TaikoPP<'m> {
|
||||||
@@ -214,3 +178,39 @@ const HITWINDOW_MAX: f32 = 20.0;
|
|||||||
fn difficulty_range_od(ar: f32) -> f32 {
|
fn difficulty_range_od(ar: f32) -> f32 {
|
||||||
crate::difficulty_range(ar, HITWINDOW_MAX, HITWINDOW_AVG, HITWINDOW_MIN)
|
crate::difficulty_range(ar, HITWINDOW_MAX, HITWINDOW_AVG, HITWINDOW_MIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait TaikoAttributeProvider {
|
||||||
|
fn attributes(self) -> Option<f32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaikoAttributeProvider for f32 {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaikoAttributeProvider for DifficultyAttributes {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
Some(self.stars)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaikoAttributeProvider for StarResult {
|
||||||
|
#[inline]
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let StarResult::Taiko(attributes) = self {
|
||||||
|
Some(attributes.stars)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaikoAttributeProvider for PpResult {
|
||||||
|
fn attributes(self) -> Option<f32> {
|
||||||
|
self.attributes.attributes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user