Skip to content

Commit

Permalink
Make PlayerAI Snapshots account for Misses if given NoteData
Browse files Browse the repository at this point in the history
  • Loading branch information
poco0317 committed Oct 4, 2019
1 parent a3c53dd commit 23f1e08
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 5 deletions.
85 changes: 83 additions & 2 deletions src/Etterna/Models/Misc/PlayerAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,13 @@ PlayerAI::ResetScoreData()
}

void
PlayerAI::SetScoreData(HighScore* pHighScore, int firstRow)
PlayerAI::SetScoreData(HighScore* pHighScore, int firstRow, NoteData* pNoteData)
{
bool successful = pHighScore->LoadReplayData();
pScoreData = pHighScore;
m_ReplayTapMap.clear();
m_ReplayHoldMap.clear();
m_ReplayExactTapMap.clear();
m_ReplaySnapshotMap.clear();

if (!successful) {
return;
Expand Down Expand Up @@ -142,7 +141,15 @@ PlayerAI::SetScoreData(HighScore* pHighScore, int firstRow)
}
}

// Misses don't always show up in Replay Data properly.
// We require the NoteData to validate the Judge count.
// If we don't have it, don't care.
if (pNoteData == nullptr)
return;

// Fill out the Snapshot map now that the other maps are not so out of order
// We leave out misses in this section because they aren't in the Replay
// Data
int tempJudgments[NUM_TapNoteScore] = { 0 };
int holdsDropped = 0;
for (auto r = validNoterows.begin(); r != validNoterows.end(); r++) {
Expand Down Expand Up @@ -179,6 +186,80 @@ PlayerAI::SetScoreData(HighScore* pHighScore, int firstRow)
rs.holdsDropped = holdsDropped;
m_ReplaySnapshotMap[*r] = rs;
}

// Now handle misses.
// For every row in notedata...
FOREACH_NONEMPTY_ROW_ALL_TRACKS(*pNoteData, row)
{
// For every track in the row...
for (int track = 0; track < pNoteData->GetNumTracks(); track++) {
// Find the tapnote we are on
TapNote* pTN = NULL;
NoteData::iterator iter = pNoteData->FindTapNote(track, row);
DEBUG_ASSERT(iter != pNoteData->end(track));
pTN = &iter->second;

if (iter != pNoteData->end(track)) {
// It is impossible to "miss" these notes
if (pTN->type == TapNoteType_Mine ||
pTN->type == TapNoteType_Fake ||
pTN->type == TapNoteType_HoldTail ||
pTN->type == TapNoteType_AutoKeysound)
continue;
// If this tap is missing from the replay data, we count it as a
// miss.
if (m_ReplayTapMap.count(row) != 0) {
bool found = false;
for (auto& trr : m_ReplayTapMap[row]) {
if (trr.track == track)
found = true;
}
if (!found) {
tempJudgments[TNS_Miss]++;
}
} else {
tempJudgments[TNS_Miss]++;
}
}
}
// We have to update every single row with the new miss counts.
// This unfortunately takes more time.
// If current row is recorded in the snapshots, update the miss count
if (m_ReplaySnapshotMap.count(row) != 0) {
m_ReplaySnapshotMap[row].judgments[TNS_Miss] =
tempJudgments[TNS_Miss];
} else {
// If the current row is after the last recorded row, make a new one
if (m_ReplaySnapshotMap.rbegin()->first < row) {
ReplaySnapshot rs;
FOREACH_ENUM(TapNoteScore, tns)
{
rs.judgments[tns] = tempJudgments[tns];
}
rs.holdsDropped = holdsDropped;
m_ReplaySnapshotMap[row] = rs;
}
// If the current row is before the earliest recorded row, make a
// new one
else if (m_ReplaySnapshotMap.begin()->first > row) {
ReplaySnapshot rs;
rs.judgments[TNS_Miss]++;
m_ReplaySnapshotMap[row] = rs;
} else // If the current row is in between recorded rows, copy an
// older one
{
ReplaySnapshot rs;
const int prev = m_ReplaySnapshotMap.lower_bound(row)->first;
FOREACH_ENUM(TapNoteScore, tns)
{
rs.judgments[tns] =
m_ReplaySnapshotMap[prev].judgments[tns];
}
rs.holdsDropped = m_ReplaySnapshotMap[prev].holdsDropped;
m_ReplaySnapshotMap[row] = rs;
}
}
}
}

void
Expand Down
4 changes: 3 additions & 1 deletion src/Etterna/Models/Misc/PlayerAI.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "GameConstantsAndTypes.h"
#include "HighScore.h"

class NoteData;
class PlayerStageStats;
class PlayerState;
class TimingData;
Expand Down Expand Up @@ -53,7 +54,8 @@ class PlayerAI

// Set the pointer to a HighScore
static void SetScoreData(HighScore* pHighScore = pScoreData,
int firstRow = 0);
int firstRow = 0,
NoteData* = nullptr);
static void ResetScoreData();

static float GetTapNoteOffsetForReplay(TapNote* pTN, int noteRow, int col);
Expand Down
4 changes: 2 additions & 2 deletions src/Etterna/Screen/Others/ScreenSelectMusic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,7 @@ class LunaScreenSelectMusic : public Luna<ScreenSelectMusic>
}

GAMESTATE->m_gameplayMode.Set(GameplayMode_Replay);
auto nd = GAMESTATE->m_pCurSteps->GetNoteData();

// we get timestamps not noterows when getting online replays from the
// site, since order is deterministic we'll just auto set the noterows
Expand All @@ -1631,7 +1632,6 @@ class LunaScreenSelectMusic : public Luna<ScreenSelectMusic>
GAMESTATE->m_pCurSteps->GetTimingData());
auto* td = GAMESTATE->m_pCurSteps->GetTimingData();
// vector<int> ihatemylife;
auto nd = GAMESTATE->m_pCurSteps->GetNoteData();
auto nerv = nd.BuildAndGetNerv();
/* functionally dead code, may be removed -poco
if (!hs->GetChordCohesion()) {
Expand Down Expand Up @@ -1673,7 +1673,7 @@ class LunaScreenSelectMusic : public Luna<ScreenSelectMusic>
hs->SetOffsetVector(offsets);
}

PlayerAI::SetScoreData(hs);
PlayerAI::SetScoreData(hs, 0, &nd);

// prepare old mods to return to
const RString oldMods =
Expand Down

0 comments on commit 23f1e08

Please sign in to comment.