provided a way for partial plays
This commit is contained in:
+8
-7
@@ -10,8 +10,12 @@ const SECTION_LEN: f32 = 400.0;
|
||||
const STAR_SCALING_FACTOR: f32 = 0.018;
|
||||
|
||||
/// Star calculation for osu!mania maps
|
||||
pub fn stars(map: &Beatmap, mods: impl Mods) -> f32 {
|
||||
if map.hit_objects.len() < 2 {
|
||||
///
|
||||
/// In case of a partial play, e.g. a fail, one can specify the amount of passed objects.
|
||||
pub fn stars(map: &Beatmap, mods: impl Mods, passed_objects: Option<usize>) -> f32 {
|
||||
let take = passed_objects.unwrap_or_else(|| map.hit_objects.len());
|
||||
|
||||
if take < 2 {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@@ -22,6 +26,7 @@ pub fn stars(map: &Beatmap, mods: impl Mods) -> f32 {
|
||||
let mut hit_objects = map
|
||||
.hit_objects
|
||||
.iter()
|
||||
.take(take)
|
||||
.skip(1)
|
||||
.zip(map.hit_objects.iter())
|
||||
.map(|(base, prev)| DifficultyHitObject::new(base, prev, map.cs, clock_rate));
|
||||
@@ -84,7 +89,7 @@ mod tests {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn mania_single() {
|
||||
let file = match File::open("E:/Games/osu!/beatmaps/1355822.osu") {
|
||||
let file = match File::open("./maps/1355822.osu") {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("Could not open file: {}", why),
|
||||
};
|
||||
@@ -94,10 +99,6 @@ mod tests {
|
||||
Err(why) => panic!("Error while parsing map: {}", why),
|
||||
};
|
||||
|
||||
// println!("timings:\n{:#?}", map.timing_points);
|
||||
// println!("---");
|
||||
// println!("difficulties:\n{:#?}", map.difficulty_points);
|
||||
|
||||
let result = PpCalculator::new(&map).mods(256).calculate();
|
||||
|
||||
println!("Stars: {}", result.stars);
|
||||
|
||||
+15
-2
@@ -17,12 +17,12 @@ impl PpProvider for Beatmap {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Allow partial plays
|
||||
pub struct PpCalculator<'m> {
|
||||
map: &'m Beatmap,
|
||||
stars: Option<f32>,
|
||||
mods: u32,
|
||||
score: Option<f32>,
|
||||
passed_objects: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'m> PpCalculator<'m> {
|
||||
@@ -33,6 +33,7 @@ impl<'m> PpCalculator<'m> {
|
||||
stars: None,
|
||||
mods: 0,
|
||||
score: None,
|
||||
passed_objects: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +51,8 @@ impl<'m> PpCalculator<'m> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Score of a play.
|
||||
/// On NM its between 0 and 1,000,000, on EZ between 0 and 500,000, etc
|
||||
#[inline]
|
||||
pub fn score(mut self, score: u32) -> Self {
|
||||
self.score.replace(score as f32);
|
||||
@@ -57,8 +60,18 @@ impl<'m> PpCalculator<'m> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Amount of passed objects for partial plays, e.g. a fail.
|
||||
#[inline]
|
||||
pub fn passed_objects(mut self, passed_objects: usize) -> Self {
|
||||
self.passed_objects.replace(passed_objects);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn calculate(self) -> PpResult {
|
||||
let stars = self.stars.unwrap_or_else(|| stars(self.map, self.mods));
|
||||
let stars = self
|
||||
.stars
|
||||
.unwrap_or_else(|| stars(self.map, self.mods, self.passed_objects));
|
||||
|
||||
let ez = self.mods.ez();
|
||||
let nf = self.mods.nf();
|
||||
|
||||
+2
-7
@@ -43,17 +43,12 @@ impl Strain {
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn save_current_peak(&mut self) {
|
||||
// TODO: Remove branching
|
||||
if self.prev_time.is_some() {
|
||||
self.strain_peaks.push(self.current_section_peak);
|
||||
}
|
||||
self.strain_peaks.push(self.current_section_peak);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn start_new_section_from(&mut self, time: f32) {
|
||||
if let Some(prev) = self.prev_time {
|
||||
self.current_section_peak = self.peak_strain(time - prev);
|
||||
}
|
||||
self.current_section_peak = self.peak_strain(time - self.prev_time.unwrap());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
Reference in New Issue
Block a user