quaver-rs 0.1.0

A Rust library for parsing and analyzing Quaver rhythm game maps
Documentation
/// Constant Variables for any specific Gamemode that the Strain Solver can use to solve.
#[derive(Debug, Clone)]
pub struct StrainConstants {
    /// List of Constant Variables for the current Solver.
    pub constant_variables: Vec<ConstantVariable>,
}

impl StrainConstants {
    /// Create a new constant variable for difficulty calculation and optimization.
    pub fn new_constant(&mut self, name: String, value: f32) -> f32 {
        let const_var = ConstantVariable::new(name, value);
        self.constant_variables.push(const_var);
        value
    }

    /// Returns a string of Constant Variable info mainly used for debugging and optimization
    pub fn get_info_from_variables(&self) -> String {
        self.constant_variables
            .iter()
            .map(|var| var.get_variable_info())
            .collect::<Vec<_>>()
            .join("\n")
    }

    /// Constructor
    pub fn new(constant_variables: Option<Vec<ConstantVariable>>) -> Self {
        Self {
            constant_variables: constant_variables.unwrap_or_default(),
        }
    }
}

/// Strain constants specific to Keys mode
#[derive(Debug, Clone)]
pub struct StrainConstantsKeys {
    /// Base strain constants
    pub base: StrainConstants,
    
    /// When Long Notes start/end after this threshold, it will be considered for a specific multiplier.
    /// Non-Dynamic Constant. Do not use for optimization.
    pub ln_end_threshold_ms: f32,
    
    /// When separate notes are under this threshold, it will count as a chord.
    /// Non-Dynamic Constant. Do not use for optimization.
    pub chord_clump_tolerance_ms: f32,
    
    /// Size of each graph partition in milliseconds.
    /// Non-Dynamic Constant. Do not use for optimization.
    pub graph_interval_size_ms: i32,
    
    /// Offset between each graph partition in milliseconds.
    /// Non-Dynamic Constant. Do not use for optimization.
    pub graph_interval_offset_ms: i32,
    
    // Simple Jacks
    pub s_jack_lower_boundary_ms: f32,
    pub s_jack_upper_boundary_ms: f32,
    pub s_jack_max_strain_value: f32,
    pub s_jack_curve_exponential: f32,
    
    // Tech Jacks
    pub t_jack_lower_boundary_ms: f32,
    pub t_jack_upper_boundary_ms: f32,
    pub t_jack_max_strain_value: f32,
    pub t_jack_curve_exponential: f32,
    
    // Rolls
    pub roll_lower_boundary_ms: f32,
    pub roll_upper_boundary_ms: f32,
    pub roll_max_strain_value: f32,
    pub roll_curve_exponential: f32,
    
    // Brackets
    pub bracket_lower_boundary_ms: f32,
    pub bracket_upper_boundary_ms: f32,
    pub bracket_max_strain_value: f32,
    pub bracket_curve_exponential: f32,
    
    // Roll Manipulation
    pub roll_ratio_tolerance_ms: f32,
    pub roll_ratio_multiplier: f32,
    pub roll_max_length: f32,
    pub roll_length_multiplier: f32,
    
    // Jack Manipulation (Vibro)
    pub vibro_action_duration_ms: f32,
    pub vibro_action_tolerance_ms: f32,
    pub vibro_multiplier: f32,
    pub vibro_max_length: f32,
    pub vibro_length_multiplier: f32,
    
    // LN Multipliers
    pub ln_layer_threshold_ms: f32,
    pub ln_layer_tolerance_ms: f32,
    pub ln_base_multiplier: f32,
    pub ln_release_after_multiplier: f32,
    pub ln_release_before_multiplier: f32,
    pub ln_tap_multiplier: f32,
}

