quaver_rs/difficulty_processor/
constants.rs

1/// Constant Variables for any specific Gamemode that the Strain Solver can use to solve.
2#[derive(Debug, Clone)]
3pub struct StrainConstants {
4    /// List of Constant Variables for the current Solver.
5    pub constant_variables: Vec<ConstantVariable>,
6}
7
8impl StrainConstants {
9    /// Create a new constant variable for difficulty calculation and optimization.
10    pub fn new_constant(&mut self, name: String, value: f32) -> f32 {
11        let const_var = ConstantVariable::new(name, value);
12        self.constant_variables.push(const_var);
13        value
14    }
15
16    /// Returns a string of Constant Variable info mainly used for debugging and optimization
17    pub fn get_info_from_variables(&self) -> String {
18        self.constant_variables
19            .iter()
20            .map(|var| var.get_variable_info())
21            .collect::<Vec<_>>()
22            .join("\n")
23    }
24
25    /// Constructor
26    pub fn new(constant_variables: Option<Vec<ConstantVariable>>) -> Self {
27        Self {
28            constant_variables: constant_variables.unwrap_or_default(),
29        }
30    }
31}
32
33/// Strain constants specific to Keys mode
34#[derive(Debug, Clone)]
35pub struct StrainConstantsKeys {
36    /// Base strain constants
37    pub base: StrainConstants,
38    
39    /// When Long Notes start/end after this threshold, it will be considered for a specific multiplier.
40    /// Non-Dynamic Constant. Do not use for optimization.
41    pub ln_end_threshold_ms: f32,
42    
43    /// When separate notes are under this threshold, it will count as a chord.
44    /// Non-Dynamic Constant. Do not use for optimization.
45    pub chord_clump_tolerance_ms: f32,
46    
47    /// Size of each graph partition in milliseconds.
48    /// Non-Dynamic Constant. Do not use for optimization.
49    pub graph_interval_size_ms: i32,
50    
51    /// Offset between each graph partition in milliseconds.
52    /// Non-Dynamic Constant. Do not use for optimization.
53    pub graph_interval_offset_ms: i32,
54    
55    // Simple Jacks
56    pub s_jack_lower_boundary_ms: f32,
57    pub s_jack_upper_boundary_ms: f32,
58    pub s_jack_max_strain_value: f32,
59    pub s_jack_curve_exponential: f32,
60    
61    // Tech Jacks
62    pub t_jack_lower_boundary_ms: f32,
63    pub t_jack_upper_boundary_ms: f32,
64    pub t_jack_max_strain_value: f32,
65    pub t_jack_curve_exponential: f32,
66    
67    // Rolls
68    pub roll_lower_boundary_ms: f32,
69    pub roll_upper_boundary_ms: f32,
70    pub roll_max_strain_value: f32,
71    pub roll_curve_exponential: f32,
72    
73    // Brackets
74    pub bracket_lower_boundary_ms: f32,
75    pub bracket_upper_boundary_ms: f32,
76    pub bracket_max_strain_value: f32,
77    pub bracket_curve_exponential: f32,
78    
79    // Roll Manipulation
80    pub roll_ratio_tolerance_ms: f32,
81    pub roll_ratio_multiplier: f32,
82    pub roll_max_length: f32,
83    pub roll_length_multiplier: f32,
84    
85    // Jack Manipulation (Vibro)
86    pub vibro_action_duration_ms: f32,
87    pub vibro_action_tolerance_ms: f32,
88    pub vibro_multiplier: f32,
89    pub vibro_max_length: f32,
90    pub vibro_length_multiplier: f32,
91    
92    // LN Multipliers
93    pub ln_layer_threshold_ms: f32,
94    pub ln_layer_tolerance_ms: f32,
95    pub ln_base_multiplier: f32,
96    pub ln_release_after_multiplier: f32,
97    pub ln_release_before_multiplier: f32,
98    pub ln_tap_multiplier: f32,
99}
100
101impl StrainConstantsKeys {
102    pub fn new() -> Self {
103        let mut base = StrainConstants::new(None);
104        
105        Self {
106            base: base.clone(),
107            ln_end_threshold_ms: 42.0,
108            chord_clump_tolerance_ms: 8.0,
109            graph_interval_size_ms: 500,
110            graph_interval_offset_ms: 100,
111            
112            // Simple Jacks - real values from C#
113            s_jack_lower_boundary_ms: base.new_constant("SJackLowerBoundaryMs".to_string(), 40.0),
114            s_jack_upper_boundary_ms: base.new_constant("SJackUpperBoundaryMs".to_string(), 320.0),
115            s_jack_max_strain_value: base.new_constant("SJackMaxStrainValue".to_string(), 68.0),
116            s_jack_curve_exponential: base.new_constant("SJackCurveExponential".to_string(), 1.17),
117            
118            // Tech Jacks - real values from C#
119            t_jack_lower_boundary_ms: base.new_constant("TJackLowerBoundaryMs".to_string(), 40.0),
120            t_jack_upper_boundary_ms: base.new_constant("TJackUpperBoundaryMs".to_string(), 330.0),
121            t_jack_max_strain_value: base.new_constant("TJackMaxStrainValue".to_string(), 70.0),
122            t_jack_curve_exponential: base.new_constant("TJackCurveExponential".to_string(), 1.14),
123            
124            // Rolls - real values from C#
125            roll_lower_boundary_ms: base.new_constant("RollLowerBoundaryMs".to_string(), 30.0),
126            roll_upper_boundary_ms: base.new_constant("RollUpperBoundaryMs".to_string(), 230.0),
127            roll_max_strain_value: base.new_constant("RollMaxStrainValue".to_string(), 55.0),
128            roll_curve_exponential: base.new_constant("RollCurveExponential".to_string(), 1.13),
129            
130            // Brackets - real values from C#
131            bracket_lower_boundary_ms: base.new_constant("BracketLowerBoundaryMs".to_string(), 30.0),
132            bracket_upper_boundary_ms: base.new_constant("BracketUpperBoundaryMs".to_string(), 230.0),
133            bracket_max_strain_value: base.new_constant("BracketMaxStrainValue".to_string(), 56.0),
134            bracket_curve_exponential: base.new_constant("BracketCurveExponential".to_string(), 1.13),
135            
136            // LN Multipliers - real values from C#
137            ln_base_multiplier: base.new_constant("LnBaseMultiplier".to_string(), 0.6),
138            ln_layer_tolerance_ms: base.new_constant("LnLayerToleranceMs".to_string(), 60.0),
139            ln_layer_threshold_ms: base.new_constant("LnLayerThresholdMs".to_string(), 93.7),
140            ln_release_after_multiplier: base.new_constant("LnReleaseAfterMultiplier".to_string(), 1.0),
141            ln_release_before_multiplier: base.new_constant("LnReleaseBeforeMultiplier".to_string(), 1.3),
142            ln_tap_multiplier: base.new_constant("LnTapMultiplier".to_string(), 1.05),
143            
144            // Jack Manipulation (Vibro) - real values from C#
145            vibro_action_duration_ms: base.new_constant("VibroActionDurationMs".to_string(), 88.2),
146            vibro_action_tolerance_ms: base.new_constant("VibroActionToleranceMs".to_string(), 88.2),
147            vibro_multiplier: base.new_constant("VibroMultiplier".to_string(), 0.75),
148            vibro_length_multiplier: base.new_constant("VibroLengthMultiplier".to_string(), 0.3),
149            vibro_max_length: base.new_constant("VibroMaxLength".to_string(), 6.0),
150            
151            // Roll Manipulation - real values from C#
152            roll_ratio_tolerance_ms: base.new_constant("RollRatioToleranceMs".to_string(), 2.0),
153            roll_ratio_multiplier: base.new_constant("RollRatioMultiplier".to_string(), 0.25),
154            roll_length_multiplier: base.new_constant("RollLengthMultiplier".to_string(), 0.6),
155            roll_max_length: base.new_constant("RollMaxLength".to_string(), 14.0),
156        }
157    }
158}
159
160/// This class is used to represent a constant variable for difficulty calculation.
161/// It is also used for optimization.
162#[derive(Debug, Clone)]
163pub struct ConstantVariable {
164    /// Name of this constant
165    pub name: String,
166    
167    /// Value of this constant
168    pub value: f32,
169}
170
171impl ConstantVariable {
172    /// Constructor
173    pub fn new(name: String, value: f32) -> Self {
174        Self { name, value }
175    }
176    
177    /// Returns string "(name) = (value)". Mainly used for debugging and optimizing.
178    pub fn get_variable_info(&self) -> String {
179        format!("{} = {}", self.name, self.value)
180    }
181}