diff --git a/src/Etterna/Actor/Gameplay/PlayerPractice.cpp b/src/Etterna/Actor/Gameplay/PlayerPractice.cpp index f6a3c5532d..59db6ea485 100644 --- a/src/Etterna/Actor/Gameplay/PlayerPractice.cpp +++ b/src/Etterna/Actor/Gameplay/PlayerPractice.cpp @@ -7,6 +7,7 @@ #include "Etterna/Models/Misc/Game.h" #include "Etterna/Models/NoteData/NoteDataWithScoring.h" #include "Etterna/Models/ScoreKeepers/ScoreKeeperNormal.h" +#include "Etterna/Models/StepsAndStyles/Steps.h" #include "Etterna/Singletons/GameState.h" #include "Etterna/Singletons/NoteSkinManager.h" #include "Etterna/Singletons/StatsManager.h" @@ -64,6 +65,9 @@ PlayerPractice::Update(float fDeltaTime) // Tell the NoteField we pressed (or didnt press) certain columns UpdatePressedFlags(); + if (!countStats) + return; + // Tell Rolls to update (if in Autoplay) // Tell Holds to update (lose life) UpdateHoldsAndRolls(fDeltaTime, now); @@ -73,12 +77,84 @@ PlayerPractice::Update(float fDeltaTime) // Check for completely judged rows. UpdateJudgedRows(fDeltaTime); + UpdateTapNotesMissedOlderThan(GetMaxStepDistanceSeconds()); } +void +PlayerPractice::Step(int col, + int row, + const std::chrono::steady_clock::time_point& tm, + bool bHeld, + bool bRelease, + float padStickSeconds) +{ + if (!countStats) { + // big brained override to toggle this boolean and do everything else + // normally + countStats = true; + + // reset all iterators to this point so we can ignore the things we dont + // care about + const float fSongTime = GAMESTATE->m_Position.m_fMusicSeconds; + const float fNotesBeatAdjusted = + GAMESTATE->m_pCurSteps->GetTimingData()->GetBeatFromElapsedTime( + fSongTime - GetMaxStepDistanceSeconds()); + const float fNotesBeat = + GAMESTATE->m_pCurSteps->GetTimingData()->GetBeatFromElapsedTime( + fSongTime); + const int rowNowAdjusted = BeatToNoteRow(fNotesBeatAdjusted); + const int rowNow = BeatToNoteRow(fNotesBeat); + + SAFE_DELETE(m_pIterNeedsTapJudging); + m_pIterNeedsTapJudging = new NoteData::all_tracks_iterator( + m_NoteData.GetTapNoteRangeAllTracks(rowNowAdjusted, MAX_NOTE_ROW)); + + SAFE_DELETE(m_pIterNeedsHoldJudging); + m_pIterNeedsHoldJudging = new NoteData::all_tracks_iterator( + m_NoteData.GetTapNoteRangeAllTracks(rowNowAdjusted, MAX_NOTE_ROW)); + + SAFE_DELETE(m_pIterUncrossedRows); + m_pIterUncrossedRows = new NoteData::all_tracks_iterator( + m_NoteData.GetTapNoteRangeAllTracks(rowNow, MAX_NOTE_ROW)); + + SAFE_DELETE(m_pIterUnjudgedRows); + m_pIterUnjudgedRows = new NoteData::all_tracks_iterator( + m_NoteData.GetTapNoteRangeAllTracks(rowNowAdjusted, MAX_NOTE_ROW)); + + SAFE_DELETE(m_pIterUnjudgedMineRows); + m_pIterUnjudgedMineRows = new NoteData::all_tracks_iterator( + m_NoteData.GetTapNoteRangeAllTracks(rowNow, MAX_NOTE_ROW)); + } + + // then just do the normal stuff + Player::Step(col, row, tm, bHeld, bRelease, padStickSeconds); +} + void PlayerPractice::PositionReset() { // Reset stage stats and stuff countStats = false; + + curwifescore = 0; + maxwifescore = 0; + + FOREACH_ENUM(TapNoteScore, tns) + m_pPlayerStageStats->m_iTapNoteScores[tns] = 0; + FOREACH_ENUM(TapNoteScore, hns) + m_pPlayerStageStats->m_iHoldNoteScores[hns] = 0; + + m_pPlayerStageStats->m_fWifeScore = 0; + m_pPlayerStageStats->CurWifeScore = 0; + m_pPlayerStageStats->MaxWifeScore = 0; + m_pPlayerStageStats->m_vOffsetVector.clear(); + m_pPlayerStageStats->m_vNoteRowVector.clear(); + m_pPlayerStageStats->m_vTrackVector.clear(); + m_pPlayerStageStats->m_vTapNoteTypeVector.clear(); + m_pPlayerStageStats->m_vHoldReplayData.clear(); + m_pPlayerStageStats->m_iCurCombo = 0; + m_pPlayerStageStats->m_iMaxCombo = 0; + m_pPlayerStageStats->m_iCurMissCombo = 0; + m_pPlayerStageStats->m_radarActual.Zero(); } diff --git a/src/Etterna/Actor/Gameplay/PlayerPractice.h b/src/Etterna/Actor/Gameplay/PlayerPractice.h index 6187e795e6..b11df7c28a 100644 --- a/src/Etterna/Actor/Gameplay/PlayerPractice.h +++ b/src/Etterna/Actor/Gameplay/PlayerPractice.h @@ -17,6 +17,13 @@ class PlayerPractice : public Player ScoreKeeper* pPrimaryScoreKeeper) override; void Update(float fDeltaTime) override; + void Step(int col, + int row, + const std::chrono::steady_clock::time_point& tm, + bool bHeld, + bool bRelease, + float padStickSeconds = 0.0f) override; + // When called, resets stage stats and necessary things // Also sets countStats to false. void PositionReset(); diff --git a/src/Etterna/Screen/Gameplay/ScreenGameplayPractice.cpp b/src/Etterna/Screen/Gameplay/ScreenGameplayPractice.cpp index 14aea1513a..6604fbfde6 100644 --- a/src/Etterna/Screen/Gameplay/ScreenGameplayPractice.cpp +++ b/src/Etterna/Screen/Gameplay/ScreenGameplayPractice.cpp @@ -18,6 +18,7 @@ #include "Etterna/Models/NoteData/NoteDataUtil.h" #include "Etterna/Models/NoteData/NoteData.h" #include "Etterna/Actor/Gameplay/Player.h" +#include "Etterna/Actor/Gameplay/PlayerPractice.h" #include "Etterna/Models/Misc/RadarValues.h" #include "Etterna/Singletons/DownloadManager.h" #include "Etterna/Singletons/GameSoundManager.h" @@ -30,8 +31,11 @@ REGISTER_SCREEN_CLASS(ScreenGameplayPractice); void ScreenGameplayPractice::FillPlayerInfo(PlayerInfo* playerInfoOut) { - playerInfoOut->Load( - PLAYER_1, MultiPlayer_Invalid, true, Difficulty_Invalid); + playerInfoOut->Load(PLAYER_1, + MultiPlayer_Invalid, + true, + Difficulty_Invalid, + GameplayMode_Practice); } ScreenGameplayPractice::ScreenGameplayPractice() @@ -230,32 +234,11 @@ ScreenGameplayPractice::SetSongPosition(float newSongPositionSeconds, pTiming->GetBeatFromElapsedTime(newSongPositionSeconds); const int rowNow = BeatToNoteRow(fNotesBeat); SetupNoteDataFromRow(pSteps, rowNow); - m_vPlayerInfo.m_pPlayer->RenderAllNotesIgnoreScores(); - - // curwifescore sent via judgment msgs is stored in player - auto pl = m_vPlayerInfo.m_pPlayer; - // but the tns counts are stored here - auto stats = m_vPlayerInfo.GetPlayerStageStats(); // Reset the wife/judge counter related visible stuff - pl->curwifescore = 0; - pl->maxwifescore = 0; - FOREACH_ENUM(TapNoteScore, tns) - stats->m_iTapNoteScores[tns] = 0; - FOREACH_ENUM(TapNoteScore, hns) - stats->m_iHoldNoteScores[hns] = 0; - stats->m_fWifeScore = 0; - stats->CurWifeScore = 0; - stats->MaxWifeScore = 0; - stats->m_vOffsetVector.clear(); - stats->m_vNoteRowVector.clear(); - stats->m_vTrackVector.clear(); - stats->m_vTapNoteTypeVector.clear(); - stats->m_vHoldReplayData.clear(); - stats->m_iCurCombo = 0; - stats->m_iMaxCombo = 0; - stats->m_iCurMissCombo = 0; - stats->m_radarActual.Zero(); + PlayerPractice* pl = static_cast(m_vPlayerInfo.m_pPlayer); + pl->RenderAllNotesIgnoreScores(); + pl->PositionReset(); // just having a message we can respond to directly is probably the best way // to reset lua elements rather than emulating a judgment message like