From 2003f6936e230d684511159046ca6dc9ae1b11d6 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 00:01:52 -0600 Subject: [PATCH 01/43] Add optional extra information for TapReplayResult --- src/NoteTypes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NoteTypes.h b/src/NoteTypes.h index 2243047ecc..698f657d18 100644 --- a/src/NoteTypes.h +++ b/src/NoteTypes.h @@ -253,6 +253,7 @@ struct TapReplayResult int track; // column float offset; // 0 TapNoteType type; // typically mines, holds, rolls, etc + int offsetAdjustedRow; // row assigned later on for full replays }; extern TapNote TAP_EMPTY; // '0' From f63ea82f1aa6a6975ec8b57d1874396d0d8b750a Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 00:03:48 -0600 Subject: [PATCH 02/43] Specify and document new PlayerAI functions --- src/PlayerAI.cpp | 3 +++ src/PlayerAI.h | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/PlayerAI.cpp b/src/PlayerAI.cpp index 3a89362e84..12aa8bb5f0 100644 --- a/src/PlayerAI.cpp +++ b/src/PlayerAI.cpp @@ -52,6 +52,7 @@ static TapScoreDistribution g_Distributions[NUM_SKILL_LEVELS]; HighScore* PlayerAI::pScoreData = nullptr; map> PlayerAI::m_ReplayTapMap; map> PlayerAI::m_ReplayHoldMap; +map> PlayerAI::m_ReplayExactTapMap; void PlayerAI::InitFromDisk() @@ -157,6 +158,8 @@ PlayerAI::SetScoreData(HighScore* pHighScore) pScoreData = pHighScore; m_ReplayTapMap.clear(); m_ReplayHoldMap.clear(); + m_ReplayExactTapMap.clear(); + auto replayNoteRowVector = pHighScore->GetCopyOfNoteRowVector(); auto replayOffsetVector = pHighScore->GetCopyOfOffsetVector(); auto replayTapNoteTypeVector = pHighScore->GetCopyOfTapNoteTypeVector(); diff --git a/src/PlayerAI.h b/src/PlayerAI.h index 2973751c7c..58e8a814a2 100644 --- a/src/PlayerAI.h +++ b/src/PlayerAI.h @@ -25,6 +25,11 @@ class PlayerAI // A map with indices for each row of the chart, pointing to nothing or hold // drop results. static map> m_ReplayHoldMap; + // A map with indices for each row of the chart, pointing to nothing or a + // Normal Result. However, note that the rows within are actually calculated + // so that they are adjusted for offsets relative to the actual replay data/notedata. + // This map is only useful for charts with column data. + static map> m_ReplayExactTapMap; static void InitFromDisk(); static TapNoteScore GetTapNoteScore(const PlayerState* pPlayerState); @@ -35,6 +40,27 @@ class PlayerAI const PlayerState* pPlayerState, float fNoteOffset); static bool DetermineIfHoldDropped(int noteRow, int col); + // Returns the column that needs to be tapped. + // Returns -1 if no column needs to be tapped. + static int DetermineNextTapColumn(int noteRow, int searchRowDistance, TimingData* timing); + // Literally get the next row in the replay data. Disregard offset calculations. + static int GetNextRowNoOffsets(int currentRow); + // Reset and populate the ReplayExactTapMap. + // This is meant to be run once Gameplay begins. + static void SetUpExactTapMap(TimingData* timing); + // Check the Tap Replay Data to see if a tap is on this row + static bool TapExistsAtThisRow(int noteRow); + static bool TapExistsAtOrBeforeThisRow(int noteRow); + // Build a list of columns/tracks to tap based on the given noterow. + static vector GetTapsToTapForRow(int noteRow); + static int GetReplayType(); + // Build a list of columns/tracks that happened at or before the given noterow. + // (if we lag and somehow skip rows) + static vector GetTapsAtOrBeforeRow(int noteRow); + // Given a column and row, retrieve the adjusted row. + static int GetAdjustedRowFromUnadjustedCoordinates(int row, int col); + // Remove a given Tap from the fallback and Full replay data vectors + static void RemoveTapFromVectors(int row, int col); }; #endif From a6563b08049c208f3c79a0668964d8d67d37ae96 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 00:05:15 -0600 Subject: [PATCH 03/43] Implement new PlayerAI functions refactor something kind of --- src/PlayerAI.cpp | 311 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 284 insertions(+), 27 deletions(-) diff --git a/src/PlayerAI.cpp b/src/PlayerAI.cpp index 12aa8bb5f0..d40e4905e5 100644 --- a/src/PlayerAI.cpp +++ b/src/PlayerAI.cpp @@ -177,6 +177,9 @@ PlayerAI::SetScoreData(HighScore* pHighScore) { trr.track = replayTrackVector[i]; trr.type = replayTapNoteTypeVector[i]; + + + } else // Anything else (and we got this far without crashing) means // it's not a Full Replay { @@ -207,6 +210,90 @@ PlayerAI::SetScoreData(HighScore* pHighScore) } } +void +PlayerAI::SetUpExactTapMap(TimingData* timing) +{ + m_ReplayExactTapMap.clear(); + + // Don't continue if the replay doesn't have column data. + // We can't be accurate without it. + if (pScoreData->GetReplayType() != 2) + return; + + // For every row in the replay data... + for (auto& row : m_ReplayTapMap) + { + // Get the current time and go over all taps on this row... + float rowTime = timing->WhereUAtBro(row.first); + for (TapReplayResult& trr : row.second) + { + // Find the time adjusted for offset + // Then the beat according to that time + // Then the noterow according to that beat + float tapTime = rowTime + trr.offset; + float tapBeat = timing->GetBeatFromElapsedTime(tapTime); + int tapRow = BeatToNoteRow(tapBeat); + trr.offsetAdjustedRow = tapRow; + + // And put that into the exacttapmap :) + if (m_ReplayExactTapMap.count(tapRow) != 0) + { + m_ReplayExactTapMap[tapRow].push_back(trr); + } + else + { + vector trrVector = { trr }; + m_ReplayExactTapMap[tapRow] = trrVector; + } + } + + } + +} + +void +PlayerAI::RemoveTapFromVectors(int row, int col) +{ + if (m_ReplayTapMap.count(row) != 0) + { + for (int i = 0; i < (int)m_ReplayTapMap[row].size(); i++) + { + auto& trr = m_ReplayTapMap[row][i]; + if (trr.track == col) + { + m_ReplayTapMap[row].erase(m_ReplayTapMap[row].begin() + i); + if (m_ReplayTapMap[row].empty()) + m_ReplayTapMap.erase(row); + } + } + } + if (m_ReplayExactTapMap.count(row) != 0) { + for (int i = 0; i < (int)m_ReplayExactTapMap[row].size(); i++) { + auto& trr = m_ReplayExactTapMap[row][i]; + if (trr.track == col) { + m_ReplayExactTapMap[row].erase(m_ReplayExactTapMap[row].begin() + i); + if (m_ReplayExactTapMap[row].empty()) + m_ReplayExactTapMap.erase(row); + } + } + } +} + +int +PlayerAI::GetAdjustedRowFromUnadjustedCoordinates(int row, int col) +{ + int output = -1; + if (m_ReplayTapMap.count(row) != 0) + { + for (TapReplayResult& trr : m_ReplayTapMap[row]) + { + if (trr.track == col) + output = trr.offsetAdjustedRow; + } + } + return output; +} + bool PlayerAI::DetermineIfHoldDropped(int noteRow, int col) { @@ -216,7 +303,7 @@ PlayerAI::DetermineIfHoldDropped(int noteRow, int col) // LOG->Trace("Hold row exists in the data"); // It is, so let's go over each column, assuming we may have dropped // more than one hold at once. - for (auto hrr : m_ReplayHoldMap[noteRow]) { + for (auto& hrr : m_ReplayHoldMap[noteRow]) { // We found the column we are looking for if (hrr.track == col) { // LOG->Trace("KILL IT NOW"); @@ -227,6 +314,169 @@ PlayerAI::DetermineIfHoldDropped(int noteRow, int col) return false; } +int +PlayerAI::DetermineNextTapColumn(int noteRow, int searchRowDistance, TimingData* timing) +{ + // Cannot determine columns without column data. + if (pScoreData->GetReplayType() == 1) + return -1; + + float centralTime = timing->WhereUAtBro(noteRow); + float currentTime = 0.f; + int earliestColumn = -1; + float earliestColumnTime = 99999999.f; + + // For every row behind and in the future within a certain limit (in the replay data) + for (int i = noteRow - searchRowDistance; i != -1 && i < noteRow + searchRowDistance; + i = GetNextRowNoOffsets(i)) + { + if (m_ReplayTapMap.count(i) != 0) + { + currentTime = timing->WhereUAtBro(i); + for (auto& trr : m_ReplayTapMap[i]) + { + float tmpTime = currentTime + trr.offset; + if (tmpTime < earliestColumnTime) + { + earliestColumn = trr.track; + earliestColumnTime = tmpTime; + } + } + } + + + } + if (fabsf(centralTime - earliestColumnTime) < 1.f) { + return earliestColumn; + } + return -1; + + //return earliestColumn; +} + +bool +PlayerAI::TapExistsAtThisRow(int noteRow) +{ + // 2 is a replay with column data + if (pScoreData->GetReplayType() == 2) + { + return m_ReplayExactTapMap.count(noteRow) != 0; + } + else + { + return m_ReplayTapMap.count(noteRow) != 0; + } + +} + +bool +PlayerAI::TapExistsAtOrBeforeThisRow(int noteRow) +{ + // 2 is a replay with column data + if (pScoreData->GetReplayType() == 2) + { + return m_ReplayExactTapMap.lower_bound(0)->first <= noteRow; + } + else + { + return m_ReplayTapMap.lower_bound(0)->first <= noteRow; + } +} + +vector +PlayerAI::GetTapsAtOrBeforeRow(int noteRow) +{ + vector output; + + // 2 is a replay with column data + if (pScoreData->GetReplayType() == 2) + { + auto rowIt = m_ReplayExactTapMap.lower_bound(0); + int row = rowIt->first; + for (; row <= noteRow && row != -1;) + { + vector toMerge = GetTapsToTapForRow(row); + output.insert(output.end(), toMerge.begin(), toMerge.end()); + row = GetNextRowNoOffsets(row); + } + } + else + { + auto rowIt = m_ReplayTapMap.lower_bound(0); + int row = rowIt->first; + for (; row <= noteRow && row != -1;) { + vector toMerge = GetTapsToTapForRow(row); + output.insert(output.end(), toMerge.begin(), toMerge.end()); + row = GetNextRowNoOffsets(row); + } + } + return output; +} + +vector +PlayerAI::GetTapsToTapForRow(int noteRow) +{ + vector output; + + // 2 is a replay with column data + if (pScoreData->GetReplayType() == 2) + { + if (m_ReplayExactTapMap.count(noteRow) != 0) + { + for (auto& trr : m_ReplayExactTapMap[noteRow]) + { + output.push_back(trr); + } + } + } + else + { + if (m_ReplayTapMap.count(noteRow) != 0) + { + for (auto& trr : m_ReplayTapMap[noteRow]) + { + output.push_back(trr); + } + } + } + return output; +} + +int +PlayerAI::GetReplayType() +{ + return pScoreData->GetReplayType(); +} + +int +PlayerAI::GetNextRowNoOffsets(int currentRow) +{ + if (pScoreData->GetReplayType() == 2) + { + + auto thing = m_ReplayExactTapMap.lower_bound(currentRow + 1); + + if (thing == m_ReplayExactTapMap.end()) { + return -1; + } else { + return thing->first; + } + } + else + { + auto thing = m_ReplayTapMap.lower_bound(currentRow + 1); + + if (thing == m_ReplayTapMap.end()) + { + return -1; + } + else + { + return thing->first; + } + } +} + float PlayerAI::GetTapNoteOffsetForReplay(TapNote* pTN, int noteRow, int col) { @@ -240,35 +490,38 @@ PlayerAI::GetTapNoteOffsetForReplay(TapNote* pTN, int noteRow, int col) // tap note type] Current v0.60 Replay Data format (H section): H [noterow] // [track] [optional: tap note subtype] // LOG->Trace("Note row %d", noteRow); - if (m_ReplayTapMap.count(noteRow) != 0) // is the current row recorded? - { - // This replay has no column data or is considered Basic. (Pre-v0.60 - // Replays do this.) - if (pScoreData->GetReplayType() == 1) { - // mines are not preset in the old replay data, we just skip them - // this gets caught by Player after it finds that the offset wasnt - // -2.f (We check for an impossible offset of -2.f in Player to blow - // up a mine) - if (pTN->type == TapNoteType_Mine) - return -1.f; - - float offset = m_ReplayTapMap[noteRow].back().offset; - - // this is done to be able to judge simultaneous taps differently - // due to CC Off this results in possibly incorrect precise per tap - // judges, but the correct judgement ends up being made overall. - m_ReplayTapMap[noteRow].pop_back(); - if (m_ReplayTapMap[noteRow].empty()) { - m_ReplayTapMap.erase(noteRow); - } - return -offset; - } else { + // This replay has no column data or is considered Basic. (Pre-v0.60 + // Replays do this.) + if (pScoreData->GetReplayType() == 1) { + // mines are not preset in the old replay data, we just skip them + // this gets caught by Player after it finds that the offset wasnt + // -2.f (We check for an impossible offset of -2.f in Player to blow + // up a mine) + if (pTN->type == TapNoteType_Mine) + return -1.f; + + float offset = m_ReplayTapMap[noteRow].back().offset; + + // this is done to be able to judge simultaneous taps differently + // due to CC Off this results in possibly incorrect precise per tap + // judges, but the correct judgement ends up being made overall. + m_ReplayTapMap[noteRow].pop_back(); + if (m_ReplayTapMap[noteRow].empty()) { + m_ReplayTapMap.erase(noteRow); + } + + return -offset; + } else { - // This is only reached if we have column data. - for (auto trr : - m_ReplayTapMap[noteRow]) // go over all elements in the row + // This is only reached if we have column data. + noteRow = GetAdjustedRowFromUnadjustedCoordinates(noteRow, col); + if (m_ReplayExactTapMap.count(noteRow) != 0) + { + for (int i = 0; i < (int)m_ReplayExactTapMap[noteRow] + .size(); i++) // go over all elements in the row { + auto trr = m_ReplayExactTapMap[noteRow][i]; if (trr.track == col) // if the column expected is the actual note, use it { @@ -278,6 +531,10 @@ PlayerAI::GetTapNoteOffsetForReplay(TapNote* pTN, int noteRow, int col) if (trr.type != TapNoteType_Lift) continue; } + m_ReplayExactTapMap[noteRow].erase( + m_ReplayExactTapMap[noteRow].begin() + i); + if (m_ReplayExactTapMap[noteRow].empty()) + m_ReplayExactTapMap.erase(noteRow); return -trr.offset; } } From 5f18c630b12b8dcad605bb5321316f9d74d753da Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 00:06:15 -0600 Subject: [PATCH 04/43] Make v60 replays actually use offsets --- src/Player.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 8 deletions(-) diff --git a/src/Player.cpp b/src/Player.cpp index 8b63646346..f203426d57 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -762,6 +762,11 @@ Player::Load() SendComboMessages(m_pPlayerStageStats->m_iCurCombo, m_pPlayerStageStats->m_iCurMissCombo); + // If we are in a replay, attempt to load the real tapper stuff + if (GamePreferences::m_AutoPlay == PC_REPLAY) { + PlayerAI::SetUpExactTapMap(m_Timing); + } + SAFE_DELETE(m_pIterNeedsTapJudging); m_pIterNeedsTapJudging = new NoteData::all_tracks_iterator( m_NoteData.GetTapNoteRangeAllTracks(iNoteRow, MAX_NOTE_ROW)); @@ -929,6 +934,66 @@ Player::Update(float fDeltaTime) if (m_bPaused) return; + // Fake steps in Replay mode, but only if we have column data. + if (m_pPlayerState->m_PlayerController == PC_REPLAY && + PlayerAI::pScoreData->GetReplayType() == 2) { + + // Giant copy paste from Step() that simply determines how far to search + // in the past or future. + /*int searchDistance; + static const float StepSearchDistance = GetMaxStepDistanceSeconds(); + int skipstart = nerv[10]; + if (iSongRow < skipstart || + iSongRow > static_cast(nerv.size()) - 10) { + searchDistance = + max(BeatToNoteRow(m_Timing->GetBeatFromElapsedTime( + m_pPlayerState->m_Position.m_fMusicSeconds + + StepSearchDistance)) - + iSongRow, + iSongRow - BeatToNoteRow(m_Timing->GetBeatFromElapsedTime( + m_pPlayerState->m_Position.m_fMusicSeconds - + StepSearchDistance))) + + ROWS_PER_BEAT; + } else { + if (nerv[nervpos] < iSongRow && nervpos < nerv.size()) + nervpos += 1; + size_t SearchIndexBehind = nervpos; + size_t SearchIndexAhead = nervpos; + float SearchBeginTime = m_Timing->WhereUAtBro(nerv[nervpos]); + while (SearchIndexBehind > 1 && + SearchBeginTime - + m_Timing->WhereUAtBro(nerv[SearchIndexBehind - 1]) < + StepSearchDistance) + SearchIndexBehind -= 1; + while (SearchIndexAhead > 1 && SearchIndexAhead + 1 > nerv.size() && + m_Timing->WhereUAtBro(nerv[SearchIndexAhead + 1]) - + SearchBeginTime < + StepSearchDistance) + SearchIndexAhead += 1; + int MaxLookBehind = nerv[nervpos] - nerv[SearchIndexBehind]; + int MaxLookAhead = nerv[SearchIndexAhead] - nerv[nervpos]; + if (nervpos > 0) + searchDistance = + (max(MaxLookBehind, MaxLookAhead) + ROWS_PER_BEAT); + } + + + + int toTap = PlayerAI::DetermineNextTapColumn(iSongRow, searchDistance, + m_Timing); if (toTap != -1) + { + Step(toTap, iSongRow, now, false, false); + } + */ + if (PlayerAI::TapExistsAtOrBeforeThisRow(iSongRow)) { + vector trrVector = + PlayerAI::GetTapsAtOrBeforeRow(iSongRow); + for (TapReplayResult trr : trrVector) { + Step(trr.track, trr.row, now, false, false); + } + } + } + // update pressed flag const int iNumCols = GAMESTATE->GetCurrentStyle(GetPlayerState()->m_PlayerNumber) @@ -2216,9 +2281,10 @@ Player::Step(int col, DEBUG_ASSERT(iter != m_NoteData.end(col)); pTN = &iter->second; - // We don't really have to care if we are releasing on a non-lift, right? - // This fixes a weird noteskin bug with tap explosions. - if (PREFSMAN->m_bFullTapExplosions && bRelease && pTN->type != TapNoteType_Lift) + // We don't really have to care if we are releasing on a non-lift, + // right? This fixes a weird noteskin bug with tap explosions. + if (PREFSMAN->m_bFullTapExplosions && bRelease && + pTN->type != TapNoteType_Lift) return; switch (m_pPlayerState->m_PlayerController) { @@ -2377,11 +2443,16 @@ Player::Step(int col, score = TNS_None; fNoteOffset = -1.f; } else { + if (PlayerAI::GetReplayType() == 2) { + iRowOfOverlappingNoteOrRow = row; + } fNoteOffset = PlayerAI::GetTapNoteOffsetForReplay( - pTN, iRowOfOverlappingNoteOrRow, col); + pTN, iRowOfOverlappingNoteOrRow, col); if (fNoteOffset == -2.f) // we hit a mine { score = TNS_HitMine; + PlayerAI::RemoveTapFromVectors( + iRowOfOverlappingNoteOrRow, col); } else if (pTN->type == TapNoteType_Mine) // we are looking // at a mine but // missed it @@ -2804,10 +2875,14 @@ Player::CrossedRows(int iLastRowCrossed, tn.type != TapNoteType_AutoKeysound && tn.result.tns == TNS_None && this->m_Timing->IsJudgableAtRow(iRow)) { - Step(iTrack, iRow, now, false, false); - if (m_pPlayerState->m_PlayerController == PC_AUTOPLAY) { - if (m_pPlayerStageStats) - m_pPlayerStageStats->m_bDisqualified = true; + if ((m_pPlayerState->m_PlayerController == PC_REPLAY && + PlayerAI::GetReplayType() != 2) || + m_pPlayerState->m_PlayerController == PC_AUTOPLAY) { + Step(iTrack, iRow, now, false, false); + if (m_pPlayerState->m_PlayerController == PC_AUTOPLAY) { + if (m_pPlayerStageStats) + m_pPlayerStageStats->m_bDisqualified = true; + } } } } From 91817235e88287693c54147877a4824dd339cf49 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 00:15:11 -0600 Subject: [PATCH 05/43] Very minor cleanup, documentation, and formatting --- src/PlayerAI.cpp | 114 +++++++++++------------------------------------ 1 file changed, 27 insertions(+), 87 deletions(-) diff --git a/src/PlayerAI.cpp b/src/PlayerAI.cpp index d40e4905e5..8261339bba 100644 --- a/src/PlayerAI.cpp +++ b/src/PlayerAI.cpp @@ -254,23 +254,26 @@ PlayerAI::SetUpExactTapMap(TimingData* timing) void PlayerAI::RemoveTapFromVectors(int row, int col) { - if (m_ReplayTapMap.count(row) != 0) - { - for (int i = 0; i < (int)m_ReplayTapMap[row].size(); i++) - { + // if the row is in the replay data + if (m_ReplayTapMap.count(row) != 0) { + for (int i = 0; i < (int)m_ReplayTapMap[row].size(); i++) { + // if the column is in the row data auto& trr = m_ReplayTapMap[row][i]; - if (trr.track == col) - { + if (trr.track == col) { + // delete m_ReplayTapMap[row].erase(m_ReplayTapMap[row].begin() + i); if (m_ReplayTapMap[row].empty()) m_ReplayTapMap.erase(row); } } } + // if the row is in the replay data if (m_ReplayExactTapMap.count(row) != 0) { for (int i = 0; i < (int)m_ReplayExactTapMap[row].size(); i++) { + // if the column is in the row data auto& trr = m_ReplayExactTapMap[row][i]; if (trr.track == col) { + // delete m_ReplayExactTapMap[row].erase(m_ReplayExactTapMap[row].begin() + i); if (m_ReplayExactTapMap[row].empty()) m_ReplayExactTapMap.erase(row); @@ -283,6 +286,7 @@ int PlayerAI::GetAdjustedRowFromUnadjustedCoordinates(int row, int col) { int output = -1; + if (m_ReplayTapMap.count(row) != 0) { for (TapReplayResult& trr : m_ReplayTapMap[row]) @@ -314,56 +318,13 @@ PlayerAI::DetermineIfHoldDropped(int noteRow, int col) return false; } -int -PlayerAI::DetermineNextTapColumn(int noteRow, int searchRowDistance, TimingData* timing) -{ - // Cannot determine columns without column data. - if (pScoreData->GetReplayType() == 1) - return -1; - - float centralTime = timing->WhereUAtBro(noteRow); - float currentTime = 0.f; - int earliestColumn = -1; - float earliestColumnTime = 99999999.f; - - // For every row behind and in the future within a certain limit (in the replay data) - for (int i = noteRow - searchRowDistance; i != -1 && i < noteRow + searchRowDistance; - i = GetNextRowNoOffsets(i)) - { - if (m_ReplayTapMap.count(i) != 0) - { - currentTime = timing->WhereUAtBro(i); - for (auto& trr : m_ReplayTapMap[i]) - { - float tmpTime = currentTime + trr.offset; - if (tmpTime < earliestColumnTime) - { - earliestColumn = trr.track; - earliestColumnTime = tmpTime; - } - } - } - - - } - if (fabsf(centralTime - earliestColumnTime) < 1.f) { - return earliestColumn; - } - return -1; - - //return earliestColumn; -} - bool PlayerAI::TapExistsAtThisRow(int noteRow) { // 2 is a replay with column data - if (pScoreData->GetReplayType() == 2) - { + if (pScoreData->GetReplayType() == 2) { return m_ReplayExactTapMap.count(noteRow) != 0; - } - else - { + } else { return m_ReplayTapMap.count(noteRow) != 0; } @@ -373,12 +334,9 @@ bool PlayerAI::TapExistsAtOrBeforeThisRow(int noteRow) { // 2 is a replay with column data - if (pScoreData->GetReplayType() == 2) - { + if (pScoreData->GetReplayType() == 2) { return m_ReplayExactTapMap.lower_bound(0)->first <= noteRow; - } - else - { + } else { return m_ReplayTapMap.lower_bound(0)->first <= noteRow; } } @@ -389,19 +347,15 @@ PlayerAI::GetTapsAtOrBeforeRow(int noteRow) vector output; // 2 is a replay with column data - if (pScoreData->GetReplayType() == 2) - { + if (pScoreData->GetReplayType() == 2) { auto rowIt = m_ReplayExactTapMap.lower_bound(0); int row = rowIt->first; - for (; row <= noteRow && row != -1;) - { + for (; row <= noteRow && row != -1;) { vector toMerge = GetTapsToTapForRow(row); output.insert(output.end(), toMerge.begin(), toMerge.end()); row = GetNextRowNoOffsets(row); } - } - else - { + } else { auto rowIt = m_ReplayTapMap.lower_bound(0); int row = rowIt->first; for (; row <= noteRow && row != -1;) { @@ -419,22 +373,15 @@ PlayerAI::GetTapsToTapForRow(int noteRow) vector output; // 2 is a replay with column data - if (pScoreData->GetReplayType() == 2) - { - if (m_ReplayExactTapMap.count(noteRow) != 0) - { - for (auto& trr : m_ReplayExactTapMap[noteRow]) - { + if (pScoreData->GetReplayType() == 2) { + if (m_ReplayExactTapMap.count(noteRow) != 0) { + for (auto& trr : m_ReplayExactTapMap[noteRow]) { output.push_back(trr); } } - } - else - { - if (m_ReplayTapMap.count(noteRow) != 0) - { - for (auto& trr : m_ReplayTapMap[noteRow]) - { + } else { + if (m_ReplayTapMap.count(noteRow) != 0) { + for (auto& trr : m_ReplayTapMap[noteRow]) { output.push_back(trr); } } @@ -451,9 +398,7 @@ PlayerAI::GetReplayType() int PlayerAI::GetNextRowNoOffsets(int currentRow) { - if (pScoreData->GetReplayType() == 2) - { - + if (pScoreData->GetReplayType() == 2) { auto thing = m_ReplayExactTapMap.lower_bound(currentRow + 1); if (thing == m_ReplayExactTapMap.end()) { @@ -461,17 +406,12 @@ PlayerAI::GetNextRowNoOffsets(int currentRow) } else { return thing->first; } - } - else - { + } else { auto thing = m_ReplayTapMap.lower_bound(currentRow + 1); - if (thing == m_ReplayTapMap.end()) - { + if (thing == m_ReplayTapMap.end()) { return -1; - } - else - { + } else { return thing->first; } } From 2efb3fac3d7369529d58722382c197b10278ec85 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 00:17:16 -0600 Subject: [PATCH 06/43] Remove giant useless comment --- src/Player.cpp | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/src/Player.cpp b/src/Player.cpp index f203426d57..7d7d05df7d 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -937,54 +937,6 @@ Player::Update(float fDeltaTime) // Fake steps in Replay mode, but only if we have column data. if (m_pPlayerState->m_PlayerController == PC_REPLAY && PlayerAI::pScoreData->GetReplayType() == 2) { - - // Giant copy paste from Step() that simply determines how far to search - // in the past or future. - /*int searchDistance; - static const float StepSearchDistance = GetMaxStepDistanceSeconds(); - int skipstart = nerv[10]; - if (iSongRow < skipstart || - iSongRow > static_cast(nerv.size()) - 10) { - searchDistance = - max(BeatToNoteRow(m_Timing->GetBeatFromElapsedTime( - m_pPlayerState->m_Position.m_fMusicSeconds + - StepSearchDistance)) - - iSongRow, - iSongRow - BeatToNoteRow(m_Timing->GetBeatFromElapsedTime( - m_pPlayerState->m_Position.m_fMusicSeconds - - StepSearchDistance))) + - ROWS_PER_BEAT; - } else { - if (nerv[nervpos] < iSongRow && nervpos < nerv.size()) - nervpos += 1; - size_t SearchIndexBehind = nervpos; - size_t SearchIndexAhead = nervpos; - float SearchBeginTime = m_Timing->WhereUAtBro(nerv[nervpos]); - while (SearchIndexBehind > 1 && - SearchBeginTime - - m_Timing->WhereUAtBro(nerv[SearchIndexBehind - 1]) < - StepSearchDistance) - SearchIndexBehind -= 1; - while (SearchIndexAhead > 1 && SearchIndexAhead + 1 > nerv.size() && - m_Timing->WhereUAtBro(nerv[SearchIndexAhead + 1]) - - SearchBeginTime < - StepSearchDistance) - SearchIndexAhead += 1; - int MaxLookBehind = nerv[nervpos] - nerv[SearchIndexBehind]; - int MaxLookAhead = nerv[SearchIndexAhead] - nerv[nervpos]; - if (nervpos > 0) - searchDistance = - (max(MaxLookBehind, MaxLookAhead) + ROWS_PER_BEAT); - } - - - - int toTap = PlayerAI::DetermineNextTapColumn(iSongRow, searchDistance, - m_Timing); if (toTap != -1) - { - Step(toTap, iSongRow, now, false, false); - } - */ if (PlayerAI::TapExistsAtOrBeforeThisRow(iSongRow)) { vector trrVector = PlayerAI::GetTapsAtOrBeforeRow(iSongRow); From ae000d780f5979f7ea2abbf8b4e9d16cebe5f30e Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 13:32:26 -0600 Subject: [PATCH 07/43] Fix v60 replays breaking when pausing --- src/PlayerAI.cpp | 4 +++- src/PlayerAI.h | 4 +++- src/ScreenGameplay.cpp | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/PlayerAI.cpp b/src/PlayerAI.cpp index 8261339bba..d3f0e9da76 100644 --- a/src/PlayerAI.cpp +++ b/src/PlayerAI.cpp @@ -50,6 +50,7 @@ struct TapScoreDistribution static TapScoreDistribution g_Distributions[NUM_SKILL_LEVELS]; HighScore* PlayerAI::pScoreData = nullptr; +TimingData* PlayerAI::pReplayTiming = nullptr; map> PlayerAI::m_ReplayTapMap; map> PlayerAI::m_ReplayHoldMap; map> PlayerAI::m_ReplayExactTapMap; @@ -158,7 +159,6 @@ PlayerAI::SetScoreData(HighScore* pHighScore) pScoreData = pHighScore; m_ReplayTapMap.clear(); m_ReplayHoldMap.clear(); - m_ReplayExactTapMap.clear(); auto replayNoteRowVector = pHighScore->GetCopyOfNoteRowVector(); auto replayOffsetVector = pHighScore->GetCopyOfOffsetVector(); @@ -220,6 +220,8 @@ PlayerAI::SetUpExactTapMap(TimingData* timing) if (pScoreData->GetReplayType() != 2) return; + pReplayTiming = timing; + // For every row in the replay data... for (auto& row : m_ReplayTapMap) { diff --git a/src/PlayerAI.h b/src/PlayerAI.h index 58e8a814a2..27d3ab384e 100644 --- a/src/PlayerAI.h +++ b/src/PlayerAI.h @@ -14,9 +14,11 @@ class PlayerAI { public: // Pointer to real high score data for a replay - static HighScore* pScoreData; + // Pointer to real timing data for a replay + static TimingData* pReplayTiming; + // Pulled from pScoreData on initialization // A map with indices for each row of the chart, pointing to nothing or a diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index ee61d5a693..4782c45c8d 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -2849,6 +2849,7 @@ ScreenGameplay::ToggleReplayPause() ReloadCurrentSong(); STATSMAN->m_CurStageStats.m_player[PLAYER_1].InternalInit(); PlayerAI::SetScoreData(PlayerAI::pScoreData); + PlayerAI::SetUpExactTapMap(PlayerAI::pReplayTiming); // Reset the wife/judge counter related visible stuff FOREACH_ENUM(TapNoteScore, tns) From 508f50b56f9579e3543703ffa5d8fe9143ebaa41 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Thu, 15 Nov 2018 14:58:14 -0600 Subject: [PATCH 08/43] Improve Eval Screen Screenshots --- src/ScreenEvaluation.cpp | 62 ++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/ScreenEvaluation.cpp b/src/ScreenEvaluation.cpp index 5113b82c05..4553862749 100644 --- a/src/ScreenEvaluation.cpp +++ b/src/ScreenEvaluation.cpp @@ -763,30 +763,48 @@ ScreenEvaluation::Input(const InputEventPlus& input) CodeDetector::EnteredCode(input.GameI.controller, CODE_SAVE_SCREENSHOT2)) { PlayerNumber pn = input.pn; - if (!m_bSavedScreenshot[pn] && // only allow one screenshot - PROFILEMAN->IsPersistentProfile(pn)) { - Profile* pProfile = PROFILEMAN->GetProfile(pn); - RString sDir = - PROFILEMAN->GetProfileDir((ProfileSlot)pn) + "Screenshots/"; - RString sFileName = - StepMania::SaveScreenshot(sDir, true, true, "", ""); - - if (!sFileName.empty()) { - RString sPath = sDir + sFileName; - - const HighScore& hs = - m_pStageStats->m_player[pn].m_HighScore; - Screenshot screenshot; - screenshot.sFileName = sFileName; - screenshot.sMD5 = - BinaryToHex(CRYPTMAN->GetMD5ForFile(sPath)); - screenshot.highScore = hs; - pProfile->AddScreenshot(screenshot); + bool bHoldingShift = + (INPUTFILTER->IsBeingPressed( + DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT)) || + INPUTFILTER->IsBeingPressed( + DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT))); + RString sDir; + RString sFileName; + // To save a screenshot to your own profile you must hold shift + // and press the button it saves compressed so you don't end up + // with an inflated profile size + // Otherwise, you can tap away at the screenshot button without holding shift. + if (bHoldingShift && PROFILEMAN->IsPersistentProfile(pn)) + { + if (!m_bSavedScreenshot[pn]) + { + Profile* pProfile = PROFILEMAN->GetProfile(pn); + sDir = PROFILEMAN->GetProfileDir((ProfileSlot)pn) + + "Screenshots/"; + sFileName = + StepMania::SaveScreenshot(sDir, bHoldingShift, true, "", ""); + if (!sFileName.empty()) { + RString sPath = sDir + sFileName; + + const HighScore& hs = + m_pStageStats->m_player[pn].m_HighScore; + Screenshot screenshot; + screenshot.sFileName = sFileName; + screenshot.sMD5 = + BinaryToHex(CRYPTMAN->GetMD5ForFile(sPath)); + screenshot.highScore = hs; + pProfile->AddScreenshot(screenshot); + } + m_bSavedScreenshot[pn] = true; } - - m_bSavedScreenshot[pn] = true; - return true; // handled } + else + { + sDir = "Screenshots/"; + sFileName = + StepMania::SaveScreenshot(sDir, bHoldingShift, true, "", ""); + } + return true; // handled } } From fb5ca860f154b66a8e7f3292111d3e37939343b4 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Fri, 16 Nov 2018 22:51:59 -0300 Subject: [PATCH 09/43] Update GameSoundManager.cpp --- src/GameSoundManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index 49b0943c50..3a172b1c6d 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -806,6 +806,7 @@ class LunaGameSoundManager : public Luna pRet->Set(fVol); SOUNDMAN->SetMixVolume(); p->DimMusic(FArg(1), 0.01f); // lazy hack to update volume without changing songs - mina + return 0; } static int PlayOnce(T* p, lua_State* L) { From cc0958578883cb5284a2770125563261200f0753 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Fri, 16 Nov 2018 20:03:48 -0600 Subject: [PATCH 10/43] Fix 0 IQ PlayerAI replay data load bool check --- src/PlayerAI.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/PlayerAI.cpp b/src/PlayerAI.cpp index d3f0e9da76..4ac47cebd8 100644 --- a/src/PlayerAI.cpp +++ b/src/PlayerAI.cpp @@ -155,11 +155,16 @@ PlayerAI::GetTapNoteScoreForReplay(const PlayerState* pPlayerState, void PlayerAI::SetScoreData(HighScore* pHighScore) { - pHighScore->LoadReplayData(); + bool successful = pHighScore->LoadReplayData(); pScoreData = pHighScore; m_ReplayTapMap.clear(); m_ReplayHoldMap.clear(); + if (!successful) + { + return; + } + auto replayNoteRowVector = pHighScore->GetCopyOfNoteRowVector(); auto replayOffsetVector = pHighScore->GetCopyOfOffsetVector(); auto replayTapNoteTypeVector = pHighScore->GetCopyOfTapNoteTypeVector(); From a6f92693269f9fe2ae29daf058af7af776687c51 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Fri, 16 Nov 2018 20:04:25 -0600 Subject: [PATCH 11/43] Fix 0 IQ null pointer dereference --- src/ScreenSelectMusic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index 2c6c4417ae..07483a48f3 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -1475,7 +1475,8 @@ ScreenSelectMusic::AfterStepsOrTrailChange(const vector& vpns) Steps* pSteps = m_vpSteps.empty() ? NULL : m_vpSteps[m_iSelection[pn]]; GAMESTATE->m_pCurSteps[pn].Set(pSteps); - GAMESTATE->SetCompatibleStyle(pSteps->m_StepsType, pn); + if (pSteps != nullptr) + GAMESTATE->SetCompatibleStyle(pSteps->m_StepsType, pn); int iScore = 0; if (pSteps) { From a269a3bcba84cc4a3fb59e163bcbb594c244bb80 Mon Sep 17 00:00:00 2001 From: poco0317 Date: Fri, 16 Nov 2018 20:17:00 -0600 Subject: [PATCH 12/43] Fill out uninitialized struct attribute in PlayerAI probably useful to do this anyways because something random could check it --- src/PlayerAI.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PlayerAI.cpp b/src/PlayerAI.cpp index 4ac47cebd8..acc9a25557 100644 --- a/src/PlayerAI.cpp +++ b/src/PlayerAI.cpp @@ -177,6 +177,7 @@ PlayerAI::SetScoreData(HighScore* pHighScore) TapReplayResult trr; trr.row = replayNoteRowVector[i]; trr.offset = replayOffsetVector[i]; + trr.offsetAdjustedRow = replayOffsetVector[i]; if (pScoreData->GetReplayType() == 2) // 2 means that this is a Full Replay { From b93f09380de951532f0ced05751f13c3a121c802 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 19 Nov 2018 20:49:22 -0300 Subject: [PATCH 13/43] Fix wrong return count in lua function This fixes crashes on 64bit when cancelling dls --- src/DownloadManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DownloadManager.cpp b/src/DownloadManager.cpp index d645afc544..9a9ba7dd91 100644 --- a/src/DownloadManager.cpp +++ b/src/DownloadManager.cpp @@ -2574,7 +2574,7 @@ class LunaDownload : public Luna static int Stop(T* p, lua_State* L) { p->p_RFWrapper.stop = true; - return 1; + return 0; } LunaDownload() { From 7046dca61c56a110260c05960229f58f65c1ac43 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Tue, 20 Nov 2018 02:51:50 -0300 Subject: [PATCH 14/43] Update appveyor.yml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index fe02a18cc3..6d3e5bf617 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -67,7 +67,7 @@ after_build: notifications: - provider: Email to: - - etternadevs@gmail.com + - etternadev@gmail.com on_build_success: false on_build_failure: true on_build_status_changed: true From 373616359d38dcebb6d27efbffca3779aba6ab5a Mon Sep 17 00:00:00 2001 From: poco0317 Date: Tue, 20 Nov 2018 18:00:28 -0600 Subject: [PATCH 15/43] Fix the step callback for autoplayCPU broken by an update to replays --- src/Player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Player.cpp b/src/Player.cpp index 7d7d05df7d..66f1ec1415 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2829,9 +2829,9 @@ Player::CrossedRows(int iLastRowCrossed, this->m_Timing->IsJudgableAtRow(iRow)) { if ((m_pPlayerState->m_PlayerController == PC_REPLAY && PlayerAI::GetReplayType() != 2) || - m_pPlayerState->m_PlayerController == PC_AUTOPLAY) { + m_pPlayerState->m_PlayerController == PC_AUTOPLAY || m_pPlayerState->m_PlayerController == PC_CPU) { Step(iTrack, iRow, now, false, false); - if (m_pPlayerState->m_PlayerController == PC_AUTOPLAY) { + if (m_pPlayerState->m_PlayerController == PC_AUTOPLAY || m_pPlayerState->m_PlayerController == PC_CPU) { if (m_pPlayerStageStats) m_pPlayerStageStats->m_bDisqualified = true; } From 20cd6fb333ab358cffa93aeade8daba1982d7cc1 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 01:27:57 -0500 Subject: [PATCH 16/43] dont load fadedbanners if the banner actor is not visible --- src/ScreenSelectMusic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index 07483a48f3..a4e59da7e2 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -1571,7 +1571,7 @@ ScreenSelectMusic::AfterMusicChange() g_sCDTitlePath = ""; g_sBannerPath = ""; g_bWantFallbackCdTitle = false; - bool bWantBanner = true; + bool bWantBanner = true &&m_Banner.GetVisible(); static SortOrder s_lastSortOrder = SortOrder_Invalid; if (GAMESTATE->m_SortOrder != s_lastSortOrder) { From e01ab8af140fd654fd15bcd9f5c276588ab4e912 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 15:42:13 -0500 Subject: [PATCH 17/43] remove unused internal screenselectmusic actors this includes internal banner/cdtitle and highscoreframe actors that are all custom defined in lua as of now also removes the internal showbanners pref --- src/PrefsManager.cpp | 1 - src/PrefsManager.h | 1 - src/ScreenOptionsMasterPrefs.cpp | 2 - src/ScreenSelectMusic.cpp | 184 ++----------------------------- src/ScreenSelectMusic.h | 4 - 5 files changed, 10 insertions(+), 182 deletions(-) diff --git a/src/PrefsManager.cpp b/src/PrefsManager.cpp index 66410a4dfd..2bd7d6f200 100644 --- a/src/PrefsManager.cpp +++ b/src/PrefsManager.cpp @@ -150,7 +150,6 @@ PrefsManager::PrefsManager() , m_bAllowedLag("AllowedLag", 0.001f) , m_bShowStats("ShowStats", TRUE_IF_DEBUG) , m_bShowSkips("ShowSkips", true) - , m_bShowBanners("ShowBanners", true) , m_bShowMouseCursor("ShowMouseCursor", true) , m_bVsync("Vsync", false) , m_FastNoteRendering("FastNoteRendering", true) diff --git a/src/PrefsManager.h b/src/PrefsManager.h index e26d8c3863..03dd4df402 100644 --- a/src/PrefsManager.h +++ b/src/PrefsManager.h @@ -151,7 +151,6 @@ class PrefsManager Preference m_bAllowedLag; Preference m_bShowStats; Preference m_bShowSkips; - Preference m_bShowBanners; Preference m_bShowMouseCursor; Preference m_bVsync; Preference m_FastNoteRendering; diff --git a/src/ScreenOptionsMasterPrefs.cpp b/src/ScreenOptionsMasterPrefs.cpp index cae91e7a8e..3c62ba011f 100644 --- a/src/ScreenOptionsMasterPrefs.cpp +++ b/src/ScreenOptionsMasterPrefs.cpp @@ -1017,8 +1017,6 @@ InitializeConfOptions() g_ConfOptions.back().m_iEffects = OPT_APPLY_GRAPHICS; ADD(ConfOption("FastNoteRendering", MovePref, "Off", "On")); ADD(ConfOption("ShowStats", MovePref, "Off", "On")); - ADD(ConfOption("ShowBanners", MovePref, "Off", "On")); - // Sound options ADD(ConfOption("AttractSoundFrequency", MovePref, diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index a4e59da7e2..126648798d 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -66,11 +66,6 @@ AutoScreenMessage(SM_BackFromPlayerOptions); AutoScreenMessage(SM_ConfirmDeleteSong); AutoScreenMessage(SM_BackFromNamePlaylist); -static RString g_sCDTitlePath; -static bool g_bWantFallbackCdTitle; -static bool g_bCDTitleWaiting = false; -static RString g_sBannerPath; -static bool g_bBannerWaiting = false; static bool g_bSampleMusicWaiting = false; static bool delayedchartupdatewaiting = false; static RageTimer g_StartedLoadingAt(RageZeroTimer); @@ -215,37 +210,6 @@ ScreenSelectMusic::Init() m_OptionsList[PLAYER_2].Link(&m_OptionsList[PLAYER_1]); } - // this is loaded SetSong and TweenToSong - m_Banner.SetName("Banner"); - LOAD_ALL_COMMANDS_AND_SET_XY(m_Banner); - this->AddChild(&m_Banner); - - m_sprCDTitleFront.SetName("CDTitle"); - m_sprCDTitleFront.Load(THEME->GetPathG(m_sName, "fallback cdtitle")); - LOAD_ALL_COMMANDS_AND_SET_XY(m_sprCDTitleFront); - COMMAND(m_sprCDTitleFront, "Front"); - this->AddChild(&m_sprCDTitleFront); - - m_sprCDTitleBack.SetName("CDTitle"); - m_sprCDTitleBack.Load(THEME->GetPathG(m_sName, "fallback cdtitle")); - LOAD_ALL_COMMANDS_AND_SET_XY(m_sprCDTitleBack); - COMMAND(m_sprCDTitleBack, "Back"); - this->AddChild(&m_sprCDTitleBack); - - FOREACH_ENUM(PlayerNumber, p) - { - m_sprHighScoreFrame[p].Load( - THEME->GetPathG(m_sName, ssprintf("ScoreFrame P%d", p + 1))); - m_sprHighScoreFrame[p]->SetName(ssprintf("ScoreFrameP%d", p + 1)); - LOAD_ALL_COMMANDS_AND_SET_XY(m_sprHighScoreFrame[p]); - this->AddChild(m_sprHighScoreFrame[p]); - - m_textHighScore[p].SetName(ssprintf("ScoreP%d", p + 1)); - m_textHighScore[p].LoadFromFont(THEME->GetPathF(m_sName, "score")); - LOAD_ALL_COMMANDS_AND_SET_XY(m_textHighScore[p]); - this->AddChild(&m_textHighScore[p]); - } - RageSoundLoadParams SoundParams; SoundParams.m_bSupportPan = true; @@ -276,7 +240,7 @@ ScreenSelectMusic::BeginScreen() GAMESTATE->SetCompatibleStylesForPlayers(); } - if (GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == NULL) { + if (GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == nullptr) { LOG->Trace("The Style has not been set. A theme must set the Style " "before loading ScreenSelectMusic."); // Instead of crashing, set the first compatible style. @@ -284,7 +248,7 @@ ScreenSelectMusic::BeginScreen() GAMEMAN->GetStepsTypesForGame(GAMESTATE->m_pCurGame, vst); const Style* pStyle = GAMEMAN->GetFirstCompatibleStyle( GAMESTATE->m_pCurGame, GAMESTATE->GetNumSidesJoined(), vst[0]); - if (pStyle == NULL) { + if (pStyle == nullptr) { LOG->Warn(ssprintf("No compatible styles for %s with %d player%s.", GAMESTATE->m_pCurGame->m_szName, GAMESTATE->GetNumSidesJoined(), @@ -300,13 +264,6 @@ ScreenSelectMusic::BeginScreen() GAMESTATE->m_PlayMode.Set(PLAY_MODE_REGULAR); LOG->Trace("PlayMode not set, setting as regular."); } - FOREACH_ENUM(PlayerNumber, pn) - { - if (GAMESTATE->IsHumanPlayer(pn)) - continue; - m_sprHighScoreFrame[pn]->SetVisible(false); - m_textHighScore[pn].SetVisible(false); - } OPTIONS_MENU_AVAILABLE.Load(m_sName, "OptionsMenuAvailable"); PlayCommand("Mods"); @@ -348,31 +305,6 @@ ScreenSelectMusic::~ScreenSelectMusic() void ScreenSelectMusic::CheckBackgroundRequests(bool bForce) { - if (g_bCDTitleWaiting) { - // The CDTitle is normally very small, so we don't bother waiting to - // display it. - RString sPath; - if (!m_BackgroundLoader.IsCacheFileFinished(g_sCDTitlePath, sPath)) - return; - - g_bCDTitleWaiting = false; - - RString sCDTitlePath = sPath; - - if (sCDTitlePath.empty() || !IsAFile(sCDTitlePath)) - sCDTitlePath = - g_bWantFallbackCdTitle ? m_sFallbackCDTitlePath : RString(""); - - if (!sCDTitlePath.empty()) { - TEXTUREMAN->DisableOddDimensionWarning(); - m_sprCDTitleFront.Load(sCDTitlePath); - m_sprCDTitleBack.Load(sCDTitlePath); - TEXTUREMAN->EnableOddDimensionWarning(); - } - - m_BackgroundLoader.FinishedWithCachedFile(g_sCDTitlePath); - } - /* Loading the rest can cause small skips, so don't do it until the wheel * settles. Do load if we're transitioning out, though, so we don't miss * starting the music for the options screen if a song is selected quickly. @@ -382,30 +314,6 @@ ScreenSelectMusic::CheckBackgroundRequests(bool bForce) if (!m_MusicWheel.IsSettled() && !m_MusicWheel.WheelIsLocked() && !bForce) return; - if (g_bBannerWaiting) { - if (m_Banner.GetTweenTimeLeft() > 0) - return; - - RString sPath; - bool bFreeCache = false; - if (TEXTUREMAN->IsTextureRegistered( - Sprite::SongBannerTexture(g_sBannerPath))) { - /* If the file is already loaded into a texture, it's finished, - * and we only do this to honor the HighQualTime value. */ - sPath = g_sBannerPath; - } else { - if (!m_BackgroundLoader.IsCacheFileFinished(g_sBannerPath, sPath)) - return; - bFreeCache = true; - } - - g_bBannerWaiting = false; - m_Banner.Load(sPath, true); - - if (bFreeCache) - m_BackgroundLoader.FinishedWithCachedFile(g_sBannerPath); - } - // we need something similar to the previewmusic delay except for charts, so // heavy duty chart specific operations can be delayed when scrolling (chord // density graph, possibly chart leaderboards, etc) -mina @@ -1137,7 +1045,7 @@ ScreenSelectMusic::HandleMessage(const Message& msg) } m_iSelection[pn] = iSel; - Steps* pSteps = m_vpSteps.empty() ? NULL : m_vpSteps[m_iSelection[pn]]; + Steps* pSteps = m_vpSteps.empty() ? nullptr : m_vpSteps[m_iSelection[pn]]; GAMESTATE->m_pCurSteps[pn].Set(pSteps); } @@ -1156,7 +1064,7 @@ ScreenSelectMusic::HandleScreenMessage(const ScreenMessage SM) m_MenuTimer->SetSeconds(ROULETTE_TIMER_SECONDS); m_MenuTimer->Start(); } else if (DO_ROULETTE_ON_MENU_TIMER && - m_MusicWheel.GetSelectedSong() == NULL) { + m_MusicWheel.GetSelectedSong() == nullptr) { m_MenuTimer->SetSeconds(ROULETTE_TIMER_SECONDS); m_MenuTimer->Start(); } else { @@ -1252,7 +1160,7 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) return false; // a song was selected - if (m_MusicWheel.GetSelectedSong() != NULL) { + if (m_MusicWheel.GetSelectedSong() != nullptr) { if (TWO_PART_CONFIRMS_ONLY && SAMPLE_MUSIC_PREVIEW_MODE == SampleMusicPreviewMode_StartToPreview) { @@ -1387,7 +1295,6 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) /* If we're currently waiting on song assets, abort all except the music * and start the music, so if we make a choice quickly before background * requests come through, the music will still start. */ - g_bCDTitleWaiting = g_bBannerWaiting = false; m_BackgroundLoader.Abort(); CheckBackgroundRequests(true); @@ -1462,9 +1369,6 @@ ScreenSelectMusic::AfterStepsOrTrailChange(const vector& vpns) MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); } - // FOREACH_CONST(PlayerNumber, vpns, p) - //{ - // PlayerNumber pn = *p; PlayerNumber pn = PLAYER_1; ASSERT(GAMESTATE->IsHumanPlayer(pn)); @@ -1472,7 +1376,7 @@ ScreenSelectMusic::AfterStepsOrTrailChange(const vector& vpns) CLAMP(m_iSelection[pn], 0, m_vpSteps.size() - 1); Song* pSong = GAMESTATE->m_pCurSong; - Steps* pSteps = m_vpSteps.empty() ? NULL : m_vpSteps[m_iSelection[pn]]; + Steps* pSteps = m_vpSteps.empty() ? nullptr : m_vpSteps[m_iSelection[pn]]; GAMESTATE->m_pCurSteps[pn].Set(pSteps); if (pSteps != nullptr) @@ -1490,13 +1394,7 @@ ScreenSelectMusic::AfterStepsOrTrailChange(const vector& vpns) } delayedchartupdatewaiting = true; } - - m_textHighScore[pn].SetText(ssprintf("%*i", NUM_SCORE_DIGITS, iScore)); - } else { - // The numbers shouldn't stay if the current selection is NULL. - m_textHighScore[pn].SetText(NULL_SCORE_STRING); } - //} } void @@ -1555,23 +1453,18 @@ ScreenSelectMusic::AfterMusicChange() GAMESTATE->m_pCurSong.Set(pSong); if (pSong != nullptr) GAMESTATE->m_pPreferredSong = pSong; + else + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); // set steps to null when moving out of packs -mina GAMESTATE->SetPaused(false); // hacky can see this being problematic // if we forget about it -mina m_vpSteps.clear(); - - m_Banner.SetMovingFast(!!m_MusicWheel.IsMoving()); - vector m_Artists, m_AltArtists; if (SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong) { m_sSampleMusicToPlay = ""; } - m_pSampleMusicTimingData = NULL; - g_sCDTitlePath = ""; - g_sBannerPath = ""; - g_bWantFallbackCdTitle = false; - bool bWantBanner = true &&m_Banner.GetVisible(); + m_pSampleMusicTimingData = nullptr; static SortOrder s_lastSortOrder = SortOrder_Invalid; if (GAMESTATE->m_SortOrder != s_lastSortOrder) { @@ -1588,9 +1481,6 @@ ScreenSelectMusic::AfterMusicChange() case WheelItemDataType_Random: case WheelItemDataType_Custom: FOREACH_PlayerNumber(p) m_iSelection[p] = -1; - - g_sCDTitlePath = ""; // none - if (SAMPLE_MUSIC_PREVIEW_MODE == SampleMusicPreviewMode_LastSong) { // HACK: Make random music work in LastSong mode. -aj if (m_sSampleMusicToPlay == m_sRandomMusicPath) { @@ -1606,49 +1496,27 @@ ScreenSelectMusic::AfterMusicChange() case WheelItemDataType_Section: // reduce scope { - SortOrder curSort = GAMESTATE->m_SortOrder; - if (curSort == SORT_GROUP) { - g_sBannerPath = SONGMAN->GetSongGroupBannerPath( - m_MusicWheel.GetSelectedSection()); - } else { - bWantBanner = false; // we load it ourself - m_Banner.LoadFromSortOrder(curSort); - } - if (SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong) m_sSampleMusicToPlay = m_sSectionMusicPath; } break; case WheelItemDataType_Sort: - bWantBanner = false; // we load it ourself - m_Banner.LoadMode(); if (SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong) m_sSampleMusicToPlay = m_sSortMusicPath; break; case WheelItemDataType_Roulette: - bWantBanner = false; // we load it ourself - m_Banner.LoadRoulette(); if (SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong) m_sSampleMusicToPlay = m_sRouletteMusicPath; break; case WheelItemDataType_Random: - bWantBanner = false; // we load it ourself - m_Banner.LoadRandom(); // if( SAMPLE_MUSIC_PREVIEW_MODE != // SampleMusicPreviewMode_LastSong ) m_sSampleMusicToPlay = m_sRandomMusicPath; break; case WheelItemDataType_Custom: { - bWantBanner = false; // we load it ourself - RString sBannerName = - GetMusicWheel() - ->GetCurWheelItemData( - GetMusicWheel()->GetCurrentIndex()) - ->m_pAction->m_sName.c_str(); - m_Banner.LoadCustom(sBannerName); if (SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong) m_sSampleMusicToPlay = m_sSectionMusicPath; @@ -1708,48 +1576,16 @@ ScreenSelectMusic::AfterMusicChange() // nothing."); } - if (PREFSMAN->m_bShowBanners) - g_sBannerPath = pSong->GetBannerPath(); - - g_sCDTitlePath = pSong->GetCDTitlePath(); - g_bWantFallbackCdTitle = true; - SwitchToPreferredDifficulty(); break; default: FAIL_M(ssprintf("Invalid WheelItemDataType: %i", wtype)); } - m_sprCDTitleFront.UnloadTexture(); - m_sprCDTitleBack.UnloadTexture(); - // Cancel any previous, incomplete requests for song assets, // since we need new ones. m_BackgroundLoader.Abort(); - g_bCDTitleWaiting = false; - if (!g_sCDTitlePath.empty() || g_bWantFallbackCdTitle) { - if (PREFSMAN->m_verbose_log > 1) - LOG->Trace("cache \"%s\"", g_sCDTitlePath.c_str()); - m_BackgroundLoader.CacheFile(g_sCDTitlePath); // empty OK - g_bCDTitleWaiting = true; - } - - g_bBannerWaiting = false; - if (bWantBanner) { - if (PREFSMAN->m_verbose_log > 1) - LOG->Trace("LoadFromCachedBanner(%s)", g_sBannerPath.c_str()); - if (m_Banner.LoadFromCachedBanner(g_sBannerPath)) { - /* If the high-res banner is already loaded, just delay before - * loading it, so the low-res one has time to fade in. */ - if (!TEXTUREMAN->IsTextureRegistered( - Sprite::SongBannerTexture(g_sBannerPath))) - m_BackgroundLoader.CacheFile(g_sBannerPath); - - g_bBannerWaiting = true; - } - } - // Don't stop music if it's already playing the right file. g_bSampleMusicWaiting = false; if (!m_MusicWheel.IsRouletting() && @@ -1805,7 +1641,7 @@ ScreenSelectMusic::OnConfirmSongDeletion() // delete the song directory from disk FILEMAN->DeleteRecursive(deleteDir); - m_pSongAwaitingDeletionConfirmation = NULL; + m_pSongAwaitingDeletionConfirmation = nullptr; } bool diff --git a/src/ScreenSelectMusic.h b/src/ScreenSelectMusic.h index 806d00c1ca..57eef809c7 100644 --- a/src/ScreenSelectMusic.h +++ b/src/ScreenSelectMusic.h @@ -164,10 +164,6 @@ class ScreenSelectMusic : public ScreenWithMenuElements RString m_sLoopMusicPath; RString m_sFallbackCDTitlePath; - FadingBanner m_Banner; - Sprite m_sprCDTitleFront, m_sprCDTitleBack; - AutoActor m_sprHighScoreFrame[NUM_PLAYERS]; - BitmapText m_textHighScore[NUM_PLAYERS]; MusicWheel m_MusicWheel; OptionsList m_OptionsList[NUM_PLAYERS]; From 5c9b126645e7108073f53eab10399cf4dbf3c9c8 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 16:33:11 -0500 Subject: [PATCH 18/43] move get display score to fallback scores script could these possibly leak/trap mem? they should probably be done directly in scoreman --- .../wifeTwirl.lua | 107 ------------------ Themes/_fallback/Scripts/10 Scores.lua | 70 ++++++++++++ 2 files changed, 70 insertions(+), 107 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index ea4d72b89d..b27a9c4505 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -75,113 +75,6 @@ t[#t + 1] = end } --- Temporary update control tower; it would be nice if the basic song/step change commands were thorough and explicit and non-redundant -t[#t + 1] = - Def.Actor { - SetCommand = function(self) - if song and not alreadybroadcasted then -- if this is true it means we've just exited a pack's songlist into the packlist - song = GAMESTATE:GetCurrentSong() -- also apprently true if we're tabbing around within a songlist and then stop... - MESSAGEMAN:Broadcast("UpdateChart") -- ms.ok(whee:GetSelectedSection( )) -- use this later to detect pack changes - MESSAGEMAN:Broadcast("RefreshChartInfo") - else - alreadybroadcasted = false - end - end, - CurrentStepsP1ChangedMessageCommand = function(self) - song = GAMESTATE:GetCurrentSong() - MESSAGEMAN:Broadcast("UpdateChart") - end, - CurrentSongChangedMessageCommand = function(self) - -- This will disable mirror when switching songs if OneShotMirror is enabled or if permamirror is flagged on the chart (it is enabled if so in screengameplayunderlay/default) - if playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).OneShotMirror or profile:IsCurrentChartPermamirror() then - local modslevel = topscreen == "ScreenEditOptions" and "ModsLevel_Stage" or "ModsLevel_Preferred" - local playeroptions = GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerOptions(modslevel) - playeroptions:Mirror(false) - end - if not GAMESTATE:GetCurrentSong() and noteField and mcbootlarder:GetVisible() then - mcbootlarder:visible(false) - MESSAGEMAN:Broadcast("ChartPreviewOff") - heyiwasusingthat = true - end - if heyiwasusingthat and GAMESTATE:GetCurrentSong() and noteField and getTabIndex() == 0 then - mcbootlarder:visible(true) - MESSAGEMAN:Broadcast("ChartPreviewOn") - heyiwasusingthat = false - end - self:queuecommand("Set") - end -} - -local function GetBestScoreByFilter(perc, CurRate) - local rtTable = getRateTable() - if not rtTable then - return nil - end - - local rates = tableKeys(rtTable) - local scores, score - - if CurRate then - local tmp = getCurRateString() - if tmp == "1x" then - tmp = "1.0x" - end - if tmp == "2x" then - tmp = "2.0x" - end - rates = {tmp} - if not rtTable[rates[1]] then - return nil - end - end - - table.sort( - rates, - function(a, b) - a = a:gsub("x", "") - b = b:gsub("x", "") - return a < b - end - ) - for i = #rates, 1, -1 do - scores = rtTable[rates[i]] - local bestscore = 0 - local index - - for ii = 1, #scores do - score = scores[ii] - if score:ConvertDpToWife() > bestscore then - index = ii - bestscore = score:ConvertDpToWife() - end - end - - if index and scores[index]:GetWifeScore() == 0 and GetPercentDP(scores[index]) > perc * 100 then - return scores[index] - end - - if bestscore > perc then - return scores[index] - end - end -end - -local function GetDisplayScore() - local score - score = GetBestScoreByFilter(0, true) - - if not score then - score = GetBestScoreByFilter(0.9, false) - end - if not score then - score = GetBestScoreByFilter(0.5, false) - end - if not score then - score = GetBestScoreByFilter(0, false) - end - return score -end - local function toggleNoteField() if song and not noteField then -- first time setup noteField = true diff --git a/Themes/_fallback/Scripts/10 Scores.lua b/Themes/_fallback/Scripts/10 Scores.lua index a97fff2d8a..460048bde7 100644 --- a/Themes/_fallback/Scripts/10 Scores.lua +++ b/Themes/_fallback/Scripts/10 Scores.lua @@ -504,3 +504,73 @@ function getRescoredCustomPercentage(offsetVector, customWindows, totalHolds, ho p = p / ((totalNotes * weights.marv) + (totalHolds * weights.holdHit)) return p * 100.0 end + +function GetDisplayScoreByFilter(perc, CurRate) -- moved from wifetwirl, displays the score for the current rate if there is one, + local rtTable = getRateTable() -- if not it looks for what might plausibly be your best by going down each rate + if not rtTable then + return nil + end + + local rates = tableKeys(rtTable) + local scores, score + + if CurRate then + local tmp = getCurRateString() + if tmp == "1x" then + tmp = "1.0x" + end + if tmp == "2x" then + tmp = "2.0x" + end + rates = {tmp} + if not rtTable[rates[1]] then + return nil + end + end + + table.sort( + rates, + function(a, b) + a = a:gsub("x", "") + b = b:gsub("x", "") + return a < b + end + ) + for i = #rates, 1, -1 do + scores = rtTable[rates[i]] + local bestscore = 0 + local index + + for ii = 1, #scores do + score = scores[ii] + if score:ConvertDpToWife() > bestscore then + index = ii + bestscore = score:ConvertDpToWife() + end + end + + if index and scores[index]:GetWifeScore() == 0 and GetPercentDP(scores[index]) > perc * 100 then + return scores[index] + end + + if bestscore > perc then + return scores[index] + end + end +end + +function GetDisplayScore() -- wrapper for above that prioritizes current rate's pb > any rate 90% > any rate 50% > any score any rate + local score + score = GetDisplayScoreByFilter(0, true) + + if not score then + score = GetDisplayScoreByFilter(0.9, false) + end + if not score then + score = GetDisplayScoreByFilter(0.5, false) + end + if not score then + score = GetDisplayScoreByFilter(0, false) + end + return score +end \ No newline at end of file From 879bf47f700b7aecb4bef01b63b418405fe200b1 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 16:35:38 -0500 Subject: [PATCH 19/43] update comment for something that should be its own commit but i forgot --- src/ScreenSelectMusic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index 126648798d..b993923b95 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -1454,7 +1454,8 @@ ScreenSelectMusic::AfterMusicChange() if (pSong != nullptr) GAMESTATE->m_pPreferredSong = pSong; else - GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); // set steps to null when moving out of packs -mina + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); // set steps to null when moving out of packs + // so that currentstepsp1 gets broadcast when moving into packs -mina GAMESTATE->SetPaused(false); // hacky can see this being problematic // if we forget about it -mina From cce801a9981c0b40049d00064138623aca4737b6 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 16:50:27 -0500 Subject: [PATCH 20/43] wifetwirl refactor part 1 mostly making update order less completely idiotic --- .../wifeTwirl.lua | 479 +++++++----------- 1 file changed, 194 insertions(+), 285 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index b27a9c4505..420cf03a59 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -20,7 +20,7 @@ local update = false local t = Def.ActorFrame { BeginCommand = function(self) - self:queuecommand("Set") + self:queuecommand("MintyFresh") end, OffCommand = function(self) self:bouncebegin(0.2):xy(-500, 0):diffusealpha(0) @@ -28,8 +28,9 @@ local t = OnCommand = function(self) self:bouncebegin(0.2):xy(0, 0):diffusealpha(1) end, - SetCommand = function(self) + MintyFreshCommand = function(self) self:finishtweening() + song = GAMESTATE:GetCurrentSong() if getTabIndex() == 0 then if heyiwasusingthat and GAMESTATE:GetCurrentSong() and noteField then -- these can prolly be wrapped better too -mina mcbootlarder:visible(true) @@ -47,10 +48,35 @@ local t = self:queuecommand("Off") update = false end + if song and not alreadybroadcasted then + song = GAMESTATE:GetCurrentSong() +-- MESSAGEMAN:Broadcast("UpdateChart") +-- MESSAGEMAN:Broadcast("RefreshChartInfo") + --ms.ok(whee:GetSelectedSection( )) + else + alreadybroadcasted = false + end end, TabChangedMessageCommand = function(self) - self:queuecommand("Set") - end + self:queuecommand("MintyFresh") + end, + CurrentStepsP1ChangedMessageCommand = function(self) + self:queuecommand("MintyFresh") + end, + Def.Quad { + InitCommand = function(self) + self:xy(frameX, frameY - 76):zoomto(110, 94):halign(0):valign(0):diffuse(color("#333333A6")) + end + }, + Def.Quad { + InitCommand = function(self) + self:xy(frameX, frameY - 76):zoomto(8, 144):halign(0):valign(0):diffuse(getMainColor("highlight")):diffusealpha(0.5) + end + },Def.Quad { + InitCommand = function(self) + self:xy(frameX, frameY + 18):zoomto(frameWidth + 4, 50):halign(0):valign(0):diffuse(color("#333333A6")) + end + } } -- Music Rate Display @@ -62,7 +88,7 @@ t[#t + 1] = capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45) ) end, - SetCommand = function(self) + MintyFreshCommand = function(self) self:settext(getCurRateDisplayString()) end, CodeMessageCommand = function(self, params) @@ -71,7 +97,7 @@ t[#t + 1] = self:settext(getCurRateDisplayString()) end, GoalSelectedMessageCommand = function(self) - self:queuecommand("Set") + self:queuecommand("MintyFresh") end } @@ -100,278 +126,162 @@ end t[#t + 1] = Def.Actor { - SetCommand = function(self) + MintyFreshCommand = function(self) if song then ptags = tags:get_data().playerTags steps = GAMESTATE:GetCurrentSteps(PLAYER_1) chartKey = steps:GetChartKey() - score = GetDisplayScore() ctags = {} for k, v in pairs(ptags) do if ptags[k][chartKey] then ctags[#ctags + 1] = k end end - MESSAGEMAN:Broadcast("RefreshChartInfo") end - end, - UpdateChartMessageCommand = function(self) - self:queuecommand("Set") - end, - CurrentRateChangedMessageCommand = function() - score = GetDisplayScore() end } -t[#t + 1] = - Def.ActorFrame { - -- **frames/bars** - Def.Quad { - InitCommand = function(self) - self:xy(frameX, frameY - 76):zoomto(110, 94):halign(0):valign(0):diffuse(color("#333333CC")):diffusealpha(0.66) - end - }, - Def.Quad { - InitCommand = function(self) - self:xy(frameX, frameY + 18):zoomto(frameWidth + 4, 50):halign(0):valign(0):diffuse(color("#333333CC")):diffusealpha( - 0.66 - ) - end - }, - Def.Quad { +t[#t + 1] = Def.ActorFrame { + Name = "RateDependentStuff", -- msd/display score/bpm/songlength -mina + MintyFreshCommand = function() + score = GetDisplayScore() + end, + CurrentRateChangedMessageCommand = function(self) + self:queuecommand("MintyFresh") + end, + LoadFont("Common Normal") .. { + Name = "MSD", InitCommand = function(self) - self:xy(frameX, frameY - 76):zoomto(8, 144):halign(0):valign(0):diffuse(getMainColor("highlight")):diffusealpha(0.5) + self:xy(frameX + 58, frameY - 62):halign(0.5):maxwidth(110 / 0.6) + end, + MintyFreshCommand = function(self) + if song then + if steps:GetStepsType() == "StepsType_Dance_Single" then + local meter = steps:GetMSD(getCurRateValue(), 1) + self:settextf("%05.2f", meter) + self:diffuse(byMSD(meter)) + else + self:settextf("%5.2f", steps:GetMeter()) -- fallthrough to pre-defined meters for non 4k charts -mina + self:diffuse(byDifficulty(steps:GetDifficulty())) + end + else + self:settext("") + end end }, -- **score related stuff** These need to be updated with rate changed commands -- Primary percent score - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX + 55, frameY + 50):zoom(0.6):halign(0.5):maxwidth(125):valign(1) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - SetCommand = function(self) - if song and score then - self:settextf("%05.2f%%", notShit.floor(score:GetWifeScore() * 10000) / 100) - self:diffuse(getGradeColor(score:GetWifeGrade())) - else - self:settext("") - end - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 55, frameY + 50):zoom(0.8):halign(0.5):maxwidth(125):valign(1) + end, + MintyFreshCommand = function(self) + if song and score then + self:settextf("%05.2f%%", notShit.floor(score:GetWifeScore() * 10000) / 100) + self:diffuse(getGradeColor(score:GetWifeGrade())) + else + self:settext("") end - }, + end, + }, -- Rate for the displayed score - LoadFont("Common Normal") .. - { - InitCommand = function(self) - self:xy(frameX + 55, frameY + 58):zoom(0.5):halign(0.5) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - SetCommand = function(self) - if song and score then - local rate = notShit.round(score:GetMusicRate(), 3) - local notCurRate = notShit.round(getCurRateValue(), 3) ~= rate - + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 55, frameY + 58):zoom(0.5):halign(0.5) + end, + MintyFreshCommand = function(self) + if song and score then + local rate = notShit.round(score:GetMusicRate(), 3) + local notCurRate = notShit.round(getCurRateValue(), 3) ~= rate local rate = string.format("%.2f", rate) - if rate:sub(#rate, #rate) == "0" then - rate = rate:sub(0, #rate - 1) - end - rate = rate .. "x" - + if rate:sub(#rate, #rate) == "0" then + rate = rate:sub(0, #rate - 1) + end + rate = rate .. "x" if notCurRate then - self:settext("(" .. rate .. ")") - else - self:settext(rate) - end + self:settext("(" .. rate .. ")") else - self:settext("") + self:settext(rate) end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") + else + self:settext("") end - }, + end + }, -- Date score achieved on - LoadFont("Common Normal") .. - { - InitCommand = function(self) - self:xy(frameX + 185, frameY + 59):zoom(0.4):halign(0) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - SetCommand = function(self) - if song and score then - self:settext(score:GetDate()) - else - self:settext("") - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 185, frameY + 59):zoom(0.4):halign(0) + end, + BeginCommand = function(self) + self:queuecommand("Set") + end, + MintyFreshCommand = function(self) + if song and score then + self:settext(score:GetDate()) + else + self:settext("") end - }, + end + }, -- MaxCombo - LoadFont("Common Normal") .. - { - InitCommand = function(self) - self:xy(frameX + 185, frameY + 49):zoom(0.4):halign(0) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - SetCommand = function(self) - if song and score then - self:settextf("Max Combo: %d", score:GetMaxCombo()) - else - self:settext("") - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end - } - -- **End score related stuff** -} - --- "Radar values" aka basic chart information -local function radarPairs(i) - local o = - Def.ActorFrame { - LoadFont("Common Normal") .. - { - InitCommand = function(self) - self:xy(frameX + 13, frameY - 52 + 13 * i):zoom(0.5):halign(0):maxwidth(120) - end, - SetCommand = function(self) - if song then - self:settext(ms.RelevantRadarsShort[i]) - else - self:settext("") - end - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end - }, - LoadFont("Common Normal") .. - { - InitCommand = function(self) - self:xy(frameX + 105, frameY + -52 + 13 * i):zoom(0.5):halign(1):maxwidth(60) - end, - SetCommand = function(self) - if song then - self:settext(steps:GetRelevantRadars(PLAYER_1)[i]) - else - self:settext("") - end - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end - } - } - return o -end - --- Create the radar values -for i = 1, 5 do - t[#t + 1] = radarPairs(i) -end - --- Difficulty value ("meter"), need to change this later -t[#t + 1] = - LoadFont("Common Large") .. - { + LoadFont("Common Normal") .. { InitCommand = function(self) - self:xy(frameX + 58, frameY - 62):halign(0.5):zoom(0.6):maxwidth(110 / 0.6) + self:xy(frameX + 185, frameY + 49):zoom(0.4):halign(0) end, BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) - if song then - if steps:GetStepsType() == "StepsType_Dance_Single" then - local meter = steps:GetMSD(getCurRateValue(), 1) - self:settextf("%05.2f", meter) - self:diffuse(byMSD(meter)) - else - self:settextf("%5.2f", steps:GetMeter()) - self:diffuse(byDifficulty(steps:GetDifficulty())) - end + MintyFreshCommand = function(self) + if song and score then + self:settextf("Max Combo: %d", score:GetMaxCombo()) else self:settext("") end + end + }, + LoadFont("Common Normal") .. { + Name = "ClearType", + InitCommand = function(self) + self:xy(frameX + 185, frameY + 35):zoom(0.6):halign(0) end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") + MintyFreshCommand = function(self) + if song and score then + self:visible(true) + self:settext(getClearTypeFromScore(PLAYER_1, score, 0)) + self:diffuse(getClearTypeFromScore(PLAYER_1, score, 2)) + else + self:visible(false) + end + end + }, + -- **song stuff** + Def.BPMDisplay { + File = THEME:GetPathF("BPMDisplay", "bpm"), + Name = "BPMDisplay", + InitCommand = function(self) + self:xy(capWideScale(get43size(384), 384) + 62, SCREEN_BOTTOM - 100):halign(1):zoom(0.50) end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") + MintyFreshCommand = function(self) + if song then + self:visible(true) + self:SetFromSong(song) + else + self:visible(false) + end end - } - --- -- test adjustment index --- t[#t+1] = LoadFont("Common normal")..{ --- InitCommand=function(self) --- self:xy(frameX+92,frameY-70):halign(0):zoom(0.4) --- end, --- ChartLeaderboardUpdateMessageCommand = function(self,params) --- local val = params.mmm --- if val then --- if val > 0 then --- self:settextf("%+5.1f", val) --- else --- self:settextf("%5.1f", val) --- end --- else --- self:settext("") --- end --- end, --- LogOutMessageCommand=function(self) --- self:settext("") --- end, --- RefreshChartInfoMessageCommand=function(self) --- if song then --- self:visible(true) --- else --- self:visible(false) --- end --- end, --- } - --- Song duration -t[#t + 1] = - LoadFont("Common Large") .. - { + }, + LoadFont("Common Normal") .. { + Name = "PlayableDuration", InitCommand = function(self) self:xy((capWideScale(get43size(384), 384)) + 62, SCREEN_BOTTOM - 85):visible(true):halign(1):zoom( - capWideScale(get43size(0.6), 0.6) + capWideScale(get43size(0.8), 0.8) ):maxwidth(capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45)) end, BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song then local playabletime = GetPlayableTime() self:settext(SecondsToMMSS(playabletime)) @@ -387,35 +297,54 @@ t[#t + 1] = self:queuecommand("Set") end } +} + +-- "Radar values", noteinfo that isn't rate dependent -mina +local function radarPairs(i) + local o = + Def.ActorFrame { + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 13, frameY - 52 + 13 * i):zoom(0.5):halign(0):maxwidth(120) + end, + MintyFreshCommand = function(self) + if song then + self:settext(ms.RelevantRadarsShort[i]) + else + self:settext("") + end + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 105, frameY + -52 + 13 * i):zoom(0.5):halign(1):maxwidth(60) + end, + MintyFreshCommand = function(self) + if song then + self:settext(steps:GetRelevantRadars(PLAYER_1)[i]) + else + self:settext("") + end + end + } + } + return o +end --- BPM display/label not sure why this was never with the chart info in the first place -t[#t + 1] = - Def.BPMDisplay { - File = THEME:GetPathF("BPMDisplay", "bpm"), - Name = "BPMDisplay", - InitCommand = function(self) - self:xy(capWideScale(get43size(384), 384) + 62, SCREEN_BOTTOM - 100):halign(1):zoom(0.50) - end, - SetCommand = function(self) - if song then - self:visible(1) - self:SetFromSong(song) - else - self:visible(0) - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end +local r = Def.ActorFrame{ + Name = "RadarValues" } +-- Create the radar values +for i = 1, 5 do + r[#r + 1] = radarPairs(i) +end +t[#t + 1] = r + t[#t + 1] = LoadFont("Common Normal") .. { - SetCommand = function(self) + MintyFreshCommand = function(self) if song then self:settext("BPM") else @@ -437,7 +366,7 @@ t[#t + 1] = InitCommand = function(self) self:xy(capWideScale(get43size(344), 364) + 50, capWideScale(get43size(345), 255)):halign(0.5):valign(1) end, - SetCommand = function(self) + MintyFreshCommand = function(self) self:finishtweening() if GAMESTATE:GetCurrentSong() then local song = GAMESTATE:GetCurrentSong() @@ -494,7 +423,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song and steps:GetTimingData():HasWarps() then self:settext("NegBpms!") else @@ -518,7 +447,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song and steps then local goal = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) if goal then @@ -550,7 +479,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song and steps then local goal = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) if goal then @@ -672,7 +601,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song then self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 1)) else @@ -702,7 +631,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song then self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 2)) else @@ -732,7 +661,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song then self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 3)) else @@ -763,7 +692,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song and ctags[1] then self:settext(ctags[1]) else @@ -787,7 +716,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song and ctags[2] then self:settext(ctags[2]) else @@ -811,7 +740,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) if song and ctags[3] then self:settext(ctags[3]) else @@ -826,26 +755,6 @@ t[#t + 1] = end } - t[#t + 1] = - LoadFont("Common Normal") .. - { - Name = "ClearType", - InitCommand = function(self) - self:xy(frameX + 185, frameY + 35):zoom(0.6):halign(0) - end, - RefreshChartInfoMessageCommand = function(self) - if song and score then - self:visible(true) - self:settext(getClearTypeFromScore(PLAYER_1, score, 0)) - self:diffuse(getClearTypeFromScore(PLAYER_1, score, 2)) - else - self:visible(false) - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("RefreshChartInfo") - end, - } --test actor t[#t + 1] = @@ -857,7 +766,7 @@ t[#t + 1] = BeginCommand = function(self) self:queuecommand("Set") end, - SetCommand = function(self) + MintyFreshCommand = function(self) --ms.type(profile:GetGoalByKey(getCurKey())) self:settext("") end, From e0054b8ed9a2f11d8e0e613dfbf1093b2dacd75e Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 21:42:43 -0500 Subject: [PATCH 21/43] wifetwirl refactor part 2 move banner to wifetwirl and more of the same --- .../songinfo.lua | 62 --- .../wifeTwirl.lua | 469 ++++++------------ 2 files changed, 147 insertions(+), 384 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/songinfo.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/songinfo.lua index 5dead44022..e69de29bb2 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/songinfo.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/songinfo.lua @@ -1,62 +0,0 @@ -local update = false -local t = - Def.ActorFrame { - BeginCommand = function(self) - self:queuecommand("Set") - end, - OffCommand = function(self) - self:bouncebegin(0.2):xy(-500, 0) -- visible(false) - end, - OnCommand = function(self) - self:bouncebegin(0.2):xy(0, 0) - end, - SetCommand = function(self) - self:finishtweening() - if getTabIndex() == 0 then - self:queuecommand("On") - update = true - else - self:queuecommand("Off") - update = false - end - end, - TabChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - ChartPreviewOnMessageCommand = function(self) - self:visible(false) - end, - ChartPreviewOffMessageCommand = function(self) - self:visible(true) - end, -} - -t[#t + 1] = - Def.Banner { - InitCommand = function(self) - self:x(10):y(61):halign(0):valign(0):scaletoclipped( - capWideScale(get43size(384), 384), - capWideScale(get43size(120), 120) - ) - end, - SetMessageCommand = function(self) - if update then - local top = SCREENMAN:GetTopScreen() - if top:GetName() == "ScreenSelectMusic" or top:GetName() == "ScreenNetSelectMusic" then - local song = GAMESTATE:GetCurrentSong() - local group = top:GetMusicWheel():GetSelectedSection() - if song then - self:LoadFromSong(song) - elseif group then - self:LoadFromSongGroup(group) - end - end - end - self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)) - end, - CurrentSongChangedMessageCommand = function(self) - self:queuecommand("Set") - end -} - -return t diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index 420cf03a59..d24af38fda 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -2,11 +2,9 @@ local profile = PROFILEMAN:GetProfile(PLAYER_1) local frameX = 10 local frameY = 250 + capWideScale(get43size(120), 90) local frameWidth = capWideScale(get43size(455), 455) -local scoreType = themeConfig:get_data().global.DefaultScoreType local score local song local steps -local alreadybroadcasted local noteField = false local heyiwasusingthat = false local mcbootlarder @@ -19,9 +17,6 @@ local prevrevY = 208 local update = false local t = Def.ActorFrame { - BeginCommand = function(self) - self:queuecommand("MintyFresh") - end, OffCommand = function(self) self:bouncebegin(0.2):xy(-500, 0):diffusealpha(0) end, @@ -30,7 +25,14 @@ local t = end, MintyFreshCommand = function(self) self:finishtweening() - song = GAMESTATE:GetCurrentSong() + local bong = GAMESTATE:GetCurrentSong() + if not bong then + self:queuecommand("MilkyTarts") + end + if song ~= bong then + song = bong + self:queuecommand("MortyFarts") + end if getTabIndex() == 0 then if heyiwasusingthat and GAMESTATE:GetCurrentSong() and noteField then -- these can prolly be wrapped better too -mina mcbootlarder:visible(true) @@ -48,14 +50,6 @@ local t = self:queuecommand("Off") update = false end - if song and not alreadybroadcasted then - song = GAMESTATE:GetCurrentSong() --- MESSAGEMAN:Broadcast("UpdateChart") --- MESSAGEMAN:Broadcast("RefreshChartInfo") - --ms.ok(whee:GetSelectedSection( )) - else - alreadybroadcasted = false - end end, TabChangedMessageCommand = function(self) self:queuecommand("MintyFresh") @@ -81,10 +75,10 @@ local t = -- Music Rate Display t[#t + 1] = - LoadFont("Common Large") .. + LoadFont("Common Normal") .. { InitCommand = function(self) - self:xy(18, SCREEN_BOTTOM - 225):visible(true):halign(0):zoom(0.4):maxwidth( + self:xy(18, SCREEN_BOTTOM - 225):visible(true):halign(0):zoom(0.8):maxwidth( capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45) ) end, @@ -147,7 +141,8 @@ t[#t + 1] = Def.ActorFrame { score = GetDisplayScore() end, CurrentRateChangedMessageCommand = function(self) - self:queuecommand("MintyFresh") + self:queuecommand("MintyFresh") --steps stuff + self:queuecommand("MortyFarts") --songs stuff end, LoadFont("Common Normal") .. { Name = "MSD", @@ -169,6 +164,61 @@ t[#t + 1] = Def.ActorFrame { end end }, + -- skillset suff (these 3 can prolly be wrapped) + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 120, frameY - 60):halign(0):zoom(0.6, maxwidth, 125) + end, + MintyFreshCommand = function(self) + if song then + self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 1)) + else + self:settext("") + end + end, + ChartPreviewOnMessageCommand = function(self) + self:visible(false) + end, + ChartPreviewOffMessageCommand = function(self) + self:visible(true) + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 120, frameY - 30):halign(0):zoom(0.6, maxwidth, 125) + end, + MintyFreshCommand = function(self) + if song then + self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 2)) + else + self:settext("") + end + end, + ChartPreviewOnMessageCommand = function(self) + self:visible(false) + end, + ChartPreviewOffMessageCommand = function(self) + self:visible(true) + end + }, + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX + 120, frameY):halign(0):zoom(0.6, maxwidth, 125) + end, + MintyFreshCommand = function(self) + if song then + self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 3)) + else + self:settext("") + end + end, + ChartPreviewOnMessageCommand = function(self) + self:visible(false) + end, + ChartPreviewOffMessageCommand = function(self) + self:visible(true) + end + }, -- **score related stuff** These need to be updated with rate changed commands -- Primary percent score LoadFont("Common Normal") .. { @@ -208,14 +258,30 @@ t[#t + 1] = Def.ActorFrame { end end }, + -- goal for current rate if there is one stuff + LoadFont("Common Normal") .. { + Name = "Goalll", + InitCommand = function(self) + self:xy(frameX + 135, frameY + 33):zoom(0.6):halign(0.5):valign(0) + end, + MintyFreshCommand = function(self) + if song and steps then + local goal = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) + if goal then + self:settextf("Target\n%.2f%%", goal:GetPercent() * 100) + else + self:settext("") + end + else + self:settext("") + end + end + }, -- Date score achieved on LoadFont("Common Normal") .. { InitCommand = function(self) self:xy(frameX + 185, frameY + 59):zoom(0.4):halign(0) end, - BeginCommand = function(self) - self:queuecommand("Set") - end, MintyFreshCommand = function(self) if song and score then self:settext(score:GetDate()) @@ -229,9 +295,6 @@ t[#t + 1] = Def.ActorFrame { InitCommand = function(self) self:xy(frameX + 185, frameY + 49):zoom(0.4):halign(0) end, - BeginCommand = function(self) - self:queuecommand("Set") - end, MintyFreshCommand = function(self) if song and score then self:settextf("Max Combo: %d", score:GetMaxCombo()) @@ -255,14 +318,14 @@ t[#t + 1] = Def.ActorFrame { end end }, - -- **song stuff** + -- **song stuff that scales with rate** Def.BPMDisplay { File = THEME:GetPathF("BPMDisplay", "bpm"), Name = "BPMDisplay", InitCommand = function(self) self:xy(capWideScale(get43size(384), 384) + 62, SCREEN_BOTTOM - 100):halign(1):zoom(0.50) end, - MintyFreshCommand = function(self) + MortyFartsCommand = function(self) if song then self:visible(true) self:SetFromSong(song) @@ -278,10 +341,7 @@ t[#t + 1] = Def.ActorFrame { capWideScale(get43size(0.8), 0.8) ):maxwidth(capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45)) end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) + MortyFartsCommand = function(self) if song then local playabletime = GetPlayableTime() self:settext(SecondsToMMSS(playabletime)) @@ -289,12 +349,6 @@ t[#t + 1] = Def.ActorFrame { else self:settext("") end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") end } } @@ -339,37 +393,47 @@ local r = Def.ActorFrame{ for i = 1, 5 do r[#r + 1] = radarPairs(i) end -t[#t + 1] = r -t[#t + 1] = - LoadFont("Common Normal") .. - { +-- putting neg bpm warning here i guess +r[#r + 1] = + LoadFont("Common Normal") .. { + InitCommand = function(self) + self:xy(frameX, frameY - 120):halign(0):zoom(0.6) + end, MintyFreshCommand = function(self) - if song then - self:settext("BPM") + if song and steps:GetTimingData():HasWarps() then + self:settext("NegBpms!") else self:settext("") end - end, + end + } + +t[#t + 1] = r + +-- song only stuff that doesnt change with rate +t[#t + 1] = + LoadFont("Common Normal") .. { InitCommand = function(self) self:xy(capWideScale(get43size(384), 384) + 41, SCREEN_BOTTOM - 100):halign(1):zoom(0.50) end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") + MortyFartsCommand = function(self) + if song then + self:settext("BPM") + else + self:settext("") + end end } --- CDtitle, need to figure out a better place for this later. -mina ---Gonna move the cdtitle right next to selected song similar to ultralight. -Misterkister +-- cdtitle t[#t + 1] = Def.Sprite { InitCommand = function(self) self:xy(capWideScale(get43size(344), 364) + 50, capWideScale(get43size(345), 255)):halign(0.5):valign(1) end, - MintyFreshCommand = function(self) + MortyFartsCommand = function(self) self:finishtweening() - if GAMESTATE:GetCurrentSong() then - local song = GAMESTATE:GetCurrentSong() if song then if song:HasCDTitle() then self:visible(true) @@ -396,15 +460,6 @@ t[#t + 1] = else self:zoom(1) end - else - self:visible(false) - end - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") end, ChartPreviewOnMessageCommand=function(self) self:addx(capWideScale(34,0)) @@ -415,92 +470,32 @@ t[#t + 1] = } t[#t + 1] = - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX, frameY - 120):halign(0):zoom(0.4) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) - if song and steps:GetTimingData():HasWarps() then - self:settext("NegBpms!") - else - self:settext("") - end - end, - CurrentStepsP1ChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end - } - -t[#t + 1] = - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX + 135, frameY + 45):zoom(0.3):halign(0.5):valign(1) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) - if song and steps then - local goal = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) - if goal then - self:settext("Target:") - else - self:settext("") - end - else - self:settext("") - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - CurrentStepsP1ChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end - } - -t[#t + 1] = - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX + 135, frameY + 60):zoom(0.3):halign(0.5):valign(1) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) - if song and steps then - local goal = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) - if goal then - self:settextf("%.2f%%", goal:GetPercent() * 100) - else - self:settext("") - end - else - self:settext("") - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - CurrentStepsP1ChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") + Def.Banner { + InitCommand = function(self) + self:x(10):y(61):halign(0):valign(0):scaletoclipped( + capWideScale(get43size(384), 384), + capWideScale(get43size(120), 120) + ) + end, + MortyFartsCommand = function(self) + if song then + self:LoadFromSong(song) + else + local group = SCREENMAN:GetTopScreen():GetMusicWheel():GetSelectedSection() + self:LoadFromSongGroup(group) end - } + self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)) + end, + MilkyTartsCommand=function(self) + self:queuecommand("MortyFarts") -- for pack banners + end, + ChartPreviewOnMessageCommand = function(self) + self:visible(false) + end, + ChartPreviewOffMessageCommand = function(self) + self:visible(true) + end +} t[#t + 1] = Def.Quad { @@ -512,7 +507,7 @@ t[#t + 1] = local sg = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) if sg and isOver(self) and update then sg:SetPercent(sg:GetPercent() + 0.01) - MESSAGEMAN:Broadcast("RefreshChartInfo") + self:GetParent():GetChild("RateDependentStuff"):GetChild("Goalll"):queuecommand("MintyFresh") end end end, @@ -521,40 +516,12 @@ t[#t + 1] = local sg = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) if sg and isOver(self) and update then sg:SetPercent(sg:GetPercent() - 0.01) - MESSAGEMAN:Broadcast("RefreshChartInfo") + self:GetParent():GetChild("RateDependentStuff"):GetChild("Goalll"):queuecommand("MintyFresh") end end end } --- perhaps need this perhaps not --- t[#t+1] = LoadFont("Common Large") .. { --- InitCommand=function(self) --- self:xy(frameX+135,frameY+65):zoom(0.3):halign(0.5):valign(1) --- end, --- BeginCommand=function(self) --- self:queuecommand("Set") --- end, --- SetCommand=function(self) --- if steps then --- local goal = profile:GetEasiestGoalForChartAndRate(steps:GetChartKey(), getCurRateValue()) --- if goal then --- self:settextf("%.2f", goal:GetRate()) --- else --- self:settext("") --- end --- else --- self:settext("") --- end --- end, --- CurrentStepsP1ChangedMessageCommand=function(self) --- self:queuecommand("Set") --- end, --- RefreshChartInfoMessageCommand=function(self) --- self:queuecommand("Set") --- end, --- } - -- t[#t+1] = LoadFont("Common Large") .. { -- InitCommand=function(self) -- self:xy((capWideScale(get43size(384),384))+68,SCREEN_BOTTOM-135):halign(1):zoom(0.4,maxwidth,125) @@ -592,105 +559,12 @@ t[#t + 1] = -- end -- } -t[#t + 1] = - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX + 120, frameY - 60):halign(0):zoom(0.4, maxwidth, 125) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) - if song then - self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 1)) - else - self:settext("") - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end, - ChartPreviewOnMessageCommand = function(self) - self:visible(false) - end, - ChartPreviewOffMessageCommand = function(self) - self:visible(true) - end, - } - -t[#t + 1] = - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX + 120, frameY - 30):halign(0):zoom(0.4, maxwidth, 125) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) - if song then - self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 2)) - else - self:settext("") - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end, - ChartPreviewOnMessageCommand = function(self) - self:visible(false) - end, - ChartPreviewOffMessageCommand = function(self) - self:visible(true) - end, - } - -t[#t + 1] = - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX + 120, frameY):halign(0):zoom(0.4, maxwidth, 125) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) - if song then - self:settext(steps:GetRelevantSkillsetsByMSDRank(getCurRateValue(), 3)) - else - self:settext("") - end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end, - ChartPreviewOnMessageCommand = function(self) - self:visible(false) - end, - ChartPreviewOffMessageCommand = function(self) - self:visible(true) - end, - } -- tags? t[#t + 1] = - LoadFont("Common Large") .. - { + LoadFont("Common Normal") .. { InitCommand = function(self) - self:xy(frameX + 300, frameY - 60):halign(0):zoom(0.4):maxwidth(450) - end, - BeginCommand = function(self) - self:queuecommand("Set") + self:xy(frameX + 300, frameY - 60):halign(0):zoom(0.6):maxwidth(450) end, MintyFreshCommand = function(self) if song and ctags[1] then @@ -698,23 +572,13 @@ t[#t + 1] = else self:settext("") end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") end } t[#t + 1] = - LoadFont("Common Large") .. - { + LoadFont("Common Normal") .. { InitCommand = function(self) - self:xy(frameX + 300, frameY - 30):halign(0):zoom(0.4):maxwidth(450) - end, - BeginCommand = function(self) - self:queuecommand("Set") + self:xy(frameX + 300, frameY - 30):halign(0):zoom(0.6):maxwidth(450) end, MintyFreshCommand = function(self) if song and ctags[2] then @@ -722,23 +586,13 @@ t[#t + 1] = else self:settext("") end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") end } t[#t + 1] = - LoadFont("Common Large") .. - { + LoadFont("Common Normal") .. { InitCommand = function(self) - self:xy(frameX + 300, frameY):halign(0):zoom(0.4):maxwidth(450) - end, - BeginCommand = function(self) - self:queuecommand("Set") + self:xy(frameX + 300, frameY):halign(0):zoom(0.6):maxwidth(450) end, MintyFreshCommand = function(self) if song and ctags[3] then @@ -746,40 +600,11 @@ t[#t + 1] = else self:settext("") end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end - } - - ---test actor -t[#t + 1] = - LoadFont("Common Large") .. - { - InitCommand = function(self) - self:xy(frameX, frameY - 120):halign(0):zoom(0.4, maxwidth, 125) - end, - BeginCommand = function(self) - self:queuecommand("Set") - end, - MintyFreshCommand = function(self) - --ms.type(profile:GetGoalByKey(getCurKey())) - self:settext("") - end, - CurrentStepsP1ChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") end } - local yesiwantnotefield = false --Chart Preview Button +local yesiwantnotefield = false local function ihatestickinginputcallbackseverywhere(event) if event.type ~= "InputEventType_Release" and getTabIndex() == 0 then From 01710d71bb7467b1bd4f158207aa5307ed8476da Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 22:12:38 -0500 Subject: [PATCH 22/43] dont update dlman or dl progress overlay during gameplay --- .../ScreenSystemLayer overlay/default.lua | 6 +++ src/DownloadManager.cpp | 7 +++ src/ScreenInstallOverlay.cpp | 50 ++++++++++--------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua b/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua index 91ec592405..e64e8b44ce 100644 --- a/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua +++ b/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua @@ -56,6 +56,12 @@ local dltzoom = 0.5 -- download queue/progress t[#t + 1] = Def.ActorFrame { + PausingDownloadsMessageCommand=function(self) + self:visible(false) + end, + ResumingDownloadsMessageCommand=function(self) + self:visible(false) + end, AllDownloadsCompletedMessageCommand = function(self) self:visible(false) end, diff --git a/src/DownloadManager.cpp b/src/DownloadManager.cpp index 9a9ba7dd91..7b374c6c5a 100644 --- a/src/DownloadManager.cpp +++ b/src/DownloadManager.cpp @@ -428,6 +428,11 @@ void DownloadManager::UpdateDLSpeed(bool gameplay) { this->gameplay = gameplay; + if (gameplay) + MESSAGEMAN->Broadcast("PausingDownloads"); + else + MESSAGEMAN->Broadcast("ResumingDownloads"); + UpdateDLSpeed(); } @@ -492,6 +497,8 @@ DownloadManager::Update(float fDeltaSeconds) { if (!initialized) init(); + if (gameplay) + return; UpdatePacks(fDeltaSeconds); UpdateHTTP(fDeltaSeconds); return; diff --git a/src/ScreenInstallOverlay.cpp b/src/ScreenInstallOverlay.cpp index 9e21e96383..4b1f8ad761 100644 --- a/src/ScreenInstallOverlay.cpp +++ b/src/ScreenInstallOverlay.cpp @@ -250,34 +250,36 @@ ScreenInstallOverlay::Update(float fDeltaTime) DoInstalls(args); } #if !defined(WITHOUT_NETWORKING) - static float lastDLProgressUpdate = 0; - lastDLProgressUpdate += fDeltaTime; - if (DLMAN->downloads.empty() || lastDLProgressUpdate < 0.5) - return; - lastDLProgressUpdate = 0; - Message msg("DLProgressAndQueueUpdate"); + if (!DLMAN->gameplay) { + static float lastDLProgressUpdate = 0; + lastDLProgressUpdate += fDeltaTime; + if (DLMAN->downloads.empty() || lastDLProgressUpdate < 0.5) + return; + lastDLProgressUpdate = 0; + Message msg("DLProgressAndQueueUpdate"); - vector dls; - for (auto& dl : DLMAN->downloads) { - dls.push_back(dl.second->Status()); - } - msg.SetParam("dlsize", static_cast(DLMAN->downloads.size())); - msg.SetParam("dlprogress", join("\n", dls)); + vector dls; + for (auto& dl : DLMAN->downloads) { + dls.push_back(dl.second->Status()); + } + msg.SetParam("dlsize", static_cast(DLMAN->downloads.size())); + msg.SetParam("dlprogress", join("\n", dls)); - if (!DLMAN->DownloadQueue.empty()) { - vector cue; - for (auto& q : DLMAN->DownloadQueue) { - cue.push_back(q.first->name); + if (!DLMAN->DownloadQueue.empty()) { + vector cue; + for (auto& q : DLMAN->DownloadQueue) { + cue.push_back(q.first->name); + } + msg.SetParam("queuesize", + static_cast(DLMAN->DownloadQueue.size())); + msg.SetParam("queuedpacks", join("\n", cue)); + } else { + msg.SetParam("queuesize", 0); + msg.SetParam("queuedpacks", RString("")); } - msg.SetParam("queuesize", - static_cast(DLMAN->DownloadQueue.size())); - msg.SetParam("queuedpacks", join("\n", cue)); - } else { - msg.SetParam("queuesize", 0); - msg.SetParam("queuedpacks", RString("")); + MESSAGEMAN->Broadcast(msg); } - MESSAGEMAN->Broadcast(msg); - + #endif } From e1d1f0eb325452e34f9599cf0435f2112a6b300c Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 23:52:34 -0500 Subject: [PATCH 23/43] formatting because annoyed --- .../ScreenSelectMusic decorations/wifeTwirl.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index d24af38fda..967a9b1778 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -75,12 +75,10 @@ local t = -- Music Rate Display t[#t + 1] = - LoadFont("Common Normal") .. - { + LoadFont("Common Normal") .. { InitCommand = function(self) self:xy(18, SCREEN_BOTTOM - 225):visible(true):halign(0):zoom(0.8):maxwidth( - capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45) - ) + capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45)) end, MintyFreshCommand = function(self) self:settext(getCurRateDisplayString()) From 2cdb5b5de93286d06ae34b65917ffb5ac81b6a5d Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Wed, 21 Nov 2018 23:53:41 -0500 Subject: [PATCH 24/43] fix scoreboard oncommand being inherited improperly from scores.lua leading to redundant/unintentional leaderboard requests --- .../ScreenSelectMusic decorations/score.lua | 21 +++++++++---------- .../BGAnimations/superscoreboard.lua | 9 ++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua index 5055b3ca31..62d146b672 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua @@ -84,20 +84,26 @@ local function highlightIfOver(self) self:diffusealpha(1) end end - +local moped -- Only works if ... it should work -- You know, if we can see the place where the scores should be. local function updateLeaderBoardForCurrentChart() local top = SCREENMAN:GetTopScreen() if top:GetMusicWheel():IsSettled() and ((getTabIndex() == 2 and nestedTab == 2) or collapsed) then - local chartkey = GAMESTATE:GetCurrentSteps(PLAYER_1):GetChartKey() - DLMAN:RequestChartLeaderBoardFromOnline(chartkey) + local steps = GAMESTATE:GetCurrentSteps(PLAYER_1) + if steps then + DLMAN:RequestChartLeaderBoardFromOnline(steps:GetChartKey()) + moped:queuecommand("ChartLeaderboardUpdate") + else + moped:queuecommand("Bort") + end end end local ret = Def.ActorFrame { BeginCommand = function(self) + moped = self:GetChild("ScoreDisplay") self:queuecommand("Set"):visible(false) self:GetChild("LocalScores"):xy(frameX, frameY):visible(false) self:GetChild("ScoreDisplay"):xy(frameX, frameY):visible(false) @@ -143,9 +149,6 @@ local ret = self:queuecommand("Set") updateLeaderBoardForCurrentChart() end, - UpdateChartMessageCommand = function(self) - self:queuecommand("Set") - end, CollapseCommand = function(self) collapsed = true resetTabIndex() @@ -173,7 +176,7 @@ local ret = end, CurrentRateChangedMessageCommand = function(self) if ((getTabIndex() == 2 and nestedTab == 2) or collapsed) and DLMAN:GetCurrentRateFilter() then - MESSAGEMAN:Broadcast("ChartLeaderboardUpdate") + moped:queuecommand("ChartLeaderboardUpdate") end end } @@ -702,7 +705,6 @@ function nestedTabButton(i) if isOver(self) then nestedTab = i MESSAGEMAN:Broadcast("NestedTabChanged") - MESSAGEMAN:Broadcast("ChartLeaderboardUpdate") if nestedTab == 1 then self:GetParent():GetParent():GetChild("ScoreDisplay"):visible(false) self:GetParent():GetParent():GetParent():GetChild("StepsDisplay"):visible(true) @@ -711,9 +713,6 @@ function nestedTabButton(i) self:GetParent():GetParent():GetParent():GetChild("StepsDisplay"):visible(false) end end - end, - NestedTabChangedMessageCommand = function(self) - self:queuecommand("Set") end } } diff --git a/Themes/Til Death/BGAnimations/superscoreboard.lua b/Themes/Til Death/BGAnimations/superscoreboard.lua index c51ec94d94..204715b3de 100644 --- a/Themes/Til Death/BGAnimations/superscoreboard.lua +++ b/Themes/Til Death/BGAnimations/superscoreboard.lua @@ -103,15 +103,16 @@ local o = BeginCommand = function(self) SCREENMAN:GetTopScreen():AddInputCallback(input) end, - OnCommand = function(self) - GetPlayerOrMachineProfile(PLAYER_1):SetFromAll() - self:queuecommand("ChartLeaderboardUpdate") - end, ChartLeaderboardUpdateMessageCommand = function(self) scoretable = DLMAN:RequestChartLeaderBoard(GAMESTATE:GetCurrentSteps(PLAYER_1):GetChartKey(), currentCountry) ind = 0 self:playcommand("Update") end, + BortCommand = function(self) + scoretable = {} + ind = 0 + self:playcommand("Update") + end, UpdateCommand = function(self) if ind == #scoretable then ind = ind - numscores From ebe761a13718f39070750a3a9ecfa03c666843b0 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 00:01:47 -0500 Subject: [PATCH 25/43] what on earth was i doing --- .../ScreenSelectMusic decorations/msd.lua | 54 +++---------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/msd.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/msd.lua index d12f986ec3..af608f95af 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/msd.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/msd.lua @@ -53,7 +53,6 @@ local t = end end - MESSAGEMAN:Broadcast("UpdateMSDInfo") if song and steps then cd:visible(true) else @@ -69,7 +68,7 @@ local t = CurrentRateChangedMessageCommand = function(self) self:queuecommand("Set") end, - RefreshChartInfoMessageCommand = function(self) + CurrentStepsP1ChangedMessageCommand = function(self) self:queuecommand("Set") end, TabChangedMessageCommand = function(self) @@ -94,9 +93,6 @@ local function littlebits(i) InitCommand = function(self) self:xy(frameX + offsetX, frameY + 120 + 22 * i):halign(0):valign(0):zoom(0.5):maxwidth(160 / 0.6) end, - BeginCommand = function(self) - self:queuecommand("Set") - end, SetCommand = function(self) --skillset name if song and steps then @@ -114,9 +110,6 @@ local function littlebits(i) if steps and steps:GetTimingData():HasWarps() then self:settext("") end - end, - UpdateMSDInfoCommand = function(self) - self:queuecommand("Set") end }, LoadFont("Common Large") .. @@ -124,9 +117,6 @@ local function littlebits(i) InitCommand = function(self) self:xy(frameX + 225, frameY + 120 + 22 * i):halign(1):valign(0):zoom(0.5):maxwidth(110 / 0.6) end, - BeginCommand = function(self) - self:queuecommand("Set") - end, SetCommand = function(self) if song and steps then self:settextf("%05.2f", meter[i + 1]) @@ -138,12 +128,6 @@ local function littlebits(i) if steps and steps:GetTimingData():HasWarps() then self:settext("") end - end, - CurrentRateChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - UpdateMSDInfoCommand = function(self) - self:queuecommand("Set") end } } @@ -160,8 +144,7 @@ t[#t + 1] = end } t[#t + 1] = - LoadFont("Common Normal") .. - { + LoadFont("Common Normal") .. { InitCommand = function(self) self:xy(frameX + 5, frameY + offsetY - 9):zoom(0.6):halign(0):diffuse(getMainColor("positive")):settext( "MSD Breakdown (Wip)" @@ -169,8 +152,7 @@ t[#t + 1] = end } t[#t + 1] = - LoadFont("Common Large") .. - { + LoadFont("Common Large") .. { InitCommand = function(self) self:xy(frameX + 5, frameY + 35):zoom(0.6):halign(0):diffuse(getMainColor("positive")):maxwidth( SCREEN_CENTER_X / 0.7 @@ -182,9 +164,6 @@ t[#t + 1] = else self:settext("") end - end, - UpdateMSDInfoCommand = function(self) - self:queuecommand("Set") end } @@ -199,16 +178,12 @@ t[#t + 1] = end, SetCommand = function(self) self:settext(getCurRateDisplayString()) - end, - CurrentRateChangedCommand = function(self) - self:queuecommand("set") end } --Difficulty t[#t + 1] = - LoadFont("Common Normal") .. - { + LoadFont("Common Normal") .. { Name = "StepsAndMeter", InitCommand = function(self) self:xy(frameX + offsetX, frameY + offsetY + 50):zoom(0.5):halign(0) @@ -224,16 +199,12 @@ t[#t + 1] = self:diffuse(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(), steps:GetDifficulty()))) end end - end, - ScoreUpdateMessageCommand = function(self) - self:queuecommand("Set") end } --NPS t[#t + 1] = - LoadFont("Common Normal") .. - { + LoadFont("Common Normal") .. { Name = "NPS", InitCommand = function(self) self:xy(frameX + offsetX, frameY + 60):zoom(0.4):halign(0) @@ -251,22 +222,12 @@ t[#t + 1] = else self:settext("0.00 Average NPS") end - end, - CurrentSongChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - CurrentStepsP1ChangedMessageCommand = function(self) - self:queuecommand("Set") - end, - CurrentStepsP2ChangedMessageCommand = function(self) - self:queuecommand("Set") end } --Negative BPMs label t[#t + 1] = - LoadFont("Common Normal") .. - { + LoadFont("Common Normal") .. { InitCommand = function(self) self:xy(frameX + 45, frameY + 135):zoom(0.8):halign(0):diffuse(getMainColor("negative")):settext("Negative Bpms") end, @@ -276,9 +237,6 @@ t[#t + 1] = else self:settext("") end - end, - UpdateMSDInfoCommand = function(self) - self:queuecommand("Set") end } From 432949385ab83348fcdab5fb3df8815224c64232 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 00:05:19 -0500 Subject: [PATCH 26/43] oops --- .../BGAnimations/ScreenSelectMusic decorations/score.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua index 62d146b672..d27f1fef8f 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua @@ -172,6 +172,7 @@ local ret = updateLeaderBoardForCurrentChart() end, CurrentStepsP1ChangedMessageCommand = function(self) + self:queuecommand("Set") updateLeaderBoardForCurrentChart() end, CurrentRateChangedMessageCommand = function(self) @@ -659,9 +660,6 @@ t[#t+1] = Def.Quad { InitCommand = function(self) self:x(frameWidth):zoomto(4, 0):halign(1):valign(1):diffuse(getMainColor("highlight")):diffusealpha(0.75) end, - ScoreUpdateMessageCommand = function(self) - self:queuecommand("Set") - end, DisplayCommand = function(self) self:finishtweening() self:smooth(0.2) From c37d492557c9c30255804c131106df633c455814 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 06:09:13 -0500 Subject: [PATCH 27/43] Yeah. Framerates is BS and not a concern. That's just wasted cpu cycles --- .../ScreenSelectMusic decorations/score.lua | 9 +++++++-- Themes/Til Death/BGAnimations/_PlayerInfo.lua | 6 +++--- Themes/Til Death/BGAnimations/goaldisplay.lua | 4 +++- .../Til Death/BGAnimations/superscoreboard.lua | 16 ++++++++-------- .../Graphics/StepsDisplayListRow frame.lua | 4 +++- src/DifficultyList.cpp | 2 +- 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua index d27f1fef8f..a0da6f8255 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua @@ -73,7 +73,9 @@ end -- should maybe make some of these generic local function highlight(self) - self:queuecommand("Highlight") + if self:GetVisible() then + self:queuecommand("Highlight") + end end -- note: will use the local isover functionality @@ -117,11 +119,14 @@ local ret = end, OffCommand = function(self) self:bouncebegin(0.2):xy(-500, 0):diffusealpha(0) -- visible(false) + self:GetChild("LocalScores"):visible(false) end, OnCommand = function(self) self:bouncebegin(0.2):xy(0, 0):diffusealpha(1) - if nestedTab == 1 then + if getTabIndex() == 2 and nestedTab == 1 then self:GetChild("LocalScores"):visible(true) + else + self:GetChild("LocalScores"):visible(false) end end, SetCommand = function(self) diff --git a/Themes/Til Death/BGAnimations/_PlayerInfo.lua b/Themes/Til Death/BGAnimations/_PlayerInfo.lua index bf4ca7a54c..e7361a3e25 100644 --- a/Themes/Til Death/BGAnimations/_PlayerInfo.lua +++ b/Themes/Til Death/BGAnimations/_PlayerInfo.lua @@ -22,7 +22,7 @@ local setnewdisplayname = function(answer) end local function highlight(self) - self:queuecommand("Highlight") + self:GetChild("refreshbutton"):queuecommand("Highlight") end local function highlightIfOver(self) @@ -242,8 +242,8 @@ t[#t + 1] = self:settext(GAMESTATE:GetEtternaVersion()) end }, - LoadFont("Common Normal") .. - { + LoadFont("Common Normal") .. { + Name = "refreshbutton", InitCommand = function(self) self:xy(SCREEN_WIDTH - 5, AvatarY + 20):halign(1):zoom(0.35):diffuse(getMainColor("positive")) diff --git a/Themes/Til Death/BGAnimations/goaldisplay.lua b/Themes/Til Death/BGAnimations/goaldisplay.lua index 3845294580..4c79d145f2 100644 --- a/Themes/Til Death/BGAnimations/goaldisplay.lua +++ b/Themes/Til Death/BGAnimations/goaldisplay.lua @@ -40,7 +40,9 @@ local function input(event) end local function highlight(self) - self:queuecommand("Highlight") + if cheese:GetVisible() then + self:queuecommand("Highlight") + end end local function highlightIfOver(self) diff --git a/Themes/Til Death/BGAnimations/superscoreboard.lua b/Themes/Til Death/BGAnimations/superscoreboard.lua index 204715b3de..bced658842 100644 --- a/Themes/Til Death/BGAnimations/superscoreboard.lua +++ b/Themes/Til Death/BGAnimations/superscoreboard.lua @@ -70,8 +70,10 @@ local function isOver(element) end local function highlight(self) - self:queuecommand("Highlight") - self:queuecommand("WHAZZZAAAA") + if self:GetVisible() then + self:queuecommand("Highlight") + self:queuecommand("WHAZZZAAAA") + end end local function highlightIfOver(self) @@ -405,9 +407,8 @@ local function makeScoreDisplay(i) self:addy(-row2yoff) end }, - LoadFont("Common normal") .. - { - --name + LoadFont("Common normal") .. { + Name = "Burt"..i, InitCommand = function(self) self:x(c2x):zoom(tzoom + 0.1):maxwidth((c3x - c2x - capWideScale(10, 40)) / tzoom):halign(0):valign(1) if collapsed then @@ -432,9 +433,8 @@ local function makeScoreDisplay(i) end end }, - LoadFont("Common normal") .. - { - --judgments + LoadFont("Common normal") .. { + Name = "Ernie"..i, InitCommand = function(self) if not collapsed then self:x(c2x):zoom(tzoom - 0.05):halign(0):valign(0):maxwidth(width / 2 / tzoom):addy(row2yoff) diff --git a/Themes/Til Death/Graphics/StepsDisplayListRow frame.lua b/Themes/Til Death/Graphics/StepsDisplayListRow frame.lua index cab6301060..571d2b348f 100644 --- a/Themes/Til Death/Graphics/StepsDisplayListRow frame.lua +++ b/Themes/Til Death/Graphics/StepsDisplayListRow frame.lua @@ -1,5 +1,7 @@ local function highlight(self) - self:queuecommand("Highlight") + if self:GetParent():GetVisible() then + self:queuecommand("Highlight") + end end local function highlightIfOver(self) diff --git a/src/DifficultyList.cpp b/src/DifficultyList.cpp index 8491ee2c43..5d6dd05d83 100644 --- a/src/DifficultyList.cpp +++ b/src/DifficultyList.cpp @@ -13,7 +13,7 @@ /** @brief Specifies the max number of charts available for a song. * * This includes autogenned charts. */ -#define MAX_METERS ((NUM_Difficulty * NUM_StepsType) + MAX_EDITS_PER_SONG) +#define MAX_METERS 12 // kinda restrictive but im also as lazy as sm5 devs -mina REGISTER_ACTOR_CLASS(StepsDisplayList); From 0bcf406553347843b455e14d6db16f0c5b40e44d Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 06:39:06 -0500 Subject: [PATCH 28/43] gate another update function --- .../BGAnimations/ScreenSystemLayer overlay/default.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua b/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua index e64e8b44ce..64ad2112cb 100644 --- a/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua +++ b/Themes/Til Death/BGAnimations/ScreenSystemLayer overlay/default.lua @@ -49,7 +49,9 @@ local hhh = SCREEN_HEIGHT * 0.8 local rtzoom = 0.6 local function dooting(self) - self:GetChild("BGQframe"):queuecommand("dooting") + if self:GetVisible() then + self:GetChild("BGQframe"):queuecommand("dooting") + end end local dltzoom = 0.5 From d793ad6356f093c1404cc4727a690b22ebe4dca3 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 08:26:21 -0500 Subject: [PATCH 29/43] dont update notefield if it isnt visible and update wifetwirl logic --- .../ScreenSelectMusic decorations/wifeTwirl.lua | 16 +++++++++------- src/NoteField.cpp | 2 ++ src/ScreenSelectMusic.cpp | 9 ++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index 967a9b1778..20f60e3c75 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -36,6 +36,7 @@ local t = if getTabIndex() == 0 then if heyiwasusingthat and GAMESTATE:GetCurrentSong() and noteField then -- these can prolly be wrapped better too -mina mcbootlarder:visible(true) + mcbootlarder:GetChild("NoteField"):visible(true) MESSAGEMAN:Broadcast("ChartPreviewOn") heyiwasusingthat = false end @@ -44,6 +45,7 @@ local t = else if GAMESTATE:GetCurrentSong() and noteField and mcbootlarder:GetVisible() then mcbootlarder:visible(false) + mcbootlarder:GetChild("NoteField"):visible(false) MESSAGEMAN:Broadcast("ChartPreviewOff") heyiwasusingthat = true end @@ -51,6 +53,13 @@ local t = update = false end end, + MilkyTartsCommand=function(self) -- when entering pack screenselectmusic explicitly turns visibilty on notefield off -mina + if noteField and mcbootlarder:GetVisible() then + mcbootlarder:visible(false) + MESSAGEMAN:Broadcast("ChartPreviewOff") + heyiwasusingthat = true + end + end, TabChangedMessageCommand = function(self) self:queuecommand("MintyFresh") end, @@ -623,13 +632,6 @@ t[#t + 1] = LoadFont("Common Normal") .. { self:halign(0) self:settext("Toggle Preview") end, - RefreshChartInfoMessageCommand = function(self) - if song then - self:visible(true) - else - self:visible(false) - end - end, MouseLeftClickMessageCommand = function(self) if isOver(self) and (song or noteField) then toggleNoteField() diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 212b0613f1..6c852ad1c6 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -359,6 +359,8 @@ NoteField::InitColumnRenderers() void NoteField::Update(float fDeltaTime) { + if (!this->GetVisible()) + return; if (m_bFirstUpdate) { m_pCurDisplay->m_ReceptorArrowRow.PlayCommand("On"); } diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index b993923b95..dbbce13c56 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -1453,9 +1453,12 @@ ScreenSelectMusic::AfterMusicChange() GAMESTATE->m_pCurSong.Set(pSong); if (pSong != nullptr) GAMESTATE->m_pPreferredSong = pSong; - else - GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); // set steps to null when moving out of packs - // so that currentstepsp1 gets broadcast when moving into packs -mina + else { + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); + if (m_pPreviewNoteField) + m_pPreviewNoteField->SetVisible(false); + } + GAMESTATE->SetPaused(false); // hacky can see this being problematic // if we forget about it -mina From a6d788f0e7c19c66e175a860952c1f358890efe0 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 08:32:38 -0500 Subject: [PATCH 30/43] fix more update commands --- .../ScreenNetSelectMusic decorations/dumbrate.lua | 3 --- Themes/Til Death/BGAnimations/_chartpreview.lua | 8 +++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua b/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua index 19fda8b9f0..409310d7c9 100644 --- a/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua +++ b/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua @@ -84,9 +84,6 @@ local t = CurrentRateChangedMessageCommand = function(self) self:queuecommand("Set") end, - RefreshChartInfoMessageCommand = function(self) - self:queuecommand("Set") - end, TabChangedMessageCommand = function(self) self:queuecommand("Set") end, diff --git a/Themes/Til Death/BGAnimations/_chartpreview.lua b/Themes/Til Death/BGAnimations/_chartpreview.lua index a827d576c4..84db559800 100644 --- a/Themes/Til Death/BGAnimations/_chartpreview.lua +++ b/Themes/Til Death/BGAnimations/_chartpreview.lua @@ -40,6 +40,9 @@ local t = Def.ActorFrame { end, CurrentSongChangedMessageCommand=function(self) self:GetChild("pausetext"):settext("") + if GAMESTATE:GetCurrentSong() then + musicratio = GAMESTATE:GetCurrentSong():GetLastSecond() / wodth + end end, MouseRightClickMessageCommand=function(self) SCREENMAN:GetTopScreen():PausePreviewNoteField() @@ -56,11 +59,6 @@ local t = Def.ActorFrame { hELPidontDNOKNOWMessageCommand=function(self) SCREENMAN:GetTopScreen():DeletePreviewNoteField(self) end, - RefreshChartInfoMessageCommand = function(self) - if GAMESTATE:GetCurrentSong() then - musicratio = GAMESTATE:GetCurrentSong():GetLastSecond() / wodth - end - end, NoteFieldVisibleMessageCommand = function(self) self:visible(true) cd:visible(true):y(20) -- need to control this manually -mina From 92e53596f189ae7988b90d97368917a6148a409e Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 09:13:31 -0500 Subject: [PATCH 31/43] dont update banners while fast moving --- .../ScreenSelectMusic decorations/wifeTwirl.lua | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index 20f60e3c75..aca1cbbd66 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -485,13 +485,24 @@ t[#t + 1] = ) end, MortyFartsCommand = function(self) + if not INPUTFILTER:IsBeingPressed("tab") then -- dont update when fast moving + if song then + self:LoadFromSong(song) + else + local group = SCREENMAN:GetTopScreen():GetMusicWheel():GetSelectedSection() + self:LoadFromSongGroup(group) + end + self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)) + end + end, + PlayingSampleMusicMessageCommand=function(self) if song then self:LoadFromSong(song) else local group = SCREENMAN:GetTopScreen():GetMusicWheel():GetSelectedSection() self:LoadFromSongGroup(group) end - self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)) + self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)) end, MilkyTartsCommand=function(self) self:queuecommand("MortyFarts") -- for pack banners From 0bdd05fb7570b066bcc392e1b7acd61c9855e3e4 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 09:13:42 -0500 Subject: [PATCH 32/43] do the garbew --- Themes/Til Death/BGAnimations/_songbg.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Themes/Til Death/BGAnimations/_songbg.lua b/Themes/Til Death/BGAnimations/_songbg.lua index a0100a62e4..300ea392d0 100644 --- a/Themes/Til Death/BGAnimations/_songbg.lua +++ b/Themes/Til Death/BGAnimations/_songbg.lua @@ -19,6 +19,7 @@ if enabled then end, ModifySongBackgroundCommand = function(self) self:finishtweening() + collectgarbage() if GAMESTATE:GetCurrentSong() and GAMESTATE:GetCurrentSong():GetBackgroundPath() then self:finishtweening() self:visible(true) From 92fb0e170da00820172034e4834e8f6556a946cd Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 16:14:17 -0500 Subject: [PATCH 33/43] dont need this actorframe wrapper --- Themes/Til Death/BGAnimations/_songbg.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/Themes/Til Death/BGAnimations/_songbg.lua b/Themes/Til Death/BGAnimations/_songbg.lua index 300ea392d0..eaf12db8d2 100644 --- a/Themes/Til Death/BGAnimations/_songbg.lua +++ b/Themes/Til Death/BGAnimations/_songbg.lua @@ -9,7 +9,6 @@ local t = Def.ActorFrame {} if enabled then t[#t + 1] = - Def.ActorFrame { Def.Sprite { CurrentSongChangedMessageCommand = function(self) self:finishtweening():smooth(0.5):diffusealpha(0):sleep(0.2):queuecommand("ModifySongBackground") @@ -45,7 +44,6 @@ if enabled then self:visible(false) end } - } end t[#t + 1] = From a189b74db87c1f6446b5904d5295856220189a90 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Thu, 22 Nov 2018 16:19:48 -0500 Subject: [PATCH 34/43] improve banner update logic a bit (fixes banner text leak maybe?) --- .../wifeTwirl.lua | 58 ++++++++----------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index aca1cbbd66..6391f64bc3 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -476,43 +476,35 @@ t[#t + 1] = end } -t[#t + 1] = - Def.Banner { - InitCommand = function(self) - self:x(10):y(61):halign(0):valign(0):scaletoclipped( - capWideScale(get43size(384), 384), - capWideScale(get43size(120), 120) - ) - end, - MortyFartsCommand = function(self) - if not INPUTFILTER:IsBeingPressed("tab") then -- dont update when fast moving - if song then - self:LoadFromSong(song) +t[#t + 1] = + Def.Sprite { + Name = "Banner", + InitCommand = function(self) + self:x(10):y(61):halign(0):valign(0) + end, + MintyFreshCommand=function(self) + if INPUTFILTER:IsBeingPressed("tab") then + self:finishtweening():smooth(0.25):diffusealpha(0):sleep(0.2):queuecommand("ModifyBanner") else + self:finishtweening():queuecommand("ModifyBanner") + end + end, + ModifyBannerCommand = function(self) + self:finishtweening() + if song then + self:LoadBackground(GAMESTATE:GetCurrentSong():GetBannerPath()) + else local group = SCREENMAN:GetTopScreen():GetMusicWheel():GetSelectedSection() - self:LoadFromSongGroup(group) + self:LoadBackground(SONGMAN:GetSongGroupBannerPath(group)) end - self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)) - end - end, - PlayingSampleMusicMessageCommand=function(self) - if song then - self:LoadFromSong(song) - else - local group = SCREENMAN:GetTopScreen():GetMusicWheel():GetSelectedSection() - self:LoadFromSongGroup(group) + self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)):diffusealpha(1) + end, + ChartPreviewOnMessageCommand = function(self) + self:visible(false) + end, + ChartPreviewOffMessageCommand = function(self) + self:visible(true) end - self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)) - end, - MilkyTartsCommand=function(self) - self:queuecommand("MortyFarts") -- for pack banners - end, - ChartPreviewOnMessageCommand = function(self) - self:visible(false) - end, - ChartPreviewOffMessageCommand = function(self) - self:visible(true) - end } t[#t + 1] = From 4ac9453051d4953b707e6ff464ac4e8a9bd21ef4 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 03:42:02 -0500 Subject: [PATCH 35/43] use fallback banners when none is available --- .../ScreenSelectMusic decorations/wifeTwirl.lua | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index 6391f64bc3..374c970a19 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -492,10 +492,17 @@ t[#t + 1] = ModifyBannerCommand = function(self) self:finishtweening() if song then - self:LoadBackground(GAMESTATE:GetCurrentSong():GetBannerPath()) - else - local group = SCREENMAN:GetTopScreen():GetMusicWheel():GetSelectedSection() - self:LoadBackground(SONGMAN:GetSongGroupBannerPath(group)) + local bnpath = GAMESTATE:GetCurrentSong():GetBannerPath() + if not bnpath then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) + else + local bnpath = SONGMAN:GetSongGroupBannerPath(SCREENMAN:GetTopScreen():GetMusicWheel():GetSelectedSection()) + if not bnpath or bnpath == "" then + bnpath = THEME:GetPathG("Common", "fallback banner") + end + self:LoadBackground(bnpath) end self:scaletoclipped(capWideScale(get43size(384), 384), capWideScale(get43size(120), 120)):diffusealpha(1) end, From 731289cc5e01f1c18f7f6d5760fa9822b9a0b23b Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 03:42:54 -0500 Subject: [PATCH 36/43] remove "two part selection" from music select --- src/ScreenSelectMusic.cpp | 139 ++++++-------------------------------- src/ScreenSelectMusic.h | 12 +--- 2 files changed, 23 insertions(+), 128 deletions(-) diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index dbbce13c56..7b843fde2e 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -113,9 +113,6 @@ ScreenSelectMusic::Init() SELECT_MENU_NAME.Load(m_sName, "SelectMenuScreenName"); OPTIONS_LIST_TIMEOUT.Load(m_sName, "OptionsListTimeout"); SELECT_MENU_CHANGES_DIFFICULTY.Load(m_sName, "SelectMenuChangesDifficulty"); - TWO_PART_SELECTION.Load(m_sName, "TwoPartSelection"); - TWO_PART_CONFIRMS_ONLY.Load(m_sName, "TwoPartConfirmsOnly"); - TWO_PART_TIMER_SECONDS.Load(m_sName, "TwoPartTimerSeconds"); WRAP_CHANGE_STEPS.Load(m_sName, "WrapChangeSteps"); NULL_SCORE_STRING.Load(m_sName, "NullScoreString"); PLAY_SOUND_ON_ENTERING_OPTIONS_MENU.Load(m_sName, @@ -808,75 +805,30 @@ ScreenSelectMusic::Input(const InputEventPlus& input) } } - // two part confirms only means we can actually change songs here, - // so we need some hackery. -aj - if (TWO_PART_CONFIRMS_ONLY) { - if (m_SelectionState == SelectionState_SelectingSteps) { + if (m_SelectionState == SelectionState_SelectingSteps && + input.type == IET_FIRST_PRESS && !m_bStepsChosen[input.pn]) { + if (input.MenuI == m_GameButtonNextSong || + input.MenuI == m_GameButtonPreviousSong) { if (input.MenuI == m_GameButtonPreviousSong) { - m_SelectionState = SelectionState_SelectingSong; - MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); - MESSAGEMAN->Broadcast("PreviousSong"); - m_MusicWheel.ChangeMusicUnlessLocked(-1); - } else if (input.MenuI == m_GameButtonNextSong) { - m_SelectionState = SelectionState_SelectingSong; - MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); - MESSAGEMAN->Broadcast("NextSong"); - m_MusicWheel.ChangeMusicUnlessLocked(+1); - } - // added an entry for difficulty change with gamebuttons - // -DaisuMaster - else if (input.MenuI == m_GameButtonPreviousDifficulty) { - m_SelectionState = SelectionState_SelectingSong; - MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); ChangeSteps(input.pn, -1); - } else if (input.MenuI == m_GameButtonNextDifficulty) { - m_SelectionState = SelectionState_SelectingSong; - MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); + } else if (input.MenuI == m_GameButtonNextSong) { ChangeSteps(input.pn, +1); } - // added also for groupchanges - else if (input.MenuI == m_GameButtonPreviousGroup) { - RString sNewGroup = m_MusicWheel.JumpToPrevGroup(); - m_MusicWheel.SelectSection(sNewGroup); - m_MusicWheel.SetOpenSection(sNewGroup); - MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); - MESSAGEMAN->Broadcast("PreviousGroup"); - AfterMusicChange(); - } else if (input.MenuI == m_GameButtonNextGroup) { - RString sNewGroup = m_MusicWheel.JumpToNextGroup(); - m_MusicWheel.SelectSection(sNewGroup); - m_MusicWheel.SetOpenSection(sNewGroup); - MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); - MESSAGEMAN->Broadcast("NextGroup"); - AfterMusicChange(); - } - } - } else { - if (m_SelectionState == SelectionState_SelectingSteps && - input.type == IET_FIRST_PRESS && !m_bStepsChosen[input.pn]) { - if (input.MenuI == m_GameButtonNextSong || - input.MenuI == m_GameButtonPreviousSong) { - if (input.MenuI == m_GameButtonPreviousSong) { - ChangeSteps(input.pn, -1); - } else if (input.MenuI == m_GameButtonNextSong) { - ChangeSteps(input.pn, +1); - } - } else if ( - input.MenuI == GAME_BUTTON_MENUUP || - input.MenuI == - GAME_BUTTON_MENUDOWN) // && TWO_PART_DESELECTS_WITH_MENUUPDOWN - { - // XXX: should this be called "TwoPartCancelled"? - float fSeconds = m_MenuTimer->GetSeconds(); - if (fSeconds > 10) { - Message msg("SongUnchosen"); - msg.SetParam("Player", input.pn); - MESSAGEMAN->Broadcast(msg); - // unset all steps - FOREACH_ENUM(PlayerNumber, p) - m_bStepsChosen[p] = false; - m_SelectionState = SelectionState_SelectingSong; - } + } else if (input.MenuI == GAME_BUTTON_MENUUP || + input.MenuI == + GAME_BUTTON_MENUDOWN) // && + // TWO_PART_DESELECTS_WITH_MENUUPDOWN + { + // XXX: should this be called "TwoPartCancelled"? + float fSeconds = m_MenuTimer->GetSeconds(); + if (fSeconds > 10) { + Message msg("SongUnchosen"); + msg.SetParam("Player", input.pn); + MESSAGEMAN->Broadcast(msg); + // unset all steps + FOREACH_ENUM(PlayerNumber, p) + m_bStepsChosen[p] = false; + m_SelectionState = SelectionState_SelectingSong; } } } @@ -1161,8 +1113,7 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) // a song was selected if (m_MusicWheel.GetSelectedSong() != nullptr) { - if (TWO_PART_CONFIRMS_ONLY && - SAMPLE_MUSIC_PREVIEW_MODE == + if (SAMPLE_MUSIC_PREVIEW_MODE == SampleMusicPreviewMode_StartToPreview) { // start playing the preview music. g_bSampleMusicWaiting = true; @@ -1224,8 +1175,6 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) bool bAllPlayersDoneSelectingSteps = bInitiatedByMenuTimer || bAllOtherHumanPlayersDone; - if (TWO_PART_CONFIRMS_ONLY) - bAllPlayersDoneSelectingSteps = true; if (!bAllPlayersDoneSelectingSteps) { m_bStepsChosen[pn] = true; @@ -1242,8 +1191,7 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) FOREACH_ENUM(PlayerNumber, p) { - if (!TWO_PART_SELECTION || - m_SelectionState == SelectionState_SelectingSteps) { + if (m_SelectionState == SelectionState_SelectingSteps) { if (m_OptionsList[p].IsOpened()) m_OptionsList[p].Close(); } @@ -1256,14 +1204,6 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) m_soundStart.Play(true); - // If the MenuTimer has forced us to move on && TWO_PART_CONFIRMS_ONLY, - // set Selection State to finalized and move on. - if (TWO_PART_CONFIRMS_ONLY) { - if (m_MenuTimer->GetSeconds() < 1) { - m_SelectionState = SelectionState_Finalized; - } - } - if (m_SelectionState == SelectionState_Finalized) { #if !defined(WITHOUT_NETWORKING) DLMAN->UpdateDLSpeed(true); @@ -1319,13 +1259,6 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) } else { StartTransitioningScreen(SM_BeginFadingOut); } - } else // !finalized. Set the timer for selecting difficulty and mods. - { - float fSeconds = m_MenuTimer->GetSeconds(); - if (fSeconds < 10) { - m_MenuTimer->SetSeconds(TWO_PART_TIMER_SECONDS); // was 13 -aj - m_MenuTimer->Start(); - } } return false; } @@ -1333,28 +1266,7 @@ ScreenSelectMusic::SelectCurrent(PlayerNumber pn) bool ScreenSelectMusic::MenuBack(const InputEventPlus& /* input */) { - // Handle unselect song (ffff) - // todo: this isn't right at all. -aj - /* - if( m_SelectionState == SelectionState_SelectingSteps && - !m_bStepsChosen[input.pn] && input.MenuI == GAME_BUTTON_BACK && - input.type == IET_FIRST_PRESS ) - { - // if a player has chosen their steps already, don't unchoose song. - FOREACH_HumanPlayer( p ) - if( m_bStepsChosen[p] ) return; - - // and if we get here... - Message msg("SongUnchosen"); - msg.SetParam( "Player", input.pn ); - MESSAGEMAN->Broadcast( msg ); - m_SelectionState = SelectionState_SelectingSong; - return true; - } - */ - m_BackgroundLoader.Abort(); - Cancel(SM_GoToPrevScreen); return true; } @@ -1362,13 +1274,6 @@ ScreenSelectMusic::MenuBack(const InputEventPlus& /* input */) void ScreenSelectMusic::AfterStepsOrTrailChange(const vector& vpns) { - if (TWO_PART_CONFIRMS_ONLY && - m_SelectionState == SelectionState_SelectingSteps) { - // if TWO_PART_CONFIRMS_ONLY, changing difficulties unsets the song. -aj - m_SelectionState = SelectionState_SelectingSong; - MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); - } - PlayerNumber pn = PLAYER_1; ASSERT(GAMESTATE->IsHumanPlayer(pn)); diff --git a/src/ScreenSelectMusic.h b/src/ScreenSelectMusic.h index 57eef809c7..52e1baa1b1 100644 --- a/src/ScreenSelectMusic.h +++ b/src/ScreenSelectMusic.h @@ -119,9 +119,6 @@ class ScreenSelectMusic : public ScreenWithMenuElements ThemeMetric USE_PLAYER_SELECT_MENU; ThemeMetric SELECT_MENU_NAME; ThemeMetric SELECT_MENU_CHANGES_DIFFICULTY; - ThemeMetric TWO_PART_SELECTION; - ThemeMetric TWO_PART_CONFIRMS_ONLY; - ThemeMetric TWO_PART_TIMER_SECONDS; ThemeMetric WRAP_CHANGE_STEPS; ThemeMetric CHANGE_STEPS_WITH_GAME_BUTTONS; ThemeMetric CHANGE_GROUPS_WITH_GAME_BUTTONS; @@ -132,18 +129,11 @@ class ScreenSelectMusic : public ScreenWithMenuElements { return m_SelectionState == SelectionState_SelectingSong; } - bool CanChangeSteps() const - { - return TWO_PART_SELECTION - ? m_SelectionState == SelectionState_SelectingSteps - : m_SelectionState == SelectionState_SelectingSong; - } SelectionState GetNextSelectionState() const { switch (m_SelectionState) { case SelectionState_SelectingSong: - return TWO_PART_SELECTION ? SelectionState_SelectingSteps - : SelectionState_Finalized; + return SelectionState_Finalized; default: return SelectionState_Finalized; } From 2a02341f5704f6740f99635cd4b35bf2d0d1a278 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 15:36:42 -0500 Subject: [PATCH 37/43] iterate version tags to 0.63.0 --- CMake/SMDefs.cmake | 4 ++-- src/GameState.h | 2 +- src/ProductInfo.inc | 2 +- stepmania.nsi | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMake/SMDefs.cmake b/CMake/SMDefs.cmake index bac18cdd9f..edae1df02f 100644 --- a/CMake/SMDefs.cmake +++ b/CMake/SMDefs.cmake @@ -1,7 +1,7 @@ # Set up version numbers according to the new scheme. set(SM_VERSION_MAJOR 0) -set(SM_VERSION_MINOR 62) -set(SM_VERSION_PATCH 1) +set(SM_VERSION_MINOR 63) +set(SM_VERSION_PATCH 0) set(SM_VERSION_TRADITIONAL "${SM_VERSION_MAJOR}.${SM_VERSION_MINOR}.${SM_VERSION_PATCH}") execute_process(COMMAND git rev-parse --short HEAD diff --git a/src/GameState.h b/src/GameState.h index 5a1bd55d31..11a1f83d85 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -224,7 +224,7 @@ class GameState bool m_bLoadingNextSong; int GetLoadingCourseSongIndex() const; - RString GetEtternaVersion() { return "0.62.1"; } + RString GetEtternaVersion() { return "0.63.0"; } bool isplaylistcourse = false; bool IsPlaylistCourse() { return isplaylistcourse; } bool CountNotesSeparately(); diff --git a/src/ProductInfo.inc b/src/ProductInfo.inc index dc58167261..c1fa493054 100644 --- a/src/ProductInfo.inc +++ b/src/ProductInfo.inc @@ -6,7 +6,7 @@ !define PRODUCT_ID "Etterna" ; TODO: This needs to be updated with the git rev hash -!define PRODUCT_VER "v0.62.1" +!define PRODUCT_VER "v0.63.0" !define PRODUCT_DISPLAY "${PRODUCT_FAMILY} ${PRODUCT_VER}" !define PRODUCT_BITMAP "ett" diff --git a/stepmania.nsi b/stepmania.nsi index 2cc46af75b..a29cd3aef6 100644 --- a/stepmania.nsi +++ b/stepmania.nsi @@ -43,7 +43,7 @@ ; don't forget to change this before releasing a new version. ; wish this could be automated, but it requires "X.Y.Z.a" format. -aj - VIProductVersion "0.62.1.0" + VIProductVersion "0.63.0.0" VIAddVersionKey "ProductName" "${PRODUCT_ID}" VIAddVersionKey "FileVersion" "${PRODUCT_VER}" VIAddVersionKey "FileDescription" "${PRODUCT_ID} Installer" From 296f30a9153d1fcd62346ac4983fd3d464e21482 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 15:44:16 -0500 Subject: [PATCH 38/43] 0.63 loading splash --- Data/splash.png | Bin 9261 -> 9846 bytes Themes/_fallback/Graphics/Common splash.png | Bin 9261 -> 9846 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Data/splash.png b/Data/splash.png index ced5e95e5d17dfec6503580f578712b1236d95e1..768517017e8fc47baa241e1723afee751ddd8b45 100644 GIT binary patch literal 9846 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 diff --git a/Themes/_fallback/Graphics/Common splash.png b/Themes/_fallback/Graphics/Common splash.png index ced5e95e5d17dfec6503580f578712b1236d95e1..768517017e8fc47baa241e1723afee751ddd8b45 100644 GIT binary patch literal 9846 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 From 1dab3619c56a5a925738562483d2d8873951bdeb Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 16:20:36 -0500 Subject: [PATCH 39/43] add main skillset to score display for scores --- .../ScreenSelectMusic decorations/score.lua | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua index 5055b3ca31..1c90574735 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/score.lua @@ -334,7 +334,7 @@ local l = Def.ActorFrame{ -- stuff inside the frame.. so we can move it all at o { Name = "Score", InitCommand = function(self) - self:xy(55, 33):zoom(0.6):halign(0):settext("") + self:xy(55, 30):zoom(0.6):halign(0):settext("") end, DisplayCommand = function(self) if score:GetWifeScore() == 0 then @@ -346,11 +346,26 @@ local l = Def.ActorFrame{ -- stuff inside the frame.. so we can move it all at o end }, + LoadFont("Common Normal") .. + { + Name = "Score", + InitCommand = function(self) + self:xy(55, 43):zoom(0.5):halign(0):settext("") + end, + DisplayCommand = function(self) + if score:GetWifeScore() == 0 then + self:settext("") + else + self:settext(GAMESTATE:GetCurrentSteps(PLAYER_1):GetRelevantSkillsetsByMSDRank(getCurRateValue(), 1)) + end + end + }, + LoadFont("Common Normal") .. { Name = "ClearType", InitCommand = function(self) - self:y(41):zoom(0.5):halign(0):halign(0):settext("No Play"):diffuse( + self:y(43):zoom(0.5):halign(0):settext("No Play"):diffuse( color(colorConfig:get_data().clearType["NoPlay"]) ) end, From 1f54adf992441c8023d8ff0cea1c0012485caab9 Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 16:27:37 -0500 Subject: [PATCH 40/43] fix 4:3 notefield placement in preview this should be redone so dumb manual adjustments aren't necessary --- .../BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index ea4d72b89d..b4b94d0bf8 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -11,7 +11,7 @@ local noteField = false local heyiwasusingthat = false local mcbootlarder local prevX = capWideScale(get43size(98), 98) -local idkwhatimdoing = capWideScale(prevX+8, prevX/2+4) +local idkwhatimdoing = capWideScale(prevX-2, prevX/2+4) local usingreverse = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingReverse() local prevY = 55 local prevrevY = 208 From d4eda50e337490de69b8687c03d2200dc874389e Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 17:36:21 -0500 Subject: [PATCH 41/43] dont bother parsing or storing online replaydata in generic calls --- src/DownloadManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/DownloadManager.cpp b/src/DownloadManager.cpp index 7b374c6c5a..c570009d5f 100644 --- a/src/DownloadManager.cpp +++ b/src/DownloadManager.cpp @@ -1451,7 +1451,8 @@ DownloadManager::RequestChartLeaderBoard(string chartkey) FOREACH_ENUM(Skillset, ss) tmp.SSRs[ss] = static_cast( ssrs.value(SkillsetToString(ss).c_str(), 0.0)); - try { + + /*try { auto replay = score["replay"]; if (replay.size() > 1) LOG->Trace(tmp.modifiers.c_str()); @@ -1460,7 +1461,7 @@ DownloadManager::RequestChartLeaderBoard(string chartkey) pair[0].get(), pair[1].get())); } catch (exception e) { // replaydata failed - } + } */ // eo still has some old profiles with various edge issues that // unfortunately need to be handled here screen out old 11111 From fc3c4e79e5020d004d3a8ae29ee458b161d328eb Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 18:29:00 -0500 Subject: [PATCH 42/43] clear cached dlman leaderboards after finishing gameplay --- src/ScreenProfileSave.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ScreenProfileSave.cpp b/src/ScreenProfileSave.cpp index aa2e8f5912..b485526dd5 100644 --- a/src/ScreenProfileSave.cpp +++ b/src/ScreenProfileSave.cpp @@ -2,6 +2,7 @@ #include "GameState.h" #include "ScreenManager.h" #include "ScreenProfileSave.h" +#include "DownloadManager.h" REGISTER_SCREEN_CLASS(ScreenProfileSave); @@ -20,6 +21,7 @@ ScreenProfileSave::Input(const InputEventPlus& input) void ScreenProfileSave::Continue() { + DLMAN->chartLeaderboards.clear(); // clear cached leaderboard scores when saving after gameplay -mina GAMESTATE->SavePlayerProfiles(); SCREENMAN->ZeroNextUpdate(); From cfc8edc28b0e4cd9b8ec70410c5ecf02c791ca9e Mon Sep 17 00:00:00 2001 From: "born a rick, raised a morty, died a jerry" Date: Fri, 23 Nov 2018 19:16:45 -0500 Subject: [PATCH 43/43] go back to using some hires fonts in select music --- .../wifeTwirl.lua | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua index 929787beb4..b6b6168a3f 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic decorations/wifeTwirl.lua @@ -9,7 +9,7 @@ local noteField = false local heyiwasusingthat = false local mcbootlarder local prevX = capWideScale(get43size(98), 98) -local idkwhatimdoing = capWideScale(prevX-2, prevX/2+4) +local idkwhatimdoing = capWideScale(prevX+8, prevX/2+4) local usingreverse = GAMESTATE:GetPlayerState(PLAYER_1):GetCurrentPlayerOptions():UsingReverse() local prevY = 55 local prevrevY = 208 @@ -84,9 +84,9 @@ local t = -- Music Rate Display t[#t + 1] = - LoadFont("Common Normal") .. { + LoadFont("Common Large") .. { InitCommand = function(self) - self:xy(18, SCREEN_BOTTOM - 225):visible(true):halign(0):zoom(0.8):maxwidth( + self:xy(18, SCREEN_BOTTOM - 225):visible(true):halign(0):zoom(0.4):maxwidth( capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45)) end, MintyFreshCommand = function(self) @@ -151,10 +151,10 @@ t[#t + 1] = Def.ActorFrame { self:queuecommand("MintyFresh") --steps stuff self:queuecommand("MortyFarts") --songs stuff end, - LoadFont("Common Normal") .. { + LoadFont("Common Large") .. { Name = "MSD", InitCommand = function(self) - self:xy(frameX + 58, frameY - 62):halign(0.5):maxwidth(110 / 0.6) + self:xy(frameX + 58, frameY - 62):halign(0.5):zoom(0.6):maxwidth(110 / 0.6) end, MintyFreshCommand = function(self) if song then @@ -228,9 +228,9 @@ t[#t + 1] = Def.ActorFrame { }, -- **score related stuff** These need to be updated with rate changed commands -- Primary percent score - LoadFont("Common Normal") .. { + LoadFont("Common Large") .. { InitCommand = function(self) - self:xy(frameX + 55, frameY + 50):zoom(0.8):halign(0.5):maxwidth(125):valign(1) + self:xy(frameX + 55, frameY + 50):zoom(0.6):halign(0.5):maxwidth(125):valign(1) end, MintyFreshCommand = function(self) if song and score then @@ -341,11 +341,11 @@ t[#t + 1] = Def.ActorFrame { end end }, - LoadFont("Common Normal") .. { + LoadFont("Common Large") .. { Name = "PlayableDuration", InitCommand = function(self) self:xy((capWideScale(get43size(384), 384)) + 62, SCREEN_BOTTOM - 85):visible(true):halign(1):zoom( - capWideScale(get43size(0.8), 0.8) + capWideScale(get43size(0.6), 0.6) ):maxwidth(capWideScale(get43size(360), 360) / capWideScale(get43size(0.45), 0.45)) end, MortyFartsCommand = function(self) @@ -657,4 +657,4 @@ t[#t + 1] = LoadFont("Common Normal") .. { } t[#t + 1] = LoadActor("../_chartpreview.lua") -return t +return t \ No newline at end of file