Skip to content

Commit

Permalink
Utilize ReplaySnapshots to generate a ComboGraph for any Replay
Browse files Browse the repository at this point in the history
also remove some dead thing
also properly scale lifegraph and combograph on rates
  • Loading branch information
poco0317 committed Oct 18, 2019
1 parent 9f96ec5 commit 15075a7
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 12 deletions.
79 changes: 76 additions & 3 deletions src/Etterna/Models/Misc/PlayerAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,8 @@ PlayerAI::SetPlayerStageStatsForReplay(PlayerStageStats* pss)
// Life record
pss->m_fLifeRecord.clear();
pss->m_fLifeRecord = GenerateLifeRecordForReplay();
pss->m_ComboList.clear();
pss->m_ComboList = GenerateComboListForReplay();
}

pair<float, float>
Expand Down Expand Up @@ -866,15 +868,16 @@ PlayerAI::GenerateLifeRecordForReplay()
currentSnap++;
auto previousSnap = m_ReplaySnapshotMap.begin();
float lifeLevel = 0.5f;
const float rateUsed = pScoreData->GetMusicRate();

lifeRecord[0.f] = lifeLevel;

while (currentSnap != m_ReplaySnapshotMap.end()) {
float now = pReplayTiming->WhereUAtBro(currentSnap->first);
float now = pReplayTiming->WhereUAtBro(currentSnap->first) / rateUsed;
// these arrays are not unsigned so that if they somehow end up negative
// we dont sit here for a millenia waiting for it to finish
int differencesTNS[NUM_TapNoteScore];
int differencesHNS[NUM_HoldNoteScore];
int differencesTNS[NUM_TapNoteScore] = { 0 };
int differencesHNS[NUM_HoldNoteScore] = { 0 };
FOREACH_ENUM(TapNoteScore, tns)
{
differencesTNS[tns] = currentSnap->second.judgments[tns] -
Expand Down Expand Up @@ -907,3 +910,73 @@ PlayerAI::GenerateLifeRecordForReplay()

return lifeRecord;
}

vector<PlayerStageStats::Combo_t>
PlayerAI::GenerateComboListForReplay()
{
vector<PlayerStageStats::Combo_t> combos;
PlayerStageStats::Combo_t firstCombo;
const float rateUsed = pScoreData->GetMusicRate();

int taps = 0;

combos.push_back(firstCombo);
PlayerStageStats::Combo_t* curCombo = &combos[0];
auto currentSnap = m_ReplaySnapshotMap.begin();
currentSnap++;
auto previousSnap = m_ReplaySnapshotMap.begin();
auto snapOfComboStart = m_ReplaySnapshotMap.begin();

// very lazily end combos at any combo breaker and just start a new one
while (currentSnap != m_ReplaySnapshotMap.end()) {
// let me show you how to not write a loop
if (currentSnap->second.judgments[TNS_W4] -
snapOfComboStart->second.judgments[TNS_W4] >
0 ||
currentSnap->second.judgments[TNS_W5] -
snapOfComboStart->second.judgments[TNS_W5] >
0 ||
currentSnap->second.judgments[TNS_Miss] -
snapOfComboStart->second.judgments[TNS_Miss] >
0) {
taps += (currentSnap->second.judgments[TNS_W1] -
snapOfComboStart->second.judgments[TNS_W1]);
taps += (currentSnap->second.judgments[TNS_W2] -
snapOfComboStart->second.judgments[TNS_W2]);
taps += (currentSnap->second.judgments[TNS_W3] -
snapOfComboStart->second.judgments[TNS_W3]);
curCombo->m_cnt = taps;
taps = 0;
float starttime =
pReplayTiming->WhereUAtBro(snapOfComboStart->first) / rateUsed;
float finishtime =
pReplayTiming->WhereUAtBro(currentSnap->first) / rateUsed;
curCombo->m_fSizeSeconds = finishtime - starttime;
curCombo->m_fStartSecond = starttime;
PlayerStageStats::Combo_t nextcombo;
combos.emplace_back(nextcombo);
curCombo = &(combos.back());
snapOfComboStart = currentSnap;
currentSnap++;
}
currentSnap++;
}
ReplaySnapshot workingSnap = m_ReplaySnapshotMap.rbegin()->second;
taps += (workingSnap.judgments[TNS_W1] -
snapOfComboStart->second.judgments[TNS_W1]);
taps += (workingSnap.judgments[TNS_W2] -
snapOfComboStart->second.judgments[TNS_W2]);
taps += (workingSnap.judgments[TNS_W3] -
snapOfComboStart->second.judgments[TNS_W3]);
curCombo->m_cnt = taps;
float starttime =
pReplayTiming->WhereUAtBro(snapOfComboStart->first) / rateUsed;
float finishtime =
pReplayTiming->WhereUAtBro(m_ReplaySnapshotMap.rbegin()->first) /
rateUsed;
curCombo->m_fSizeSeconds = finishtime - starttime;
curCombo->m_fStartSecond = starttime;
// i feel sick

return combos;
}
8 changes: 5 additions & 3 deletions src/Etterna/Models/Misc/PlayerAI.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@

#include "GameConstantsAndTypes.h"
#include "HighScore.h"
#include "PlayerStageStats.h"

class NoteData;
class PlayerStageStats;
class PlayerState;
class TimingData;

const int NUM_SKILL_LEVELS = 6; // 0-5

// Basically contains a record for any given noterow of the essential info about
// the Player But only the info we can simply derive from the given ReplayData
struct ReplaySnapshot
Expand Down Expand Up @@ -118,6 +116,10 @@ class PlayerAI
// Given the Replay Data and Snapshot map, we can make a simple estimated
// life graph.
static map<float, float> GenerateLifeRecordForReplay();

// Given the Replay Data and Snapshot map, we can make a simple estimate
// combo graph.
static vector<PlayerStageStats::Combo_t> GenerateComboListForReplay();
};

