various minor adjustments

This commit is contained in:
MaxOhn
2022-10-21 12:40:45 +02:00
parent 335f0a7dde
commit 5a129437eb
27 changed files with 268 additions and 202 deletions
+9 -1
View File
@@ -135,7 +135,7 @@ impl<'map> ManiaStars<'map> {
let ManiaResult { strain, .. } = calculate_result(self);
ManiaStrains {
section_len: SECTION_LEN * clock_rate, // TODO: clock_rate correct here?
section_len: SECTION_LEN * clock_rate,
strains: strain.strain_peaks,
}
}
@@ -224,6 +224,14 @@ pub struct ManiaDifficultyAttributes {
pub max_combo: usize,
}
impl ManiaDifficultyAttributes {
/// Return the maximum combo.
#[inline]
pub fn max_combo(&self) -> usize {
self.max_combo
}
}
/// The result of a performance calculation on an osu!mania map.
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct ManiaPerformanceAttributes {
+4 -6
View File
@@ -5,7 +5,6 @@ use crate::{
Beatmap, DifficultyAttributes, GameMode, HitResultPriority, Mods, OsuPP, PerformanceAttributes,
};
// TODO: update
/// Performance calculator on osu!mania maps.
///
/// # Example
@@ -124,7 +123,7 @@ impl<'map> ManiaPP<'map> {
self
}
/// Specify the accuracy of a play between `0` and `100`.
/// Specify the accuracy of a play between `0.0` and `100.0`.
/// This will be used to generate matching hitresults.
#[inline]
pub fn accuracy(mut self, acc: f64) -> Self {
@@ -252,7 +251,6 @@ impl<'map> ManiaPP<'map> {
let n_misses = self.n_misses.unwrap_or(0);
if let Some(acc) = self.acc {
// TODO: test
let target_total = (acc * (n_objects * 6) as f64).round() as usize;
match (self.n320, self.n300, self.n200, self.n100, self.n50) {
@@ -530,11 +528,11 @@ impl ManiaPpInner {
}
fn compute_difficulty_value(&self) -> f64 {
// Star rating to pp curve
// * Star rating to pp curve
(self.attrs.stars - 0.15).max(0.05).powf(2.2)
// From 80% accuracy, 1/20th of total pp is awarded per additional 1% accuracy
// * From 80% accuracy, 1/20th of total pp is awarded per additional 1% accuracy
* (5.0 * self.calculate_custom_accuracy() - 4.0).max(0.0)
// Length bonus, capped at 1500 notes
// * Length bonus, capped at 1500 notes
* (1.0 + 0.1 * (self.total_hits() / 1500.0).min(1.0))
}
+5 -6
View File
@@ -25,9 +25,8 @@ pub(crate) trait StrainSkill: Sized + Skill {
fn strain_value_at(&mut self, curr: &ManiaDifficultyObject) -> f64;
fn process(&mut self, curr: &ManiaDifficultyObject, diff_objects: &[ManiaDifficultyObject]) {
// The first object doesn't generate a strain, so we begin with an incremented section end
// * The first object doesn't generate a strain, so we begin with an incremented section end
if curr.idx == 0 {
// currentSectionEnd = Math.Ceiling(current.StartTime / SectionLength) * SectionLength;
*self.curr_section_end_mut() = (curr.start_time / SECTION_LEN).ceil() * SECTION_LEN;
}
@@ -72,14 +71,14 @@ pub(crate) trait StrainSkill: Sized + Skill {
let mut difficulty = 0.0;
let mut weight = 1.0;
// Sections with 0 strain are excluded to avoid worst-case time complexity of the following sort (e.g. /b/2351871).
// These sections will not contribute to the difficulty.
// * Sections with 0 strain are excluded to avoid worst-case time complexity of the following sort (e.g. /b/2351871).
// * These sections will not contribute to the difficulty.
let mut peaks = self.get_curr_strain_peaks();
peaks.retain(|&peak| peak > 0.0);
peaks.sort_unstable_by(|a, b| b.partial_cmp(a).unwrap_or(Ordering::Equal));
// Difficulty is the weighted sum of the highest strains from every section.
// We're sorting from highest to lowest strain.
// * Difficulty is the weighted sum of the highest strains from every section.
// * We're sorting from highest to lowest strain.
for strain in peaks {
difficulty += strain * weight;
weight *= Self::DECAY_WEIGHT;
+31 -20
View File
@@ -43,10 +43,12 @@ impl Strain {
}
impl Skill for Strain {
#[inline]
fn process(&mut self, curr: &ManiaDifficultyObject, diff_objects: &[ManiaDifficultyObject]) {
<Self as StrainSkill>::process(self, curr, diff_objects)
}
#[inline]
fn difficulty_value(self) -> f64 {
<Self as StrainSkill>::difficulty_value(self)
}
@@ -55,30 +57,37 @@ impl Skill for Strain {
impl StrainSkill for Strain {
const DECAY_WEIGHT: f64 = 0.9;
#[inline]
fn curr_section_end(&self) -> f64 {
self.curr_section_end
}
#[inline]
fn curr_section_end_mut(&mut self) -> &mut f64 {
&mut self.curr_section_end
}
#[inline]
fn curr_section_peak(&self) -> f64 {
self.curr_section_peak
}
#[inline]
fn curr_section_peak_mut(&mut self) -> &mut f64 {
&mut self.curr_section_peak
}
#[inline]
fn strain_peaks_mut(&mut self) -> &mut Vec<f64> {
&mut self.strain_peaks
}
#[inline]
fn strain_value_at(&mut self, curr: &ManiaDifficultyObject) -> f64 {
<Self as StrainDecaySkill>::strain_value_at(self, curr)
}
#[inline]
fn calculate_initial_strain(
&self,
time: f64,
@@ -93,10 +102,12 @@ impl StrainDecaySkill for Strain {
const SKILL_MULTIPLIER: f64 = 1.0;
const STRAIN_DECAY_BASE: f64 = 1.0;
#[inline]
fn curr_strain(&self) -> f64 {
self.curr_strain
}
#[inline]
fn curr_strain_mut(&mut self) -> &mut f64 {
&mut self.curr_strain
}
@@ -108,19 +119,19 @@ impl StrainDecaySkill for Strain {
let col = mania_curr.base_column;
let mut is_overlapping = false;
// Lowest value we can assume with the current information
// * Lowest value we can assume with the current information
let mut closest_end_time = (end_time - start_time).abs();
// Factor to all additional strains in case something else is held
// * Factor to all additional strains in case something else is held
let mut hold_factor = 1.0;
// Addition to the current note in case it's a hold and has to be released awkwardly
// * Addition to the current note in case it's a hold and has to be released awkwardly
let mut hold_addition = 0.0;
for i in 0..self.end_times.len() {
// The current note is overlapped if a previous note or end is overlapping the current note body
// * The current note is overlapped if a previous note or end is overlapping the current note body
is_overlapping |=
self.end_times[i] > start_time + 1.0 && end_time > self.end_times[i] + 1.0;
// We give a slight bonus to everything if something is held meanwhile
// * We give a slight bonus to everything if something is held meanwhile
if self.end_times[i] > end_time + 1.0 {
hold_factor = 1.25;
}
@@ -128,22 +139,22 @@ impl StrainDecaySkill for Strain {
closest_end_time = (end_time - self.end_times[i]).abs().min(closest_end_time);
}
// The hold addition is given if there was an overlap, however it is only valid if there are no other note with a similar ending.
// Releasing multiple notes is just as easy as releasing 1. Nerfs the hold addition by half if the closest release is release_threshold away.
// holdAddition
// ^
// 1.0 + - - - - - -+-----------
// | /
// 0.5 + - - - - -/ Sigmoid Curve
// | /|
// 0.0 +--------+-+---------------> Release Difference / ms
// release_threshold
// * The hold addition is given if there was an overlap, however it is only valid if there are no other note with a similar ending.
// * Releasing multiple notes is just as easy as releasing 1. Nerfs the hold addition by half if the closest release is release_threshold away.
// * holdAddition
// * ^
// * 1.0 + - - - - - -+-----------
// * | /
// * 0.5 + - - - - -/ Sigmoid Curve
// * | /|
// * 0.0 +--------+-+---------------> Release Difference / ms
// * release_threshold
if is_overlapping {
hold_addition =
(1.0 + (0.5 * (Self::RELEASE_THRESHOLD - closest_end_time)).exp()).recip();
}
// Decay and increase individualStrains in own column
// * Decay and increase individualStrains in own column
self.individual_strains[col] = Self::apply_decay(
self.individual_strains[col],
start_time - self.start_times[col],
@@ -151,14 +162,14 @@ impl StrainDecaySkill for Strain {
);
self.individual_strains[col] += 2.0 * hold_factor;
// For notes at the same time (in a chord), the individualStrain should be the hardest individualStrain out of those columns
// * For notes at the same time (in a chord), the individualStrain should be the hardest individualStrain out of those columns
self.individual_strain = if mania_curr.delta_time <= 1.0 {
self.individual_strain.max(self.individual_strains[col])
} else {
self.individual_strains[col]
};
// Decay and increase overallStrain
// * Decay and increase overallStrain
self.overall_strain = Self::apply_decay(
self.overall_strain,
curr.delta_time,
@@ -166,11 +177,11 @@ impl StrainDecaySkill for Strain {
);
self.overall_strain += (1.0 + hold_addition) * hold_factor;
// Update startTimes and endTimes arrays
// * Update startTimes and endTimes arrays
self.start_times[col] = start_time;
self.end_times[col] = end_time;
// By subtracting CurrentStrain, this skill effectively only considers the maximum strain of any one hitobject within each strain section.
// * By subtracting CurrentStrain, this skill effectively only considers the maximum strain of any one hitobject within each strain section.
self.individual_strain + self.overall_strain - self.curr_strain
}