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;
|
delete pNewNotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SlideDuplicateDifficulties( out );
|
||||||
|
|
||||||
CString sPath = out.GetSongDir() + arrayBMSFileNames[0];
|
CString sPath = out.GetSongDir() + arrayBMSFileNames[0];
|
||||||
|
|
||||||
RageFile file(sPath);
|
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 "Steps.h"
|
||||||
#include "NotesLoader.h"
|
#include "NotesLoader.h"
|
||||||
|
|
||||||
class BMSLoader: public NotesLoader {
|
class BMSLoader: public NotesLoader
|
||||||
|
{
|
||||||
bool LoadFromBMSFile( const CString &sPath, Steps &out1 );
|
bool LoadFromBMSFile( const CString &sPath, Steps &out1 );
|
||||||
void mapBMSTrackToDanceNote( int iBMSTrack, int &iDanceColOut, char &cNoteCharOut );
|
void mapBMSTrackToDanceNote( int iBMSTrack, int &iDanceColOut, char &cNoteCharOut );
|
||||||
void PushTrackNumForMagic( int iTrackNum );
|
void PushTrackNumForMagic( int iTrackNum );
|
||||||
StepsType CheckTracksMagic( void );
|
StepsType CheckTracksMagic( void );
|
||||||
void ResetTracksMagic( void );
|
void ResetTracksMagic( void );
|
||||||
|
|
||||||
|
void SlideDuplicateDifficulties( Song &p );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void GetApplicableFiles( CString sPath, CStringArray &out );
|
void GetApplicableFiles( CString sPath, CStringArray &out );
|
||||||
bool LoadFromDir( CString sDir, Song &out );
|
bool LoadFromDir( CString sDir, Song &out );
|
||||||
|
|||||||
+42
-29
@@ -348,6 +348,7 @@ void Song::RevertFromDisk( bool bAllowNotesLoss )
|
|||||||
PREFSMAN->m_bFastLoad = false;
|
PREFSMAN->m_bFastLoad = false;
|
||||||
|
|
||||||
LoadFromSongDir( dir );
|
LoadFromSongDir( dir );
|
||||||
|
/* XXX: reload edits? */
|
||||||
|
|
||||||
PREFSMAN->m_bFastLoad = OldVal;
|
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
|
/* 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.
|
* a signal that the path is from the root directory, not the song directory.
|
||||||
* Other than a leading "./", song paths must never contain "." or "..". */
|
* 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).
|
/* 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
|
* We should be able to use difficulty names as unique identifiers for steps. */
|
||||||
* the Difficulty from the meter. */
|
AdjustDuplicateSteps();
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Generated filename; this doesn't always point to a loadable file,
|
/* Generated filename; this doesn't always point to a loadable file,
|
||||||
|
|||||||
@@ -203,6 +203,10 @@ public:
|
|||||||
|
|
||||||
void FreeAllLoadedFromProfiles();
|
void FreeAllLoadedFromProfiles();
|
||||||
bool WasLoadedFromProfile() const { return m_LoadedFromProfile != PROFILE_SLOT_INVALID; }
|
bool WasLoadedFromProfile() const { return m_LoadedFromProfile != PROFILE_SLOT_INVALID; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AdjustDuplicateSteps(); // part of TidyUpData
|
||||||
|
CString GetUniqueSongDescription( StepsType st );
|
||||||
};
|
};
|
||||||
|
|
||||||
CString MakeSortString( CString s );
|
CString MakeSortString( CString s );
|
||||||
|
|||||||
Reference in New Issue
Block a user