use crate::{
mania::difficulty::object::ManiaDifficultyObject,
util::{difficulty::logistic, sync::Weak},
};
pub struct OverallStrainEvaluator;
impl OverallStrainEvaluator {
const RELEASE_THRESHOLD: f64 = 30.0;
pub fn evaluate_diff_of(curr: &ManiaDifficultyObject) -> f64 {
let mania_curr = curr;
let start_time = curr.start_time;
let end_time = curr.end_time;
let mut is_overlapping = false;
let mut closest_end_time = (end_time - start_time).abs();
let mut hold_factor = 1.0;
let mut hold_addition = 0.0;
for mania_prev in mania_curr
.prev_hit_objects
.iter()
.flatten()
.filter_map(Weak::upgrade)
{
let mania_prev_ref = mania_prev.get();
is_overlapping |= mania_prev_ref.end_time > start_time + 1.0
&& end_time > mania_prev_ref.end_time + 1.0
&& start_time > mania_prev_ref.start_time + 1.0;
if mania_prev_ref.end_time > end_time + 1.0
&& start_time > mania_prev_ref.start_time + 1.0
{
hold_factor = 1.25;
}
closest_end_time = closest_end_time.min((end_time - mania_prev_ref.end_time).abs());
}
if is_overlapping {
hold_addition = logistic(closest_end_time, Self::RELEASE_THRESHOLD, 0.27, None);
}
(1.0 + hold_addition) * hold_factor
}
}