Etterna 0.75.1
Loading...
Searching...
No Matches
UlbuFiveKey.h
1#pragma once
2
3#include "UlbuBase.h"
4
5#include "./Dependent/HD_PatternMods/HandSwitch.h"
6
7/* my love is the great Bazoinkazoink. i love the great Five Key Ulbu. arrows are my hands, the center panel is my body, the rhythm is my heart. */
8
10{
11 HandSwitchMod _hsw;
12
13 //SequencerGeneral _seq;
14
15 diffz _diffz;
16
17 explicit TheFiveEaredBazoinkazoink(Calc& calc)
18 : Bazoinkazoink(calc)
19 {
20
21 }
22
23 private:
24 const std::array<std::vector<int>, NUM_Skillset> pmods = { {
25 // Overall
26 {},
27
28 // Stream
29 {
30 GStream,
31 },
32
33 // Jumpstream
34 {
35 GChordStream,
36 },
37
38 // Handstream
39 {
40 GBracketing,
41 },
42
43 // Stamina
44 {},
45
46 // Jackspeed
47 {},
48
49 // Chordjack
50 {
51 CJ,
52 },
53
54 // Technical
55 {
56 HandBalance,
57 HandSwitch,
58 },
59 } };
60
61 const std::array<float, NUM_Skillset> basescalers = {
62 0.F, 1.F, 1.F, 1.F, 0.93F, 1.F, 1.F, 1.F
63 };
64
65 public:
66 const std::array<std::vector<int>, NUM_Skillset>& get_pmods() const override
67 {
68 return pmods;
69 }
70 const std::array<float, NUM_Skillset>& get_basescalers() const override
71 {
72 return basescalers;
73 }
74 void adj_diff_func(
75 const size_t& itv,
76 const int& hand,
77 float*& adj_diff,
78 float*& stam_base,
79 const float& adj_npsbase,
80 const int& ss,
81 std::array<float, NUM_Skillset>& pmod_product_cur_interval) override
82 {
83 switch (ss) {
84 case Skill_Stream:
85 break;
86 case Skill_Jumpstream: {
87 auto a = *adj_diff;
88 auto b =
89 _calc.init_base_diff_vals.at(hand).at(NPSBase).at(itv) *
90 pmod_product_cur_interval[Skill_Handstream];
91 *stam_base = std::max<float>(a, b);
92 } break;
93 case Skill_Handstream: {
94 auto a = adj_npsbase;
95 auto b =
96 _calc.init_base_diff_vals.at(hand).at(NPSBase).at(itv) *
97 pmod_product_cur_interval[Skill_Jumpstream];
98 *stam_base = std::max<float>(a, b);
99 } break;
100 case Skill_JackSpeed:
101 break;
102 case Skill_Chordjack:
103 break;
104 case Skill_Technical: {
105 *adj_diff =
106 _calc.init_base_diff_vals.at(hand).at(TechBase).at(itv) *
107 pmod_product_cur_interval.at(ss) * basescalers.at(ss) /
108 std::max<float>(
109 fastpow(_calc.pmod_vals.at(hand).at(CJ).at(itv) + 0.05F,
110 2.F),
111 1.F);
112 } break;
113 default:
114 break;
115 }
116 }
117
118 virtual void apply_keymode_multipliers(
119 std::vector<float>& cur_iteration_skillset_vals) const
120 {
121
122 }
123
127 {
128 for (auto& hand : both_hands) {
129 for (auto& base : {TechBase}) {
130 // to be thorough: JackBase, CJBase, NPSBase, RMABase
131 auto& v = _calc.init_base_diff_vals.at(hand)[base];
132 std::fill(v.begin(), v.end(), 0.F);
133 }
134 _calc.jack_diff.at(hand).clear();
135 }
136 }
137
140 {
142 hand = 0;
143
144 full_hand_reset();
145 full_agnostic_reset();
146 reset_row_sequencing();
147
148 run_agnostic_pmod_loop();
149 run_dependent_pmod_loop();
150 }
151
152 virtual void full_agnostic_reset()
153 {
154 _gchordstream.full_reset();
155 _cj.full_reset();
156 _hb.full_reset();
157
158 _mri.get()->reset();
159 _last_mri.get()->reset();
160 }
161
162 virtual void setup_agnostic_pmods()
163 {
164
165 }
166
167 virtual void advance_agnostic_sequencing()
168 {
169 _hb.advance_sequencing(_mri->notes, _calc);
170 }
171
172 virtual void set_agnostic_pmods(const int& itv)
173 {
174 PatternMods::set_agnostic(
175 _gchordstream._pmod, _gchordstream(_mitvi), itv, _calc);
176 PatternMods::set_agnostic(_cj._pmod, _cj(_mitvi), itv, _calc);
177 PatternMods::set_agnostic(_hb._pmod, _hb(), itv, _calc);
178 }
179
180 virtual void run_agnostic_pmod_loop()
181 {
182 setup_agnostic_pmods();
183
184 for (auto itv = 0; itv < _calc.numitv; ++itv) {
185 for (auto row = 0; row < _calc.itv_size.at(itv); ++row) {
186
187 const auto& ri = _calc.adj_ni.at(itv).at(row);
188 (*_mri)(
189 *_last_mri, _mitvi, ri.row_time, ri.row_count, ri.row_notes);
190
191 advance_agnostic_sequencing();
192
193 // we only need to look back 1 metanoterow object, so we can
194 // swap the one we just built into last and recycle the two
195 // pointers instead of keeping track of everything
196 swap(_mri, _last_mri);
197 }
198
199 // run pattern mod generation for hand agnostic mods
200 set_agnostic_pmods(itv);
201
202 // reset any accumulated interval info and set cur index number
203 _mitvi.handle_interval_end();
204 }
205
206 PatternMods::run_agnostic_smoothing_pass(_calc.numitv, _calc);
207
208 // copy left -> right for agnostic mods
209 PatternMods::bruh_they_the_same(_calc.numitv, _calc);
210 }
211
212
213 virtual void reset_row_sequencing()
214 {
215 _mitvi.reset();
216 }
217
218 virtual void setup_dependent_mods()
219 {
220
221 }
222
223 virtual void set_dependent_pmods(const int& itv)
224 {
225 PatternMods::set_dependent(
226 hand, _gstream._pmod, _gstream(_mitvghi), itv, _calc);
227 PatternMods::set_dependent(
228 hand, _gbracketing._pmod, _gbracketing(_mitvghi), itv, _calc);
229 PatternMods::set_dependent(
230 hand, _hsw._pmod, _hsw(_mitvghi), itv, _calc);
231 }
232
233 virtual void full_hand_reset()
234 {
235 lazy_jacks.init(_calc.keycount);
236
237 _gstream.full_reset();
238 _gbracketing.full_reset();
239 _hsw.full_reset();
240
241 _mitvghi.zero();
242 _diffz.full_reset();
243 }
244
245 void set_sequenced_base_diffs(const int& itv) const override {
246 _calc.init_base_diff_vals.at(hand)[TechBase].at(itv) =
247 _diffz._tc.get_itv_diff(
248 _calc.init_base_diff_vals.at(hand)[NPSBase].at(itv), _calc);
249 }
250
251 virtual void handle_dependent_interval_end(const int& itv)
252 {
253 set_dependent_pmods(itv);
254
255 set_sequenced_base_diffs(itv);
256
257 _mitvghi.interval_end();
258 _diffz.interval_end();
259 }
260
261 virtual void run_dependent_pmod_loop() {
262 setup_dependent_mods();
263
264 hand = 0;
265 for (const auto& ids : _calc.hand_col_masks) {
266 full_hand_reset();
267 nps::actual_cancer(_calc, hand);
268 Smooth(_calc.init_base_diff_vals.at(hand).at(NPSBase),
269 0.F,
270 _calc.numitv);
271
272 auto row_time = s_init;
273 auto last_row_time = s_init;
274 auto any_ms = ms_init;
275 auto row_notes = 0u;
276 for (auto itv = 0; itv < _calc.numitv; ++itv) {
277 for (auto row = 0; row < _calc.itv_size.at(itv); row++) {
278 const auto& ri = _calc.adj_ni.at(itv).at(row);
279 row_time = ri.row_time;
280 row_notes = ri.row_notes;
281
282 _hsw.advance_sequencing(row_time, row_notes);
283
284 any_ms = ms_from(row_time, last_row_time);
285 auto masked_notes = row_notes & ids;
286
287 auto non_empty_cols = find_non_empty_cols(masked_notes);
288 if (non_empty_cols.empty()) {
289 continue;
290 }
291
292 for (auto& c : non_empty_cols) {
293 lazy_jacks(c, row_time);
294 }
295
296 // update counts
297 _mitvghi.handle_row(masked_notes, ids);
298
299 auto thing =
300 std::pair{ row_time,
301 ms_to_scaled_nps(
302 lazy_jacks.get_lowest_jack_ms(hand, _calc)) *
303 basescalers[Skill_JackSpeed] };
304 if (std::isnan(thing.second)) {
305 thing.second = 0.F;
306 }
307 _calc.jack_diff.at(hand).push_back(thing);
308
309 last_row_time = row_time;
310 }
311 handle_dependent_interval_end(itv);
312 }
313 PatternMods::run_dependent_smoothing_pass(_calc.numitv, _calc);
314
315 hand++;
316 }
317 }
318
319#if !defined(STANDALONE_CALC) && !defined(PHPCALC)
320 const std::string get_calc_param_xml() const override
321 {
322 return "Save/CalcParams_5k.xml";
323 }
324
325 void load_calc_params_internal(const XNode& params) const override
326 {
327 load_params_for_mod(&params, _cj._params, _cj.name);
328 load_params_for_mod(&params, _gbracketing._params, _gbracketing.name);
329 load_params_for_mod(&params, _gchordstream._params, _gchordstream.name);
330 load_params_for_mod(&params, _gstream._params, _gstream.name);
331 load_params_for_mod(&params, _hsw._params, _hsw.name);
332 }
333
334 XNode* make_param_node_internal(XNode* calcparams) const override
335 {
336 calcparams->AppendChild(
337 make_mod_param_node(_cj._params, _cj.name));
338 calcparams->AppendChild(
339 make_mod_param_node(_gbracketing._params, _gbracketing.name));
340 calcparams->AppendChild(
341 make_mod_param_node(_gchordstream._params, _gchordstream.name));
342 calcparams->AppendChild(
343 make_mod_param_node(_gstream._params, _gstream.name));
344 calcparams->AppendChild(
345 make_mod_param_node(_hsw._params, _hsw.name));
346
347 return calcparams;
348 }
349#endif
350};
351
Main driver class for the difficulty calculator as a whole.
Definition MinaCalc.h:82
std::array< std::array< std::vector< float >, NUM_CalcDiffValue >, num_hands > init_base_diff_vals
Definition MinaCalc.h:187
int numitv
Total number of intervals for the current file/rate (one per half second)
Definition MinaCalc.h:263
std::vector< std::array< RowInfo, max_rows_for_single_interval > > adj_ni
Definition MinaCalc.h:162
std::array< std::array< std::vector< float >, NUM_CalcPatternMod >, num_hands > pmod_vals
Definition MinaCalc.h:179
unsigned keycount
Assigns the keymode specific logic.
Definition MinaCalc.h:104
std::array< std::vector< std::pair< float, float > >, num_hands > jack_diff
Definition MinaCalc.h:239
std::vector< int > itv_size
Number of rows in each interval.
Definition MinaCalc.h:165
Definition XmlFile.h:95
Definition UlbuBase.h:16
Definition HandSwitch.h:13
Definition UlbuFiveKey.h:10
void operator()()
main driver for operations
Definition UlbuFiveKey.h:139
void reset_base_diffs()
Definition UlbuFiveKey.h:126
Definition SequencedBaseDiffCalc.h:1031
void interval_end()
handle end of interval
Definition MetaIntervalGenericHandInfo.h:160
void zero()
Definition MetaIntervalGenericHandInfo.h:173
static void actual_cancer(Calc &calc, const int &hand)
determine NPSBase, itv_points, CJBase for this hand
Definition SequencedBaseDiffCalc.h:68