Etterna 0.75.1
Loading...
Searching...
No Matches
Replay.h
1#ifndef REPLAY_H
2#define REPLAY_H
3
4#include "Etterna/Models/Misc/EnumHelper.h"
5#include "ReplayConstantsAndTypes.h"
6#include "Etterna/Models/NoteData/NoteData.h"
7#include <set>
8
9struct HighScore;
10class TimingData;
11class Steps;
12class Style;
13
14class Replay
15{
16 public:
17 Replay();
18 Replay(const HighScore* hs);
19 Replay(std::string chartKey,
20 float musicRate,
21 float songOffset,
22 float globalOffset,
23 int rngSeed);
24 ~Replay();
25
26 inline const std::string GetBasicPath() const
27 {
28 return BASIC_REPLAY_DIR + scoreKey;
29 }
30
31 inline const std::string GetFullPath() const
32 {
33 return FULL_REPLAY_DIR + scoreKey;
34 }
35
36 inline const std::string GetInputPath() const
37 {
38 return INPUT_DATA_DIR + scoreKey;
39 }
40
41 inline const std::string GetOnlinePath() const
42 {
43 return ONLINE_DATA_DIR + scoreKey;
44 }
45
46 const std::vector<float>& GetOffsetVector() const
47 {
48 return vOffsetVector;
49 }
50 std::vector<float> GetCopyOfOffsetVector() const
51 {
52 return vOffsetVector;
53 }
54 void SetOffsetVector(const std::vector<float>& v) { vOffsetVector = v; }
55
56 const std::vector<int>& GetNoteRowVector() const
57 {
58 return vNoteRowVector;
59 }
60 std::vector<int> GetCopyOfNoteRowVector() const
61 {
62 return vNoteRowVector;
63 }
64 void SetNoteRowVector(const std::vector<int>& v) { vNoteRowVector = v; }
65
66 const std::vector<int>& GetTrackVector() const
67 {
68 return vTrackVector;
69 }
70 std::vector<int> GetCopyOfTrackVector() const
71 {
72 return vTrackVector;
73 }
74 void SetTrackVector(const std::vector<int>& v) { vTrackVector = v; }
75
76 const std::vector<TapNoteType>& GetTapNoteTypeVector() const
77 {
78 return vTapNoteTypeVector;
79 }
80 std::vector<TapNoteType> GetCopyOfTapNoteTypeVector() const
81 {
82 return vTapNoteTypeVector;
83 }
84 void SetTapNoteTypeVector(const std::vector<TapNoteType>& v)
85 {
86 vTapNoteTypeVector = v;
87 }
88
89 const std::vector<HoldReplayResult>& GetHoldReplayDataVector() const
90 {
91 return vHoldReplayDataVector;
92 }
93 std::vector<HoldReplayResult> GetCopyOfHoldReplayDataVector() const
94 {
95 return vHoldReplayDataVector;
96 }
97 void SetHoldReplayDataVector(const std::vector<HoldReplayResult>& v)
98 {
99 vHoldReplayDataVector = v;
100 }
101
102 const std::vector<MineReplayResult>& GetMineReplayDataVector() const
103 {
104 return vMineReplayDataVector;
105 }
106 std::vector<MineReplayResult> GetCopyOfMineReplayDataVector() const
107 {
108 return vMineReplayDataVector;
109 }
110 void SetMineReplayDataVector(const std::vector<MineReplayResult>& v)
111 {
112 vMineReplayDataVector = v;
113 }
114
115 const std::vector<float>& GetOnlineReplayTimestampVector() const
116 {
117 return vOnlineReplayTimestampVector;
118 }
119 std::vector<float> GetCopyOfOnlineReplayTimestampVector() const
120 {
121 return vOnlineReplayTimestampVector;
122 }
123 void SetOnlineReplayTimestampVector(const std::vector<float>& v)
124 {
125 vOnlineReplayTimestampVector = v;
126 }
127
128 const std::vector<InputDataEvent>& GetInputDataVector() const
129 {
130 return InputData;
131 }
132 std::vector<InputDataEvent> GetCopyOfInputDataVector() const
133 {
134 return InputData;
135 }
136 void SetInputDataVector(const std::vector<InputDataEvent>& v)
137 {
138 InputData = v;
139 }
140
141 const std::vector<MissReplayResult>& GetMissReplayDataVector() const
142 {
143 return vMissReplayDataVector;
144 }
145 std::vector<MissReplayResult> GetCopyOfMissReplayDataVector() const
146 {
147 return vMissReplayDataVector;
148 }
149 void SetMissReplayDataVector(const std::vector<MissReplayResult>& v)
150 {
151 vMissReplayDataVector = v;
152 }
153
154 const std::map<int, ReplaySnapshot>& GetReplaySnapshotMap() const
155 {
156 return m_ReplaySnapshotMap;
157 }
158 std::map<int, ReplaySnapshot> GetCopyOfReplaySnapshotMap() const
159 {
160 return m_ReplaySnapshotMap;
161 }
162 void SetReplaySnapshotMap(const std::map<int, ReplaySnapshot>& m)
163 {
164 m_ReplaySnapshotMap = m;
165 }
166
167 JudgeInfo& GetJudgeInfo() { return judgeInfo; }
168 JudgeInfo GetCopyOfJudgeInfo() const { return judgeInfo; }
169 void SetJudgeInfo(const JudgeInfo& ji) { judgeInfo = ji; }
170
171 std::string GetScoreKey() const { return scoreKey; }
172 void SetScoreKey(std::string& key) { scoreKey = key; }
173 std::string GetChartKey() const { return chartKey; }
174 void SetChartKey(std::string& key) { chartKey = key; }
175 float GetMusicRate() const { return fMusicRate; }
176 void SetMusicRate(float f) { fMusicRate = f; }
177 float GetSongOffset() const { return fSongOffset; }
178 void SetSongOffset(float f) { fSongOffset = f; }
179 float GetGlobalOffset() const { return fGlobalOffset; }
180 void SetGlobalOffset(float f) { fGlobalOffset = f; }
181 int GetRngSeed() const { return rngSeed; }
182 void SetRngSeed(int seed) { rngSeed = seed; }
183 std::string GetModifiers() const { return mods; }
184 void SetModifiers(std::string& modstr) { mods = modstr; }
185
186 void SetUseReprioritizedNoteRows(bool b)
187 {
188 if (b != useReprioritizedNoterows) {
189 if (IsOnlineScore()) {
190 if (vOnlineNoteRowVector.empty() &&
192 // initial backup
193 vOnlineOffsetVector = GetCopyOfOffsetVector();
194 vOnlineNoteRowVector = GetCopyOfNoteRowVector();
195 vOnlineTrackVector = GetCopyOfTrackVector();
196 vOnlineTapNoteTypeVector = GetCopyOfTapNoteTypeVector();
197 }
198 }
199 ClearPrimitiveVectors();
200 ClearReprioritizedVectors();
201 }
202 if (generatedInputData) {
203 InputData.clear();
204 vMissReplayDataVector.clear();
205 vHoldReplayDataVector.clear();
206 vMineReplayDataVector.clear();
207 generatedInputData = false;
208 }
209 useReprioritizedNoterows = b;
210 }
211 bool UsingReprioritizedNoteRows()
212 {
213 return useReprioritizedNoterows;
214 }
215 const std::vector<MissReplayResult>& GetReprioritizedMissData() const
216 {
217 return vReprioritizedMissData;
218 }
219 std::vector<MissReplayResult> GetCopyOfReprioritizedMissData() const
220 {
221 return vReprioritizedMissData;
222 }
223 void SetReprioritizedMissData(const std::vector<MissReplayResult>& v) {
224 vReprioritizedMissData = v;
225 }
226 const std::vector<HoldReplayResult>& GetReprioritizedHoldData() const
227 {
228 return vReprioritizedHoldData;
229 }
230 std::vector<HoldReplayResult> GetCopyOfReprioritizedHoldData() const
231 {
232 return vReprioritizedHoldData;
233 }
234 void SetReprioritizedHoldData(const std::vector<HoldReplayResult>& v)
235 {
236 vReprioritizedHoldData = v;
237 }
238 const std::vector<MineReplayResult>& GetReprioritizedMineData() const
239 {
240 return vReprioritizedMineData;
241 }
242 std::vector<MineReplayResult> GetCopyOfReprioritizedMineData() const
243 {
244 return vReprioritizedMineData;
245 }
246 void SetReprioritizedMineData(const std::vector<MineReplayResult>& v)
247 {
248 vReprioritizedMineData = v;
249 }
250
251 const std::vector<MissReplayResult>& GetRelevantMissData() const
252 {
253 if (useReprioritizedNoterows) {
254 return vReprioritizedMissData;
255 } else {
256 return vMissReplayDataVector;
257 }
258 }
259 const std::vector<HoldReplayResult>& GetRelevantHoldData() const
260 {
261 if (useReprioritizedNoterows) {
262 return vReprioritizedHoldData;
263 } else {
264 return vHoldReplayDataVector;
265 }
266 }
267 const std::vector<MineReplayResult>& GetRelevantMineData() const
268 {
269 if (useReprioritizedNoterows) {
270 return vReprioritizedMineData;
271 } else {
272 return vMineReplayDataVector;
273 }
274 }
275
276 void IngestInputData(bool ispress,
277 int col,
278 int row,
279 float musicsecs,
280 float offset,
281 TapNoteType tnt,
282 TapNoteSubType tnst)
283 {
284 InputData.emplace_back(
285 ispress, col, musicsecs, row, -offset, tnt, tnst);
286 }
287
288 void IngestHoldDrop(int col, int row, TapNoteSubType tnst)
289 {
291 hrr.row = row;
292 hrr.track = col;
293 hrr.subType = tnst;
294 vHoldReplayDataVector.push_back(hrr);
295 }
296
297 void IngestMineHit(int col, int row)
298 {
300 mrr.row = row;
301 mrr.track = col;
302 vMineReplayDataVector.push_back(mrr);
303 }
304
305 void IngestMissData(int col, int row, TapNoteType tnt, TapNoteSubType tnst)
306 {
308 mrr.row = row;
309 mrr.track = col;
310 mrr.tapNoteType = tnt;
311 mrr.tapNoteSubType = tnst;
312 vMissReplayDataVector.push_back(mrr);
313 }
314
315 void IngestV2Data(int col, int row, float offset, TapNoteType tnt)
316 {
317 vTrackVector.push_back(col);
318 vNoteRowVector.push_back(row);
319 vOffsetVector.push_back(offset);
320 vTapNoteTypeVector.push_back(tnt);
321 }
322
323 ReplayType GetReplayType() const
324 {
325 if (!InputData.empty()) {
326 // detailed data
327 return ReplayType_Input;
328 } else if (!vTrackVector.empty()) {
329 // column data
330 return ReplayType_V2;
331 } else if (!vNoteRowVector.empty()) {
332 // no column/extra data
333 return ReplayType_V1;
334 } else {
335 // it probably isn't loaded
336 return ReplayType_Invalid;
337 }
338 }
339
341 bool HasColumnData() const
342 {
343 const auto t = GetReplayType();
344 return t >= ReplayType_V2 && t < NUM_ReplayType;
345 }
346
347 bool WriteReplayData();
348 bool WriteInputData();
349 bool LoadReplayData();
350 bool HasReplayData() const;
351 bool HasWrittenReplayData() const;
352
356
363 bool GenerateInputData();
364
368
370 std::map<int, std::vector<PlaybackEvent>> GeneratePlaybackEvents(
371 int startRow = 0);
372
374 std::map<int, std::vector<PlaybackEvent>>
376
378 bool GenerateJudgeInfoAndReplaySnapshots(int startingRow = 0,
379 float timingScale = 1.F);
380
381 // Instead of making some complex iterator...
382 // Just offer both solutions
385 std::map<int, std::set<int>> GenerateDroppedHoldColumnsToRowsMap(
386 int startRow = 0);
389 std::map<int, std::set<int>> GenerateDroppedHoldRowsToColumnsMap(
390 int startRow = 0);
391
393 std::map<int, std::set<int>> GenerateDroppedHoldColumnsToRowsMapFromHead();
394
396 void ValidateOffsets();
397
405
410
415
416 HighScore* GetHighScore() const;
417 Steps* GetSteps() const;
418 NoteData GetNoteData(Steps* pSteps = nullptr, bool bTransform = true);
419 TimingData* GetTimingData() const;
420 const Style* GetStyle() const;
421
422 std::shared_ptr<ReplaySnapshot> GetReplaySnapshotForNoterow(int row);
423
426
427 bool IsOnlineScore() const
428 {
429 return scoreKey.find("Online_") != std::string::npos;
430 }
431
432 bool IsSpectateScore() const
433 {
434 return scoreKey.find("SPECTATE") != std::string::npos;
435 }
436
437 void Unload()
438 {
439 useReprioritizedNoterows = false;
440 generatedInputData = false;
441
442 // stats
443 m_ReplaySnapshotMap.clear();
444
445 ClearReprioritizedVectors();
446
447 // replay data
448 ClearPrimitiveVectors();
449
450 InputData.clear();
451 vMissReplayDataVector.clear();
452 vHoldReplayDataVector.clear();
453 vMineReplayDataVector.clear();
454
455 InputData.shrink_to_fit();
456 vMissReplayDataVector.shrink_to_fit();
457 vHoldReplayDataVector.shrink_to_fit();
458 vMineReplayDataVector.shrink_to_fit();
459
460 // extra online data "backups"
461 vOnlineOffsetVector.clear();
462 vOnlineNoteRowVector.clear();
463 vOnlineTrackVector.clear();
464 vOnlineTapNoteTypeVector.clear();
465 vOnlineOffsetVector.shrink_to_fit();
466 vOnlineNoteRowVector.shrink_to_fit();
467 vOnlineTrackVector.shrink_to_fit();
468 vOnlineTapNoteTypeVector.shrink_to_fit();
469 }
470
473 void SetHighScoreMods();
474
476 void PushSelf(lua_State* L);
477
478 private:
479 bool LoadReplayDataBasic(const std::string& replayDir = BASIC_REPLAY_DIR);
480 bool LoadReplayDataFull(const std::string& replayDir = FULL_REPLAY_DIR);
481 bool LoadInputData(const std::string& replayDir = INPUT_DATA_DIR);
482 bool LoadOnlineDataFromDisk(const std::string& replayDir = ONLINE_DATA_DIR);
483 bool LoadStoredOnlineData();
484
488 bool GenerateReplayV2DataPresumptively();
489
490 void ClearPrimitiveVectors() {
491 vOffsetVector.clear();
492 vNoteRowVector.clear();
493 vTrackVector.clear();
494 vTapNoteTypeVector.clear();
495 vOnlineReplayTimestampVector.clear();
496
497 vOffsetVector.shrink_to_fit();
498 vNoteRowVector.shrink_to_fit();
499 vTrackVector.shrink_to_fit();
500 vTapNoteTypeVector.shrink_to_fit();
501 vOnlineReplayTimestampVector.shrink_to_fit();
502 }
503
504 void ClearReprioritizedVectors() {
505 vReprioritizedMissData.clear();
506 vReprioritizedHoldData.clear();
507 vReprioritizedMineData.clear();
508 vReprioritizedMissData.shrink_to_fit();
509 vReprioritizedHoldData.shrink_to_fit();
510 vReprioritizedMineData.shrink_to_fit();
511 }
512
513 std::map<int, ReplaySnapshot> m_ReplaySnapshotMap{};
514 JudgeInfo judgeInfo{};
515
516 // optimization for ReplaySnapshot generation
517 // filled out by RegenerateJudgmentInfo
518 std::set<int> significantNoterows{};
519
520 // for snapshot stuff and rescoring
521 // set by Lua, data filled by ReprioritizeInputData
522 bool useReprioritizedNoterows = false;
523 std::vector<MissReplayResult> vReprioritizedMissData{};
524 std::vector<MineReplayResult> vReprioritizedMineData{};
525 std::vector<HoldReplayResult> vReprioritizedHoldData{};
526
527 std::string scoreKey{};
528 std::string chartKey{};
529 float fMusicRate = 1.F;
530 float fSongOffset = 0.F;
531 float fGlobalOffset = 0.F;
532 std::string mods{};
533 int rngSeed = 0;
534
535 std::vector<InputDataEvent> InputData{};
536 std::vector<MissReplayResult> vMissReplayDataVector{};
537 std::vector<float> vOffsetVector{};
538 std::vector<int> vNoteRowVector{};
539 std::vector<int> vTrackVector{};
540 std::vector<TapNoteType> vTapNoteTypeVector{};
541 std::vector<HoldReplayResult> vHoldReplayDataVector{};
542 std::vector<MineReplayResult> vMineReplayDataVector{};
543 std::vector<float> vOnlineReplayTimestampVector{};
544
545 // mainly useful for the noterow reprioritization stuff
546 // because if we switch that and it is generated, force generate
547 // the reason is that given only v2, we generate inputdata
548 // that input data outputs a separate set of v2 data
549 // and reloading that v2 data generates wrong input data
550 // so this just refreshes the whole process
551 bool generatedInputData = false;
552
553 // if we failed to load data, dont try again and waste time
554 bool attemptedToLoadInputData = false;
555 bool loadResultInputData = false;
556 bool attemptedToLoadReplayV2 = false;
557 bool loadResultReplayV2 = false;
558 bool attemptedToLoadReplayV1 = false;
559 bool loadResultReplayV1 = false;
560
561 bool LoadedInputData(bool b) {
562 attemptedToLoadInputData = true;
563 loadResultInputData = b;
564 return b;
565 }
566 bool LoadedReplayV2(bool b) {
567 attemptedToLoadReplayV2 = true;
568 loadResultReplayV2 = b;
569 return b;
570 }
571 bool LoadedReplayV1(bool b) {
572 attemptedToLoadReplayV1 = true;
573 loadResultReplayV1 = b;
574 return b;
575 }
576
578 // storage of vectors temporarily for online scores only
579 std::vector<float> vOnlineOffsetVector{};
580 std::vector<int> vOnlineNoteRowVector{};
581 std::vector<int> vOnlineTrackVector{};
582 std::vector<TapNoteType> vOnlineTapNoteTypeVector{};
584};
585
586#endif
Holds data about the notes that the player is supposed to hit.
Definition NoteData.h:43
Definition Replay.h:15
void VerifyInputDataAndReplayData()
Definition Replay.cpp:2452
std::map< int, std::set< int > > GenerateDroppedHoldRowsToColumnsMap(int startRow=0)
Definition Replay.cpp:3168
std::map< int, std::vector< PlaybackEvent > > GeneratePlaybackEvents(int startRow=0)
Generate events used for playing back replay in gameplay.
Definition Replay.cpp:3036
void ValidateOffsets()
Offsets can be really weird - Remove all impossible offsets.
Definition Replay.cpp:1856
bool WriteInputData()
Definition Replay.cpp:425
bool ValidateInputDataNoterows()
Definition Replay.cpp:1897
bool ReprioritizeInputData()
Definition Replay.cpp:2642
void SetHighScoreMods()
Definition Replay.cpp:248
void VerifyGeneratedInputDataMatchesReplayData()
Definition Replay.cpp:2275
bool GeneratePrimitiveVectors()
Definition Replay.cpp:1429
std::map< int, std::set< int > > GenerateDroppedHoldColumnsToRowsMapFromHead()
Generate the event required for spectator playback.
Definition Replay.cpp:3151
void PushSelf(lua_State *L)
Lua.
std::map< int, std::vector< PlaybackEvent > > GeneratePlaybackEventForInputDataHead()
Generate an event for replay playback for only one InputData element.
Definition Replay.cpp:3096
bool FillInBlanksForInputData()
Definition Replay.cpp:1179
bool GenerateInputData()
Generate InputData using any ReplayData.
Definition Replay.cpp:2890
bool GenerateNoterowsFromTimestamps()
Generate Noterow vector using online timestamp replay format.
Definition Replay.cpp:1789
std::map< int, std::set< int > > GenerateDroppedHoldColumnsToRowsMap(int startRow=0)
Definition Replay.cpp:3132
bool HasColumnData() const
true for V2 and InputData
Definition Replay.h:341
bool GenerateJudgeInfoAndReplaySnapshots(int startingRow=0, float timingScale=1.F)
For Stats and ReplaySnapshots.
Definition Replay.cpp:3187
bool CanSafelyTransformNoteData()
A check to see if the Replay has an RNG seed, if it uses shuffle.
Definition Replay.cpp:269
Holds note information for a Song.
Definition Steps.h:42
Definition Style.h:22
Holds data for translating beats<->seconds.
Definition TimingData.h:54
The high score that is earned by a player.
Definition HighScore.h:18
Definition ReplayConstantsAndTypes.h:143
Definition ReplayConstantsAndTypes.h:228
Definition ReplayConstantsAndTypes.h:106
Definition ReplayConstantsAndTypes.h:118