Only slide duplicate difficulties when loading BMS files; in other cases,
just move the duplicates to EDIT. This should fix the common glitch of users with eg. two beginner steps for a song having all difficulties bumped up; instead, just move the extra step to an edit.
This commit is contained in:
@@ -430,6 +430,8 @@ bool BMSLoader::LoadFromDir( CString sDir, Song &out )
|
||||
delete pNewNotes;
|
||||
}
|
||||
|
||||
SlideDuplicateDifficulties( out );
|
||||
|
||||
CString sPath = out.GetSongDir() + arrayBMSFileNames[0];
|
||||
|
||||
RageFile file(sPath);
|
||||
@@ -703,3 +705,33 @@ bool BMSLoader::LoadFromDir( CString sDir, Song &out )
|
||||
}
|
||||
|
||||
|
||||
void BMSLoader::SlideDuplicateDifficulties( Song &p )
|
||||
{
|
||||
/* BMS files have to guess the Difficulty from the meter; this is inaccurate,
|
||||
* and often leads to duplicates. Slide duplicate difficulties upwards. We
|
||||
* only do this with BMS files, since a very common bug was having *all*
|
||||
* difficulties slid upwards due to (for example) having two beginner steps.
|
||||
* We do a second pass in Song::TidyUpData to eliminate any remaining duplicates
|
||||
* after this. */
|
||||
for( int i=0; i<NUM_STEPS_TYPES; i++ )
|
||||
{
|
||||
StepsType st = (StepsType)i;
|
||||
|
||||
for( unsigned j=0; j<=DIFFICULTY_CHALLENGE; j++ ) // not DIFFICULTY_EDIT
|
||||
{
|
||||
Difficulty dc = (Difficulty)j;
|
||||
|
||||
vector<Steps*> vSteps;
|
||||
p.GetSteps( vSteps, st, dc );
|
||||
|
||||
SortNotesArrayByDifficulty( vSteps );
|
||||
for( unsigned k=1; k<vSteps.size(); k++ )
|
||||
{
|
||||
Steps* pSteps = vSteps[k];
|
||||
|
||||
Difficulty dc2 = min( (Difficulty)(dc+1), DIFFICULTY_CHALLENGE );
|
||||
pSteps->SetDifficulty( dc2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,16 @@
|
||||
#include "Steps.h"
|
||||
#include "NotesLoader.h"
|
||||
|
||||
class BMSLoader: public NotesLoader {
|
||||
class BMSLoader: public NotesLoader
|
||||
{
|
||||
bool LoadFromBMSFile( const CString &sPath, Steps &out1 );
|
||||
void mapBMSTrackToDanceNote( int iBMSTrack, int &iDanceColOut, char &cNoteCharOut );
|
||||
void PushTrackNumForMagic( int iTrackNum );
|
||||
StepsType CheckTracksMagic( void );
|
||||
void ResetTracksMagic( void );
|
||||
|
||||
void SlideDuplicateDifficulties( Song &p );
|
||||
|
||||
public:
|
||||
void GetApplicableFiles( CString sPath, CStringArray &out );
|
||||
bool LoadFromDir( CString sDir, Song &out );
|
||||
|
||||
+42
-29
@@ -348,6 +348,7 @@ void Song::RevertFromDisk( bool bAllowNotesLoss )
|
||||
PREFSMAN->m_bFastLoad = false;
|
||||
|
||||
LoadFromSongDir( dir );
|
||||
/* XXX: reload edits? */
|
||||
|
||||
PREFSMAN->m_bFastLoad = OldVal;
|
||||
|
||||
@@ -437,6 +438,45 @@ static void DeleteDuplicateSteps( Song *song, vector<Steps*> &vSteps )
|
||||
}
|
||||
}
|
||||
|
||||
/* Make any duplicate difficulties edits. (Note that BMS files do a first pass
|
||||
* on this; see BMSLoader::SlideDuplicateDifficulties.) */
|
||||
void Song::AdjustDuplicateSteps()
|
||||
{
|
||||
for( int i=0; i<NUM_STEPS_TYPES; i++ )
|
||||
{
|
||||
StepsType st = (StepsType)i;
|
||||
|
||||
for( unsigned j=0; j<=DIFFICULTY_CHALLENGE; j++ ) // not DIFFICULTY_EDIT
|
||||
{
|
||||
Difficulty dc = (Difficulty)j;
|
||||
|
||||
vector<Steps*> vSteps;
|
||||
this->GetSteps( vSteps, st, dc );
|
||||
|
||||
/* Delete steps that are completely identical. This happened due to a
|
||||
* bug in an earlier version. */
|
||||
DeleteDuplicateSteps( this, vSteps );
|
||||
|
||||
CHECKPOINT;
|
||||
SortNotesArrayByDifficulty( vSteps );
|
||||
CHECKPOINT;
|
||||
for( unsigned k=1; k<vSteps.size(); k++ )
|
||||
{
|
||||
vSteps[k]->SetDifficulty( DIFFICULTY_EDIT );
|
||||
if( vSteps[k]->GetDescription() == "" )
|
||||
{
|
||||
/* "Hard Edit" */
|
||||
CString EditName = Capitalize( DifficultyToString(dc) ) + " Edit";
|
||||
vSteps[k]->SetDescription( EditName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: Don't allow edits to have descriptions that look like regular difficulties.
|
||||
* These are confusing, and they're ambiguous when passed to GetStepsByID. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix up song paths. If there's a leading "./", be sure to keep it: it's
|
||||
* a signal that the path is from the root directory, not the song directory.
|
||||
* Other than a leading "./", song paths must never contain "." or "..". */
|
||||
@@ -747,35 +787,8 @@ void Song::TidyUpData()
|
||||
|
||||
|
||||
/* Don't allow multiple Steps of the same StepsType and Difficulty (except for edits).
|
||||
* This happens a lot reading BMS files because they we have to guess
|
||||
* the Difficulty from the meter. */
|
||||
for( i=0; i<NUM_STEPS_TYPES; i++ )
|
||||
{
|
||||
StepsType st = (StepsType)i;
|
||||
|
||||
for( unsigned j=0; j<=DIFFICULTY_CHALLENGE; j++ ) // not DIFFICULTY_EDIT
|
||||
{
|
||||
Difficulty dc = (Difficulty)j;
|
||||
|
||||
vector<Steps*> vSteps;
|
||||
this->GetSteps( vSteps, st, dc );
|
||||
|
||||
/* Delete steps that are completely identical. This happened due to a
|
||||
* bug in an earlier version. */
|
||||
DeleteDuplicateSteps( this, vSteps );
|
||||
|
||||
CHECKPOINT;
|
||||
SortNotesArrayByDifficulty( vSteps );
|
||||
CHECKPOINT;
|
||||
for( unsigned k=1; k<vSteps.size(); k++ )
|
||||
{
|
||||
Steps* pSteps = vSteps[k];
|
||||
|
||||
Difficulty dc2 = min( (Difficulty)(dc+1), DIFFICULTY_CHALLENGE );
|
||||
pSteps->SetDifficulty( dc2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
* We should be able to use difficulty names as unique identifiers for steps. */
|
||||
AdjustDuplicateSteps();
|
||||
|
||||
{
|
||||
/* Generated filename; this doesn't always point to a loadable file,
|
||||
|
||||
@@ -203,6 +203,10 @@ public:
|
||||
|
||||
void FreeAllLoadedFromProfiles();
|
||||
bool WasLoadedFromProfile() const { return m_LoadedFromProfile != PROFILE_SLOT_INVALID; }
|
||||
|
||||
private:
|
||||
void AdjustDuplicateSteps(); // part of TidyUpData
|
||||
CString GetUniqueSongDescription( StepsType st );
|
||||
};
|
||||
|
||||
CString MakeSortString( CString s );
|
||||
|
||||
Reference in New Issue
Block a user