f32 -> f64 & osu_precise fixes + update
This commit is contained in:
+11
-11
@@ -8,8 +8,8 @@ use strain::Strain;
|
||||
|
||||
use crate::{parse::HitObject, Beatmap, GameMode, Mods, Strains};
|
||||
|
||||
const SECTION_LEN: f32 = 400.0;
|
||||
const STAR_SCALING_FACTOR: f32 = 0.018;
|
||||
const SECTION_LEN: f64 = 400.0;
|
||||
const STAR_SCALING_FACTOR: f64 = 0.018;
|
||||
|
||||
/// Star calculation for osu!mania maps
|
||||
///
|
||||
@@ -150,13 +150,13 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
|
||||
pub(crate) struct DifficultyHitObject<'o> {
|
||||
base: &'o HitObject,
|
||||
column: usize,
|
||||
delta: f32,
|
||||
start_time: f32,
|
||||
delta: f64,
|
||||
start_time: f64,
|
||||
}
|
||||
|
||||
impl<'o> DifficultyHitObject<'o> {
|
||||
#[inline]
|
||||
fn new(base: &'o HitObject, prev: &'o HitObject, columns: f32, clock_rate: f32) -> Self {
|
||||
fn new(base: &'o HitObject, prev: &'o HitObject, columns: f32, clock_rate: f64) -> Self {
|
||||
let x_divisor = 512.0 / columns;
|
||||
let column = (base.pos.x / x_divisor).floor().min(columns - 1.0) as usize;
|
||||
|
||||
@@ -173,28 +173,28 @@ impl<'o> DifficultyHitObject<'o> {
|
||||
/// This data is necessary to calculate PP.
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct DifficultyAttributes {
|
||||
pub stars: f32,
|
||||
pub stars: f64,
|
||||
}
|
||||
|
||||
/// Various data created through the pp calculation.
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct PerformanceAttributes {
|
||||
pub attributes: DifficultyAttributes,
|
||||
pub pp_acc: f32,
|
||||
pub pp_strain: f32,
|
||||
pub pp: f32,
|
||||
pub pp_acc: f64,
|
||||
pub pp_strain: f64,
|
||||
pub pp: f64,
|
||||
}
|
||||
|
||||
impl PerformanceAttributes {
|
||||
/// Return the star value.
|
||||
#[inline]
|
||||
pub fn stars(&self) -> f32 {
|
||||
pub fn stars(&self) -> f64 {
|
||||
self.attributes.stars
|
||||
}
|
||||
|
||||
/// Return the performance point value.
|
||||
#[inline]
|
||||
pub fn pp(&self) -> f32 {
|
||||
pub fn pp(&self) -> f64 {
|
||||
self.pp
|
||||
}
|
||||
}
|
||||
|
||||
+17
-17
@@ -30,9 +30,9 @@ use crate::{Beatmap, Mods, PpResult, StarResult};
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub struct ManiaPP<'m> {
|
||||
map: &'m Beatmap,
|
||||
stars: Option<f32>,
|
||||
stars: Option<f64>,
|
||||
mods: u32,
|
||||
score: Option<f32>,
|
||||
score: Option<f64>,
|
||||
passed_objects: Option<usize>,
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ impl<'m> ManiaPP<'m> {
|
||||
#[inline]
|
||||
pub fn attributes(mut self, attributes: impl ManiaAttributeProvider) -> Self {
|
||||
if let Some(stars) = attributes.attributes() {
|
||||
self.stars.replace(stars);
|
||||
self.stars = Some(stars);
|
||||
}
|
||||
|
||||
self
|
||||
@@ -76,7 +76,7 @@ impl<'m> ManiaPP<'m> {
|
||||
/// On `NoMod` its between 0 and 1,000,000, on `Easy` between 0 and 500,000, etc.
|
||||
#[inline]
|
||||
pub fn score(mut self, score: u32) -> Self {
|
||||
self.score.replace(score as f32);
|
||||
self.score = Some(score as f64);
|
||||
|
||||
self
|
||||
}
|
||||
@@ -100,17 +100,17 @@ impl<'m> ManiaPP<'m> {
|
||||
let ht = self.mods.ht();
|
||||
|
||||
let mut scaled_score = self.score.map_or(1_000_000.0, |score| {
|
||||
score / 0.5_f32.powi(ez as i32 + nf as i32 + ht as i32)
|
||||
score / 0.5_f64.powi(ez as i32 + nf as i32 + ht as i32)
|
||||
});
|
||||
|
||||
if let Some(passed_objects) = self.passed_objects {
|
||||
let percent_passed =
|
||||
passed_objects as f32 / (self.map.n_circles + self.map.n_sliders) as f32;
|
||||
passed_objects as f64 / (self.map.n_circles + self.map.n_sliders) as f64;
|
||||
|
||||
scaled_score /= percent_passed;
|
||||
}
|
||||
|
||||
let mut od = 34.0 + 3.0 * (10.0 - self.map.od).max(0.0).min(10.0);
|
||||
let mut od = 34.0 + 3.0 * (10.0 - self.map.od as f64).max(0.0).min(10.0);
|
||||
let clock_rate = self.mods.speed();
|
||||
|
||||
let mut multiplier = 0.8;
|
||||
@@ -139,10 +139,10 @@ impl<'m> ManiaPP<'m> {
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_strain(&self, score: f32, stars: f32) -> f32 {
|
||||
fn compute_strain(&self, score: f64, stars: f64) -> f64 {
|
||||
let mut strain_value = (5.0 * (stars / 0.2).max(1.0) - 4.0).powf(2.2) / 135.0;
|
||||
|
||||
strain_value *= 1.0 + 0.1 * (self.map.hit_objects.len() as f32 / 1500.0).min(1.0);
|
||||
strain_value *= 1.0 + 0.1 * (self.map.hit_objects.len() as f64 / 1500.0).min(1.0);
|
||||
|
||||
if score <= 500_000.0 {
|
||||
strain_value = 0.0;
|
||||
@@ -162,7 +162,7 @@ impl<'m> ManiaPP<'m> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_accuracy_value(&self, score: f32, strain: f32, hit_window: f32) -> f32 {
|
||||
fn compute_accuracy_value(&self, score: f64, strain: f64, hit_window: f64) -> f64 {
|
||||
(0.2 - (hit_window - 34.0) * 0.006667).max(0.0)
|
||||
* strain
|
||||
* ((score - 960_000.0).max(0.0) / 40_000.0).powf(1.1)
|
||||
@@ -170,33 +170,33 @@ impl<'m> ManiaPP<'m> {
|
||||
}
|
||||
|
||||
pub trait ManiaAttributeProvider {
|
||||
fn attributes(self) -> Option<f32>;
|
||||
fn attributes(self) -> Option<f64>;
|
||||
}
|
||||
|
||||
impl ManiaAttributeProvider for f32 {
|
||||
impl ManiaAttributeProvider for f64 {
|
||||
#[inline]
|
||||
fn attributes(self) -> Option<f32> {
|
||||
fn attributes(self) -> Option<f64> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ManiaAttributeProvider for DifficultyAttributes {
|
||||
#[inline]
|
||||
fn attributes(self) -> Option<f32> {
|
||||
fn attributes(self) -> Option<f64> {
|
||||
Some(self.stars)
|
||||
}
|
||||
}
|
||||
|
||||
impl ManiaAttributeProvider for PerformanceAttributes {
|
||||
#[inline]
|
||||
fn attributes(self) -> Option<f32> {
|
||||
fn attributes(self) -> Option<f64> {
|
||||
Some(self.attributes.stars)
|
||||
}
|
||||
}
|
||||
|
||||
impl ManiaAttributeProvider for StarResult {
|
||||
#[inline]
|
||||
fn attributes(self) -> Option<f32> {
|
||||
fn attributes(self) -> Option<f64> {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let Self::Mania(attributes) = self {
|
||||
Some(attributes.stars)
|
||||
@@ -208,7 +208,7 @@ impl ManiaAttributeProvider for StarResult {
|
||||
|
||||
impl ManiaAttributeProvider for PpResult {
|
||||
#[inline]
|
||||
fn attributes(self) -> Option<f32> {
|
||||
fn attributes(self) -> Option<f64> {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let Self::Mania(attributes) = self {
|
||||
Some(attributes.attributes.stars)
|
||||
|
||||
+19
-19
@@ -3,25 +3,25 @@ use super::DifficultyHitObject;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
pub(crate) struct Strain {
|
||||
current_strain: f32,
|
||||
current_section_peak: f32,
|
||||
current_strain: f64,
|
||||
current_section_peak: f64,
|
||||
|
||||
individual_strain: f32,
|
||||
overall_strain: f32,
|
||||
individual_strain: f64,
|
||||
overall_strain: f64,
|
||||
|
||||
hold_end_times: Vec<f32>,
|
||||
individual_strains: Vec<f32>,
|
||||
pub(crate) strain_peaks: Vec<f32>,
|
||||
hold_end_times: Vec<f64>,
|
||||
individual_strains: Vec<f64>,
|
||||
pub(crate) strain_peaks: Vec<f64>,
|
||||
|
||||
prev_time: Option<f32>,
|
||||
prev_time: Option<f64>,
|
||||
}
|
||||
|
||||
const INDIVISUAL_DECAY_BASE: f32 = 0.125;
|
||||
const OVERALL_DECAY_BASE: f32 = 0.3;
|
||||
const STRAIN_DECAY_BASE: f32 = 1.0;
|
||||
const INDIVISUAL_DECAY_BASE: f64 = 0.125;
|
||||
const OVERALL_DECAY_BASE: f64 = 0.3;
|
||||
const STRAIN_DECAY_BASE: f64 = 1.0;
|
||||
|
||||
const SKILL_MULTIPLIER: f32 = 1.0;
|
||||
const DECAY_WEIGHT: f32 = 0.9;
|
||||
const SKILL_MULTIPLIER: f64 = 1.0;
|
||||
const DECAY_WEIGHT: f64 = 0.9;
|
||||
|
||||
impl Strain {
|
||||
#[inline]
|
||||
@@ -47,18 +47,18 @@ impl Strain {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn start_new_section_from(&mut self, time: f32) {
|
||||
pub(crate) fn start_new_section_from(&mut self, time: f64) {
|
||||
self.current_section_peak = self.peak_strain(time - self.prev_time.unwrap());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn peak_strain(&self, delta_time: f32) -> f32 {
|
||||
fn peak_strain(&self, delta_time: f64) -> f64 {
|
||||
apply_decay(self.individual_strain, delta_time, INDIVISUAL_DECAY_BASE)
|
||||
+ apply_decay(self.overall_strain, delta_time, OVERALL_DECAY_BASE)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn strain_decay(&self, ms: f32) -> f32 {
|
||||
fn strain_decay(&self, ms: f64) -> f64 {
|
||||
STRAIN_DECAY_BASE.powf(ms / 1000.0)
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ impl Strain {
|
||||
self.prev_time.replace(current.start_time);
|
||||
}
|
||||
|
||||
fn strain_value_of(&mut self, current: &DifficultyHitObject<'_>) -> f32 {
|
||||
fn strain_value_of(&mut self, current: &DifficultyHitObject<'_>) -> f64 {
|
||||
let end_time = current.base.end_time();
|
||||
|
||||
let mut hold_factor = 1.0;
|
||||
@@ -107,7 +107,7 @@ impl Strain {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn difficulty_value(&mut self) -> f32 {
|
||||
pub(crate) fn difficulty_value(&mut self) -> f64 {
|
||||
let mut difficulty = 0.0;
|
||||
let mut weight = 1.0;
|
||||
|
||||
@@ -124,6 +124,6 @@ impl Strain {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn apply_decay(value: f32, delta_time: f32, decay_base: f32) -> f32 {
|
||||
fn apply_decay(value: f64, delta_time: f64, decay_base: f64) -> f64 {
|
||||
value * decay_base.powf(delta_time / 1000.0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user