impl StrainConstantsKeys {
    pub fn new() -> Self {
        let mut base = StrainConstants::new(None);
        
        Self {
            base: base.clone(),
            ln_end_threshold_ms: 42.0,
            chord_clump_tolerance_ms: 8.0,
            graph_interval_size_ms: 500,
            graph_interval_offset_ms: 100,
            
            // Simple Jacks - real values from C#
            s_jack_lower_boundary_ms: base.new_constant("SJackLowerBoundaryMs".to_string(), 40.0),
            s_jack_upper_boundary_ms: base.new_constant("SJackUpperBoundaryMs".to_string(), 320.0),
            s_jack_max_strain_value: base.new_constant("SJackMaxStrainValue".to_string(), 68.0),
            s_jack_curve_exponential: base.new_constant("SJackCurveExponential".to_string(), 1.17),
            
            // Tech Jacks - real values from C#
            t_jack_lower_boundary_ms: base.new_constant("TJackLowerBoundaryMs".to_string(), 40.0),
            t_jack_upper_boundary_ms: base.new_constant("TJackUpperBoundaryMs".to_string(), 330.0),
            t_jack_max_strain_value: base.new_constant("TJackMaxStrainValue".to_string(), 70.0),
            t_jack_curve_exponential: base.new_constant("TJackCurveExponential".to_string(), 1.14),
            
            // Rolls - real values from C#
            roll_lower_boundary_ms: base.new_constant("RollLowerBoundaryMs".to_string(), 30.0),
            roll_upper_boundary_ms: base.new_constant("RollUpperBoundaryMs".to_string(), 230.0),
            roll_max_strain_value: base.new_constant("RollMaxStrainValue".to_string(), 55.0),
            roll_curve_exponential: base.new_constant("RollCurveExponential".to_string(), 1.13),
            
            // Brackets - real values from C#
            bracket_lower_boundary_ms: base.new_constant("BracketLowerBoundaryMs".to_string(), 30.0),
            bracket_upper_boundary_ms: base.new_constant("BracketUpperBoundaryMs".to_string(), 230.0),
            bracket_max_strain_value: base.new_constant("BracketMaxStrainValue".to_string(), 56.0),
            bracket_curve_exponential: base.new_constant("BracketCurveExponential".to_string(), 1.13),
            
            // LN Multipliers - real values from C#
            ln_base_multiplier: base.new_constant("LnBaseMultiplier".to_string(), 0.6),
            ln_layer_tolerance_ms: base.new_constant("LnLayerToleranceMs".to_string(), 60.0),
            ln_layer_threshold_ms: base.new_constant("LnLayerThresholdMs".to_string(), 93.7),
            ln_release_after_multiplier: base.new_constant("LnReleaseAfterMultiplier".to_string(), 1.0),
            ln_release_before_multiplier: base.new_constant("LnReleaseBeforeMultiplier".to_string(), 1.3),
            ln_tap_multiplier: base.new_constant("LnTapMultiplier".to_string(), 1.05),
            
            // Jack Manipulation (Vibro) - real values from C#
            vibro_action_duration_ms: base.new_constant("VibroActionDurationMs".to_string(), 88.2),
            vibro_action_tolerance_ms: base.new_constant("VibroActionToleranceMs".to_string(), 88.2),
            vibro_multiplier: base.new_constant("VibroMultiplier".to_string(), 0.75),
            vibro_length_multiplier: base.new_constant("VibroLengthMultiplier".to_string(), 0.3),
            vibro_max_length: base.new_constant("VibroMaxLength".to_string(), 6.0),
            
            // Roll Manipulation - real values from C#
            roll_ratio_tolerance_ms: base.new_constant("RollRatioToleranceMs".to_string(), 2.0),
            roll_ratio_multiplier: base.new_constant("RollRatioMultiplier".to_string(), 0.25),
            roll_length_multiplier: base.new_constant("RollLengthMultiplier".to_string(), 0.6),
            roll_max_length: base.new_constant("RollMaxLength".to_string(), 14.0),
        }
    }
}

/// This class is used to represent a constant variable for difficulty calculation.
/// It is also used for optimization.
#[derive(Debug, Clone)]
pub struct ConstantVariable {
    /// Name of this constant
    pub name: String,
    
    /// Value of this constant
    pub value: f32,
}

impl ConstantVariable {
    /// Constructor
    pub fn new(name: String, value: f32) -> Self {
        Self { name, value }
    }
    
    /// Returns string "(name) = (value)". Mainly used for debugging and optimizing.
    pub fn get_variable_info(&self) -> String {
        format!("{} = {}", self.name, self.value)
    }
}