#endif
9 changes: 4 additions & 5 deletions src/Etterna/Screen/Gameplay/ScreenGameplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
#include "Etterna/Models/NoteData/NoteDataUtil.h"
#include "Etterna/Models/NoteData/NoteDataWithScoring.h"
#include "Etterna/Actor/Gameplay/Player.h"
#include "Etterna/Models/Misc/PlayerAI.h" // for NUM_SKILL_LEVELS
#include "Etterna/Models/Misc/PlayerAI.h"
#include "Etterna/Models/Misc/PlayerState.h"
#include "Etterna/Singletons/PrefsManager.h"
#include "Etterna/Models/Misc/Profile.h" // for replay data stuff
#include "Etterna/Models/Misc/Profile.h"
#include "Etterna/Singletons/ProfileManager.h"
#include "RageUtil/Misc/RageLog.h"
#include "RageUtil/Sound/RageSoundReader.h"
Expand Down Expand Up @@ -566,10 +566,9 @@ ScreenGameplay::LoadNextSong()
if (GAMESTATE->IsCpuPlayer(m_vPlayerInfo.GetStepsAndTrailIndex())) {
m_vPlayerInfo.GetPlayerState()->m_PlayerController = PC_CPU;
int iMeter = pSteps->GetMeter();
int iNewSkill =
SCALE(iMeter, MIN_METER, MAX_METER, 0, NUM_SKILL_LEVELS - 1);
int iNewSkill = SCALE(iMeter, MIN_METER, MAX_METER, 0, 5);
/* Watch out: songs aren't actually bound by MAX_METER. */
iNewSkill = clamp(iNewSkill, 0, NUM_SKILL_LEVELS - 1);
iNewSkill = clamp(iNewSkill, 0, 5);
m_vPlayerInfo.GetPlayerState()->m_iCpuSkill = iNewSkill;
} else {
if (m_vPlayerInfo.GetPlayerState()
Expand Down
3 changes: 2 additions & 1 deletion src/Etterna/Screen/Gameplay/ScreenGameplayReplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,9 @@ ScreenGameplayReplay::StageFinished(bool bBackedOut)
return;
}

auto pss = m_vPlayerInfo.GetPlayerStageStats();
// Makes sure all PlayerStageStats discrepancies are corrected forcibly.
PlayerAI::SetPlayerStageStatsForReplay(m_vPlayerInfo.GetPlayerStageStats());
PlayerAI::SetPlayerStageStatsForReplay(pss);

STATSMAN->m_CurStageStats.FinalizeScores(false);

Expand Down
1 change: 1 addition & 0 deletions src/Etterna/Screen/Others/ScreenSelectMusic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,7 @@ class LunaScreenSelectMusic : public Luna<ScreenSelectMusic>
score->GetHoldNoteScore((HoldNoteScore)i);
}
pss.m_fLifeRecord = PlayerAI::GenerateLifeRecordForReplay();
pss.m_ComboList = PlayerAI::GenerateComboListForReplay();
ss.m_vpPlayedSongs.emplace_back(GAMESTATE->m_pCurSong);
ss.m_vpPossibleSongs.emplace_back(GAMESTATE->m_pCurSong);
STATSMAN->m_CurStageStats = ss;
Expand Down

0 comments on commit 15075a7

Please sign in to comment.