more work on a new course editor
This commit is contained in:
+80
-65
@@ -23,6 +23,17 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const CString SongSortNames[] = {
|
||||||
|
"Randomize",
|
||||||
|
"MostPlays",
|
||||||
|
"FewestPlays",
|
||||||
|
"TopGrades",
|
||||||
|
"LowestGrades",
|
||||||
|
};
|
||||||
|
XToString( SongSort, NUM_SongSort );
|
||||||
|
XToThemedString( SongSort, NUM_SongSort );
|
||||||
|
|
||||||
|
|
||||||
/* Maximum lower value of ranges when difficult: */
|
/* Maximum lower value of ranges when difficult: */
|
||||||
const int MAX_BOTTOM_RANGE = 10;
|
const int MAX_BOTTOM_RANGE = 10;
|
||||||
|
|
||||||
@@ -44,7 +55,7 @@ CourseType Course::GetCourseType() const
|
|||||||
return COURSE_TYPE_ENDLESS;
|
return COURSE_TYPE_ENDLESS;
|
||||||
if( m_iLives > 0 )
|
if( m_iLives > 0 )
|
||||||
return COURSE_TYPE_ONI;
|
return COURSE_TYPE_ONI;
|
||||||
FOREACH_CONST( CourseEntry, m_entries, e )
|
FOREACH_CONST( CourseEntry, m_vEntries, e )
|
||||||
{
|
{
|
||||||
if( e->fGainSeconds > 0 )
|
if( e->fGainSeconds > 0 )
|
||||||
return COURSE_TYPE_SURVIVAL;
|
return COURSE_TYPE_SURVIVAL;
|
||||||
@@ -211,13 +222,15 @@ void Course::LoadFromCRSFile( CString sPath )
|
|||||||
// infer entry::Type from the first param
|
// infer entry::Type from the first param
|
||||||
if( sParams[1].Left(strlen("BEST")) == "BEST" )
|
if( sParams[1].Left(strlen("BEST")) == "BEST" )
|
||||||
{
|
{
|
||||||
new_entry.iMostPopularIndex = atoi( sParams[1].Right(sParams[1].size()-strlen("BEST")) ) - 1;
|
new_entry.iChooseIndex = atoi( sParams[1].Right(sParams[1].size()-strlen("BEST")) ) - 1;
|
||||||
CLAMP( new_entry.iMostPopularIndex, 0, 500 );
|
CLAMP( new_entry.iChooseIndex, 0, 500 );
|
||||||
|
new_entry.songSort = SongSort_MostPlays;
|
||||||
}
|
}
|
||||||
else if( sParams[1].Left(strlen("WORST")) == "WORST" )
|
else if( sParams[1].Left(strlen("WORST")) == "WORST" )
|
||||||
{
|
{
|
||||||
new_entry.iLeastPopularIndex = atoi( sParams[1].Right(sParams[1].size()-strlen("WORST")) ) - 1;
|
new_entry.iChooseIndex = atoi( sParams[1].Right(sParams[1].size()-strlen("WORST")) ) - 1;
|
||||||
CLAMP( new_entry.iLeastPopularIndex, 0, 500 );
|
CLAMP( new_entry.iChooseIndex, 0, 500 );
|
||||||
|
new_entry.songSort = SongSort_FewestPlays;
|
||||||
}
|
}
|
||||||
else if( sParams[1] == "*" )
|
else if( sParams[1] == "*" )
|
||||||
{
|
{
|
||||||
@@ -231,11 +244,16 @@ void Course::LoadFromCRSFile( CString sPath )
|
|||||||
CStringArray bits;
|
CStringArray bits;
|
||||||
split( sSong, "/", bits );
|
split( sSong, "/", bits );
|
||||||
if( bits.size() == 2 )
|
if( bits.size() == 2 )
|
||||||
|
{
|
||||||
new_entry.sSongGroup = bits[0];
|
new_entry.sSongGroup = bits[0];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
LOG->Warn( "Course file '%s' contains a random_within_group entry '%s' that is invalid. "
|
LOG->Warn( "Course file '%s' contains a random_within_group entry '%s' that is invalid. "
|
||||||
"Song should be in the format '<group>/*'.",
|
"Song should be in the format '<group>/*'.",
|
||||||
sPath.c_str(), sSong.c_str());
|
sPath.c_str(), sSong.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if( !SONGMAN->DoesSongGroupExist(new_entry.sSongGroup) )
|
if( !SONGMAN->DoesSongGroupExist(new_entry.sSongGroup) )
|
||||||
{
|
{
|
||||||
/* XXX: We need a place to put "user warnings". This is too loud for info.txt--
|
/* XXX: We need a place to put "user warnings". This is too loud for info.txt--
|
||||||
@@ -304,7 +322,7 @@ void Course::LoadFromCRSFile( CString sPath )
|
|||||||
new_entry.fGainSeconds = fGainSeconds;
|
new_entry.fGainSeconds = fGainSeconds;
|
||||||
attacks.clear();
|
attacks.clear();
|
||||||
|
|
||||||
m_entries.push_back( new_entry );
|
m_vEntries.push_back( new_entry );
|
||||||
}
|
}
|
||||||
else if( bUseCache && !stricmp(sValueName, "RADAR") )
|
else if( bUseCache && !stricmp(sValueName, "RADAR") )
|
||||||
{
|
{
|
||||||
@@ -331,7 +349,7 @@ void Course::LoadFromCRSFile( CString sPath )
|
|||||||
|
|
||||||
/* Cache and load the course banner. Only bother doing this if at least one
|
/* Cache and load the course banner. Only bother doing this if at least one
|
||||||
* song was found in the course. */
|
* song was found in the course. */
|
||||||
if( m_sBannerPath != "" && !m_entries.empty() )
|
if( m_sBannerPath != "" && !m_vEntries.empty() )
|
||||||
BANNERCACHE->CacheBanner( m_sBannerPath );
|
BANNERCACHE->CacheBanner( m_sBannerPath );
|
||||||
|
|
||||||
/* Cache each trail RadarValues that's slow to load, so we
|
/* Cache each trail RadarValues that's slow to load, so we
|
||||||
@@ -371,10 +389,10 @@ void Course::Init()
|
|||||||
m_bRandomize = false;
|
m_bRandomize = false;
|
||||||
m_iLives = -1;
|
m_iLives = -1;
|
||||||
m_bSortByMeter = false;
|
m_bSortByMeter = false;
|
||||||
m_entries.clear();
|
m_vEntries.clear();
|
||||||
FOREACH_Difficulty(dc)
|
FOREACH_Difficulty(dc)
|
||||||
m_iCustomMeter[dc] = -1;
|
m_iCustomMeter[dc] = -1;
|
||||||
m_entries.clear();
|
m_vEntries.clear();
|
||||||
m_sPath = "";
|
m_sPath = "";
|
||||||
m_sGroupName = "";
|
m_sGroupName = "";
|
||||||
m_sMainTitle = "";
|
m_sMainTitle = "";
|
||||||
@@ -439,9 +457,9 @@ void Course::Save( CString sPath, bool bSavingCache )
|
|||||||
f.PutLine( "// end cache tags" );
|
f.PutLine( "// end cache tags" );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned i=0; i<m_entries.size(); i++ )
|
for( unsigned i=0; i<m_vEntries.size(); i++ )
|
||||||
{
|
{
|
||||||
const CourseEntry& entry = m_entries[i];
|
const CourseEntry& entry = m_vEntries[i];
|
||||||
|
|
||||||
for( unsigned j = 0; j < entry.attacks.size(); ++j )
|
for( unsigned j = 0; j < entry.attacks.size(); ++j )
|
||||||
{
|
{
|
||||||
@@ -462,13 +480,13 @@ void Course::Save( CString sPath, bool bSavingCache )
|
|||||||
if( entry.fGainSeconds > 0 )
|
if( entry.fGainSeconds > 0 )
|
||||||
f.PutLine( ssprintf("#GAINSECONDS:%f;", entry.fGainSeconds) );
|
f.PutLine( ssprintf("#GAINSECONDS:%f;", entry.fGainSeconds) );
|
||||||
|
|
||||||
if( entry.iMostPopularIndex != -1 )
|
if( entry.songSort == SongSort_MostPlays && entry.iChooseIndex != -1 )
|
||||||
{
|
{
|
||||||
f.Write( ssprintf( "#SONG:BEST%d", entry.iMostPopularIndex+1 ) );
|
f.Write( ssprintf( "#SONG:BEST%d", entry.iChooseIndex+1 ) );
|
||||||
}
|
}
|
||||||
else if( entry.iLeastPopularIndex != -1 )
|
else if( entry.songSort == SongSort_FewestPlays && entry.iChooseIndex != -1 )
|
||||||
{
|
{
|
||||||
f.Write( ssprintf( "#SONG:WORST%d", entry.iLeastPopularIndex+1 ) );
|
f.Write( ssprintf( "#SONG:WORST%d", entry.iChooseIndex+1 ) );
|
||||||
}
|
}
|
||||||
else if( entry.pSong )
|
else if( entry.pSong )
|
||||||
{
|
{
|
||||||
@@ -550,7 +568,7 @@ void Course::AutogenEndlessFromGroup( CString sGroupName, Difficulty diff )
|
|||||||
vector<Song*> vSongs;
|
vector<Song*> vSongs;
|
||||||
SONGMAN->GetSongs( vSongs, e.sSongGroup );
|
SONGMAN->GetSongs( vSongs, e.sSongGroup );
|
||||||
for( unsigned i = 0; i < vSongs.size(); ++i)
|
for( unsigned i = 0; i < vSongs.size(); ++i)
|
||||||
m_entries.push_back( e );
|
m_vEntries.push_back( e );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Course::AutogenNonstopFromGroup( CString sGroupName, Difficulty diff )
|
void Course::AutogenNonstopFromGroup( CString sGroupName, Difficulty diff )
|
||||||
@@ -562,10 +580,10 @@ void Course::AutogenNonstopFromGroup( CString sGroupName, Difficulty diff )
|
|||||||
m_sMainTitle += " Random";
|
m_sMainTitle += " Random";
|
||||||
|
|
||||||
// resize to 4
|
// resize to 4
|
||||||
while( m_entries.size() < 4 )
|
while( m_vEntries.size() < 4 )
|
||||||
m_entries.push_back( m_entries[0] );
|
m_vEntries.push_back( m_vEntries[0] );
|
||||||
while( m_entries.size() > 4 )
|
while( m_vEntries.size() > 4 )
|
||||||
m_entries.pop_back();
|
m_vEntries.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Course::AutogenOniFromArtist( CString sArtistName, CString sArtistNameTranslit, vector<Song*> aSongs, Difficulty dc )
|
void Course::AutogenOniFromArtist( CString sArtistName, CString sArtistNameTranslit, vector<Song*> aSongs, Difficulty dc )
|
||||||
@@ -608,7 +626,7 @@ void Course::AutogenOniFromArtist( CString sArtistName, CString sArtistNameTrans
|
|||||||
for( unsigned i = 0; i < aSongs.size(); ++i )
|
for( unsigned i = 0; i < aSongs.size(); ++i )
|
||||||
{
|
{
|
||||||
e.pSong = aSongs[i];
|
e.pSong = aSongs[i];
|
||||||
m_entries.push_back( e );
|
m_vEntries.push_back( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,7 +690,7 @@ Trail* Course::GetTrail( StepsType st, CourseDifficulty cd ) const
|
|||||||
{
|
{
|
||||||
/* If we have any random entries (so that the seed matters), invalidate the cache. */
|
/* If we have any random entries (so that the seed matters), invalidate the cache. */
|
||||||
bool bHaveRandom = false;
|
bool bHaveRandom = false;
|
||||||
FOREACH_CONST( CourseEntry, m_entries, e )
|
FOREACH_CONST( CourseEntry, m_vEntries, e )
|
||||||
{
|
{
|
||||||
if( e->IsRandomSong() )
|
if( e->IsRandomSong() )
|
||||||
{
|
{
|
||||||
@@ -792,11 +810,11 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
/* Always randomize the same way per round. Otherwise, the displayed course
|
/* Always randomize the same way per round. Otherwise, the displayed course
|
||||||
* will change every time it's viewed, and the displayed order will have no
|
* will change every time it's viewed, and the displayed order will have no
|
||||||
* bearing on what you'll actually play. */
|
* bearing on what you'll actually play. */
|
||||||
tmp_entries = m_entries;
|
tmp_entries = m_vEntries;
|
||||||
random_shuffle( tmp_entries.begin(), tmp_entries.end(), rnd );
|
random_shuffle( tmp_entries.begin(), tmp_entries.end(), rnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<CourseEntry> &entries = m_bRandomize? tmp_entries:m_entries;
|
const vector<CourseEntry> &entries = m_bRandomize? tmp_entries:m_vEntries;
|
||||||
|
|
||||||
/* This can take some time, so don't fill it out unless we need it. */
|
/* This can take some time, so don't fill it out unless we need it. */
|
||||||
bool bMostPlayedSet = false;
|
bool bMostPlayedSet = false;
|
||||||
@@ -936,40 +954,37 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
|
|
||||||
|
|
||||||
// TODO: Move Course initialization after PROFILEMAN is created
|
// TODO: Move Course initialization after PROFILEMAN is created
|
||||||
if( PROFILEMAN && e->iMostPopularIndex != -1 )
|
switch( e->songSort )
|
||||||
{
|
|
||||||
SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), true ); // descending
|
|
||||||
if( e->iMostPopularIndex < vpPossibleSongs.size() )
|
|
||||||
{
|
|
||||||
pResolvedSong = vpPossibleSongs[e->iMostPopularIndex];
|
|
||||||
vector<Steps*> &vpPossibleSteps = mapSongToSteps[pResolvedSong];
|
|
||||||
pResolvedSteps = vpPossibleSteps[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( PROFILEMAN && e->iLeastPopularIndex != -1 )
|
|
||||||
{
|
|
||||||
SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), false ); // ascending
|
|
||||||
if( e->iLeastPopularIndex < vpPossibleSongs.size() )
|
|
||||||
{
|
|
||||||
pResolvedSong = vpPossibleSongs[e->iLeastPopularIndex];
|
|
||||||
vector<Steps*> &vpPossibleSteps = mapSongToSteps[pResolvedSong];
|
|
||||||
pResolvedSteps = vpPossibleSteps[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !vpPossibleSongs.empty() )
|
|
||||||
{
|
{
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
case SongSort_Randomize:
|
||||||
random_shuffle( vpPossibleSongs.begin(), vpPossibleSongs.end(), rnd );
|
random_shuffle( vpPossibleSongs.begin(), vpPossibleSongs.end(), rnd );
|
||||||
pResolvedSong = vpPossibleSongs[0];
|
break;
|
||||||
vector<Steps*> &vpPossibleSteps = mapSongToSteps[pResolvedSong];
|
case SongSort_MostPlays:
|
||||||
if( !vpPossibleSteps.empty() )
|
if( PROFILEMAN )
|
||||||
|
SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), true ); // descending
|
||||||
|
break;
|
||||||
|
case SongSort_FewestPlays:
|
||||||
|
if( PROFILEMAN )
|
||||||
|
SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), false ); // ascending
|
||||||
|
break;
|
||||||
|
case SongSort_TopGrades:
|
||||||
|
SongUtil::SortSongPointerArrayByGrades( vpPossibleSongs, true ); // descending
|
||||||
|
break;
|
||||||
|
case SongSort_LowestGrades:
|
||||||
|
SongUtil::SortSongPointerArrayByGrades( vpPossibleSongs, false ); // ascending
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( e->iChooseIndex < vpPossibleSongs.size() )
|
||||||
{
|
{
|
||||||
|
pResolvedSong = vpPossibleSongs[e->iChooseIndex];
|
||||||
|
vector<Steps*> &vpPossibleSteps = mapSongToSteps[pResolvedSong];
|
||||||
|
ASSERT( !vpPossibleSteps.empty() ); // if no steps are playable, this shouldn't be a possible song
|
||||||
random_shuffle( vpPossibleSteps.begin(), vpPossibleSteps.end(), rnd );
|
random_shuffle( vpPossibleSteps.begin(), vpPossibleSteps.end(), rnd );
|
||||||
pResolvedSteps = vpPossibleSteps[0];
|
pResolvedSteps = vpPossibleSteps[0];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( pResolvedSong == NULL || pResolvedSteps == NULL )
|
if( pResolvedSong == NULL || pResolvedSteps == NULL )
|
||||||
@@ -1096,7 +1111,7 @@ void Course::GetAllTrails( vector<Trail*> &AddTo ) const
|
|||||||
|
|
||||||
bool Course::HasMods() const
|
bool Course::HasMods() const
|
||||||
{
|
{
|
||||||
FOREACH_CONST( CourseEntry, m_entries, e )
|
FOREACH_CONST( CourseEntry, m_vEntries, e )
|
||||||
{
|
{
|
||||||
if( !e->sModifiers.empty() || !e->attacks.empty() )
|
if( !e->sModifiers.empty() || !e->attacks.empty() )
|
||||||
return true;
|
return true;
|
||||||
@@ -1107,7 +1122,7 @@ bool Course::HasMods() const
|
|||||||
|
|
||||||
bool Course::AllSongsAreFixed() const
|
bool Course::AllSongsAreFixed() const
|
||||||
{
|
{
|
||||||
FOREACH_CONST( CourseEntry, m_entries, e )
|
FOREACH_CONST( CourseEntry, m_vEntries, e )
|
||||||
{
|
{
|
||||||
if( e->pSong == NULL )
|
if( e->pSong == NULL )
|
||||||
return false;
|
return false;
|
||||||
@@ -1117,7 +1132,7 @@ bool Course::AllSongsAreFixed() const
|
|||||||
|
|
||||||
void Course::Invalidate( Song *pStaleSong )
|
void Course::Invalidate( Song *pStaleSong )
|
||||||
{
|
{
|
||||||
FOREACH_CONST( CourseEntry, m_entries, e )
|
FOREACH_CONST( CourseEntry, m_vEntries, e )
|
||||||
{
|
{
|
||||||
if( e->pSong == pStaleSong ) // a fixed entry that references the stale Song
|
if( e->pSong == pStaleSong ) // a fixed entry that references the stale Song
|
||||||
{
|
{
|
||||||
@@ -1161,8 +1176,8 @@ RageColor Course::GetColor() const
|
|||||||
switch( PREFSMAN->m_CourseSortOrder )
|
switch( PREFSMAN->m_CourseSortOrder )
|
||||||
{
|
{
|
||||||
case PrefsManager::COURSE_SORT_SONGS:
|
case PrefsManager::COURSE_SORT_SONGS:
|
||||||
if( m_entries.size() >= 7 ) return SORT_LEVEL2_COLOR;
|
if( m_vEntries.size() >= 7 ) return SORT_LEVEL2_COLOR;
|
||||||
else if( m_entries.size() >= 4 ) return SORT_LEVEL4_COLOR;
|
else if( m_vEntries.size() >= 4 ) return SORT_LEVEL4_COLOR;
|
||||||
else return SORT_LEVEL5_COLOR;
|
else return SORT_LEVEL5_COLOR;
|
||||||
|
|
||||||
case PrefsManager::COURSE_SORT_METER:
|
case PrefsManager::COURSE_SORT_METER:
|
||||||
@@ -1192,9 +1207,9 @@ RageColor Course::GetColor() const
|
|||||||
|
|
||||||
bool Course::IsFixed() const
|
bool Course::IsFixed() const
|
||||||
{
|
{
|
||||||
for(unsigned i = 0; i < m_entries.size(); i++)
|
for(unsigned i = 0; i < m_vEntries.size(); i++)
|
||||||
{
|
{
|
||||||
if ( m_entries[i].pSong == NULL )
|
if ( m_vEntries[i].pSong == NULL )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1217,11 +1232,11 @@ bool Course::GetTotalSeconds( StepsType st, float& fSecondsOut ) const
|
|||||||
|
|
||||||
bool Course::CourseHasBestOrWorst() const
|
bool Course::CourseHasBestOrWorst() const
|
||||||
{
|
{
|
||||||
FOREACH_CONST( CourseEntry, m_entries, e )
|
FOREACH_CONST( CourseEntry, m_vEntries, e )
|
||||||
{
|
{
|
||||||
if( e->iMostPopularIndex != -1 )
|
if( e->iChooseIndex == SongSort_MostPlays && e->iChooseIndex != -1 )
|
||||||
return true;
|
return true;
|
||||||
if( e->iLeastPopularIndex != -1 )
|
if( e->iChooseIndex == SongSort_FewestPlays && e->iChooseIndex != -1 )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1238,9 +1253,9 @@ void Course::UpdateCourseStats( StepsType st )
|
|||||||
m_SortOrder_TotalDifficulty = 0;
|
m_SortOrder_TotalDifficulty = 0;
|
||||||
|
|
||||||
// courses with random/players best-worst songs should go at the end
|
// courses with random/players best-worst songs should go at the end
|
||||||
for(unsigned i = 0; i < m_entries.size(); i++)
|
for(unsigned i = 0; i < m_vEntries.size(); i++)
|
||||||
{
|
{
|
||||||
if ( m_entries[i].pSong != NULL )
|
if ( m_vEntries[i].pSong != NULL )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( m_SortOrder_Ranking == 2 )
|
if ( m_SortOrder_Ranking == 2 )
|
||||||
@@ -1277,7 +1292,7 @@ bool Course::IsRanking() const
|
|||||||
|
|
||||||
const CourseEntry *Course::FindFixedSong( const Song *pSong ) const
|
const CourseEntry *Course::FindFixedSong( const Song *pSong ) const
|
||||||
{
|
{
|
||||||
FOREACH_CONST( CourseEntry, m_entries, e )
|
FOREACH_CONST( CourseEntry, m_vEntries, e )
|
||||||
{
|
{
|
||||||
const CourseEntry &entry = *e;
|
const CourseEntry &entry = *e;
|
||||||
if( entry.pSong == pSong )
|
if( entry.pSong == pSong )
|
||||||
|
|||||||
+22
-8
@@ -32,6 +32,19 @@ inline PlayMode CourseTypeToPlayMode( CourseType ct ) { return (PlayMode)(PLAY_M
|
|||||||
inline CourseType PlayModeToCourseType( PlayMode pm ) { return (CourseType)(pm-PLAY_MODE_NONSTOP); }
|
inline CourseType PlayModeToCourseType( PlayMode pm ) { return (CourseType)(pm-PLAY_MODE_NONSTOP); }
|
||||||
|
|
||||||
|
|
||||||
|
enum SongSort
|
||||||
|
{
|
||||||
|
SongSort_Randomize,
|
||||||
|
SongSort_MostPlays,
|
||||||
|
SongSort_FewestPlays,
|
||||||
|
SongSort_TopGrades,
|
||||||
|
SongSort_LowestGrades,
|
||||||
|
NUM_SongSort
|
||||||
|
};
|
||||||
|
#define FOREACH_SongSort( i ) FOREACH_ENUM( SongSort, NUM_SongSort, i )
|
||||||
|
const CString& SongSortToString( SongSort ss );
|
||||||
|
const CString& SongSortToThemedString( SongSort ss );
|
||||||
|
|
||||||
class CourseEntry
|
class CourseEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -44,8 +57,9 @@ public:
|
|||||||
bool bNoDifficult; // if true, CourseDifficulty doesn't affect this entry
|
bool bNoDifficult; // if true, CourseDifficulty doesn't affect this entry
|
||||||
int iLowMeter; // don't filter if -1
|
int iLowMeter; // don't filter if -1
|
||||||
int iHighMeter; // don't filter if -1
|
int iHighMeter; // don't filter if -1
|
||||||
int iMostPopularIndex; // don't filter if -1
|
|
||||||
int iLeastPopularIndex; // don't filter if -1
|
SongSort songSort; // sort by this after filtering
|
||||||
|
int iChooseIndex; //
|
||||||
|
|
||||||
CString sModifiers; // set player and song options using these
|
CString sModifiers; // set player and song options using these
|
||||||
AttackArray attacks; // timed sModifiers
|
AttackArray attacks; // timed sModifiers
|
||||||
@@ -61,8 +75,9 @@ public:
|
|||||||
bNoDifficult = false;
|
bNoDifficult = false;
|
||||||
iLowMeter = -1;
|
iLowMeter = -1;
|
||||||
iHighMeter = -1;
|
iHighMeter = -1;
|
||||||
iMostPopularIndex = -1;
|
|
||||||
iLeastPopularIndex = -1;
|
songSort = SongSort_Randomize;
|
||||||
|
iChooseIndex = 0;
|
||||||
|
|
||||||
sModifiers = "";
|
sModifiers = "";
|
||||||
fGainSeconds = 0;
|
fGainSeconds = 0;
|
||||||
@@ -71,8 +86,7 @@ public:
|
|||||||
bool IsRandomSong() const
|
bool IsRandomSong() const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
iMostPopularIndex == -1 &&
|
iChooseIndex == -1 &&
|
||||||
iLeastPopularIndex == -1 &&
|
|
||||||
pSong == NULL;
|
pSong == NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -101,7 +115,7 @@ public:
|
|||||||
int m_iCustomMeter[NUM_DIFFICULTIES]; // -1 = no meter specified
|
int m_iCustomMeter[NUM_DIFFICULTIES]; // -1 = no meter specified
|
||||||
bool m_bSortByMeter;
|
bool m_bSortByMeter;
|
||||||
|
|
||||||
vector<CourseEntry> m_entries;
|
vector<CourseEntry> m_vEntries;
|
||||||
|
|
||||||
/* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit* below.
|
/* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit* below.
|
||||||
* Otherwise, they return the main titles. */
|
* Otherwise, they return the main titles. */
|
||||||
@@ -124,7 +138,7 @@ public:
|
|||||||
bool HasMods() const;
|
bool HasMods() const;
|
||||||
bool AllSongsAreFixed() const;
|
bool AllSongsAreFixed() const;
|
||||||
|
|
||||||
int GetEstimatedNumStages() const { return m_entries.size(); }
|
int GetEstimatedNumStages() const { return m_vEntries.size(); }
|
||||||
bool IsPlayableIn( StepsType st ) const;
|
bool IsPlayableIn( StepsType st ) const;
|
||||||
bool CourseHasBestOrWorst() const;
|
bool CourseHasBestOrWorst() const;
|
||||||
RageColor GetColor() const;
|
RageColor GetColor() const;
|
||||||
|
|||||||
@@ -75,8 +75,7 @@ GameState::GameState() :
|
|||||||
m_stEdit( MESSAGE_EDIT_STEPS_TYPE_CHANGED ),
|
m_stEdit( MESSAGE_EDIT_STEPS_TYPE_CHANGED ),
|
||||||
m_pEditSourceSteps( MESSAGE_EDIT_SOURCE_STEPS_CHANGED ),
|
m_pEditSourceSteps( MESSAGE_EDIT_SOURCE_STEPS_CHANGED ),
|
||||||
m_stEditSource( MESSAGE_EDIT_SOURCE_STEPS_TYPE_CHANGED ),
|
m_stEditSource( MESSAGE_EDIT_SOURCE_STEPS_TYPE_CHANGED ),
|
||||||
m_iEditCourseEntryIndex(MESSAGE_EDIT_COURSE_ENTRY_INDEX_CHANGED ),
|
m_iEditCourseEntryIndex(MESSAGE_EDIT_COURSE_ENTRY_INDEX_CHANGED )
|
||||||
m_EditCourseEntryAction(MESSAGE_EDIT_COURSE_ENTRY_ACTION_CHANGED )
|
|
||||||
{
|
{
|
||||||
m_pCurStyle.Set( NULL );
|
m_pCurStyle.Set( NULL );
|
||||||
|
|
||||||
@@ -255,7 +254,6 @@ void GameState::Reset()
|
|||||||
m_pEditSourceSteps.Set( NULL );
|
m_pEditSourceSteps.Set( NULL );
|
||||||
m_stEditSource.Set( STEPS_TYPE_INVALID );
|
m_stEditSource.Set( STEPS_TYPE_INVALID );
|
||||||
m_iEditCourseEntryIndex.Set( -1 );
|
m_iEditCourseEntryIndex.Set( -1 );
|
||||||
m_EditCourseEntryAction.Set( ACTION_EDIT );
|
|
||||||
|
|
||||||
ApplyCmdline();
|
ApplyCmdline();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,8 +299,6 @@ public:
|
|||||||
BroadcastOnChangePtr<Steps> m_pEditSourceSteps;
|
BroadcastOnChangePtr<Steps> m_pEditSourceSteps;
|
||||||
BroadcastOnChange<StepsType> m_stEditSource;
|
BroadcastOnChange<StepsType> m_stEditSource;
|
||||||
BroadcastOnChange<int> m_iEditCourseEntryIndex;
|
BroadcastOnChange<int> m_iEditCourseEntryIndex;
|
||||||
enum EditCourseEntryAction { ACTION_EDIT, ACTION_INSERT };
|
|
||||||
BroadcastOnChange<EditCourseEntryAction> m_EditCourseEntryAction;
|
|
||||||
|
|
||||||
// Workout stuff
|
// Workout stuff
|
||||||
float GetGoalPercentComplete( PlayerNumber pn );
|
float GetGoalPercentComplete( PlayerNumber pn );
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void LifeMeterTime::OnLoadSong()
|
|||||||
|
|
||||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||||
ASSERT( pCourse );
|
ASSERT( pCourse );
|
||||||
const CourseEntry *pEntry = &pCourse->m_entries[GAMESTATE->GetCourseSongIndex()];
|
const CourseEntry *pEntry = &pCourse->m_vEntries[GAMESTATE->GetCourseSongIndex()];
|
||||||
m_fLifeTotalGainedSeconds += pEntry->fGainSeconds;
|
m_fLifeTotalGainedSeconds += pEntry->fGainSeconds;
|
||||||
|
|
||||||
if( GAMESTATE->GetCourseSongIndex() > 0 )
|
if( GAMESTATE->GetCourseSongIndex() > 0 )
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ static const CString MessageNames[] = {
|
|||||||
"EditPreferredCourseDifficutyP1Changed",
|
"EditPreferredCourseDifficutyP1Changed",
|
||||||
"EditPreferredCourseDifficutyP2Changed",
|
"EditPreferredCourseDifficutyP2Changed",
|
||||||
"EditCourseEntryIndexChanged",
|
"EditCourseEntryIndexChanged",
|
||||||
"EditCourseEntryActionChanged",
|
|
||||||
"GoalCompleteP1",
|
"GoalCompleteP1",
|
||||||
"GoalCompleteP2",
|
"GoalCompleteP2",
|
||||||
"NoteCrossed",
|
"NoteCrossed",
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ enum Message
|
|||||||
MESSAGE_EDIT_PREFERRED_COURSE_DIFFICULTY_P1_CHANGED,
|
MESSAGE_EDIT_PREFERRED_COURSE_DIFFICULTY_P1_CHANGED,
|
||||||
MESSAGE_EDIT_PREFERRED_COURSE_DIFFICULTY_P2_CHANGED,
|
MESSAGE_EDIT_PREFERRED_COURSE_DIFFICULTY_P2_CHANGED,
|
||||||
MESSAGE_EDIT_COURSE_ENTRY_INDEX_CHANGED,
|
MESSAGE_EDIT_COURSE_ENTRY_INDEX_CHANGED,
|
||||||
MESSAGE_EDIT_COURSE_ENTRY_ACTION_CHANGED,
|
|
||||||
MESSAGE_GOAL_COMPLETE_P1,
|
MESSAGE_GOAL_COMPLETE_P1,
|
||||||
MESSAGE_GOAL_COMPLETE_P2,
|
MESSAGE_GOAL_COMPLETE_P2,
|
||||||
MESSAGE_NOTE_CROSSED,
|
MESSAGE_NOTE_CROSSED,
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
|||||||
bUseSections = false;
|
bUseSections = false;
|
||||||
break;
|
break;
|
||||||
case SORT_TOP_GRADES:
|
case SORT_TOP_GRADES:
|
||||||
SongUtil::SortSongPointerArrayByGrade( arraySongs );
|
SongUtil::SortSongPointerArrayByGrades( arraySongs, true );
|
||||||
break;
|
break;
|
||||||
case SORT_ARTIST:
|
case SORT_ARTIST:
|
||||||
SongUtil::SortSongPointerArrayByArtist( arraySongs );
|
SongUtil::SortSongPointerArrayByArtist( arraySongs );
|
||||||
|
|||||||
@@ -691,6 +691,36 @@ void OptionRow::SetOneSharedSelection( int iChoice )
|
|||||||
SetOneSelection( pn, iChoice );
|
SetOneSelection( pn, iChoice );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int OptionRow::GetChoiceInRowWithFocus( PlayerNumber pn ) const
|
||||||
|
{
|
||||||
|
if( m_RowDef.bOneChoiceForAllPlayers )
|
||||||
|
pn = PLAYER_1;
|
||||||
|
if( m_RowDef.choices.empty() )
|
||||||
|
return -1;
|
||||||
|
int iChoice = m_iChoiceInRowWithFocus[pn];
|
||||||
|
return iChoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OptionRow::GetChoiceInRowWithFocusShared() const
|
||||||
|
{
|
||||||
|
return GetChoiceInRowWithFocus( (PlayerNumber)0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionRow::SetChoiceInRowWithFocus( PlayerNumber pn, int iChoice )
|
||||||
|
{
|
||||||
|
if( m_RowDef.bOneChoiceForAllPlayers )
|
||||||
|
pn = PLAYER_1;
|
||||||
|
ASSERT(iChoice >= 0 && iChoice < (int)m_RowDef.choices.size());
|
||||||
|
m_iChoiceInRowWithFocus[pn] = iChoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionRow::SetChoiceInRowWithFocusShared( int iChoice )
|
||||||
|
{
|
||||||
|
FOREACH_PlayerNumber( pn )
|
||||||
|
SetChoiceInRowWithFocus( pn, iChoice );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OptionRow::SetExitText( CString sExitText )
|
void OptionRow::SetExitText( CString sExitText )
|
||||||
{
|
{
|
||||||
BitmapText *bt = m_textItems.back();
|
BitmapText *bt = m_textItems.back();
|
||||||
|
|||||||
@@ -107,22 +107,11 @@ public:
|
|||||||
void SetOneSelection( PlayerNumber pn, int iChoice );
|
void SetOneSelection( PlayerNumber pn, int iChoice );
|
||||||
void SetOneSharedSelection( int iChoice );
|
void SetOneSharedSelection( int iChoice );
|
||||||
|
|
||||||
int GetChoiceInRowWithFocus( PlayerNumber pn ) const
|
int GetChoiceInRowWithFocus( PlayerNumber pn ) const;
|
||||||
{
|
int GetChoiceInRowWithFocusShared() const;
|
||||||
if( m_RowDef.bOneChoiceForAllPlayers )
|
void SetChoiceInRowWithFocus( PlayerNumber pn, int iChoice );
|
||||||
pn = PLAYER_1;
|
void SetChoiceInRowWithFocusShared( int iChoice );
|
||||||
if( m_RowDef.choices.empty() )
|
|
||||||
return -1;
|
|
||||||
int iChoice = m_iChoiceInRowWithFocus[pn];
|
|
||||||
return iChoice;
|
|
||||||
}
|
|
||||||
void SetChoiceInRowWithFocus( PlayerNumber pn, int iChoice )
|
|
||||||
{
|
|
||||||
if( m_RowDef.bOneChoiceForAllPlayers )
|
|
||||||
pn = PLAYER_1;
|
|
||||||
ASSERT(iChoice >= 0 && iChoice < (int)m_RowDef.choices.size());
|
|
||||||
m_iChoiceInRowWithFocus[pn] = iChoice;
|
|
||||||
}
|
|
||||||
bool GetSelected( PlayerNumber pn, int iChoice ) const
|
bool GetSelected( PlayerNumber pn, int iChoice ) const
|
||||||
{
|
{
|
||||||
if( m_RowDef.bOneChoiceForAllPlayers )
|
if( m_RowDef.bOneChoiceForAllPlayers )
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ void ScoreDisplayLifeTime::OnLoadSong()
|
|||||||
|
|
||||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||||
ASSERT( pCourse );
|
ASSERT( pCourse );
|
||||||
const CourseEntry *pEntry = &pCourse->m_entries[GAMESTATE->GetCourseSongIndex()];
|
const CourseEntry *pEntry = &pCourse->m_vEntries[GAMESTATE->GetCourseSongIndex()];
|
||||||
|
|
||||||
PlayGainLoss( GAIN_LIFE_COMMAND_NAME, pEntry->fGainSeconds );
|
PlayGainLoss( GAIN_LIFE_COMMAND_NAME, pEntry->fGainSeconds );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ void ScreenCourseManager::GoToNextScreen()
|
|||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
case ACTION_EDIT:
|
case ACTION_EDIT:
|
||||||
|
GAMESTATE->m_iEditCourseEntryIndex.Set( 0 );
|
||||||
SCREENMAN->SetNewScreen( "ScreenEditCourse" );
|
SCREENMAN->SetNewScreen( "ScreenEditCourse" );
|
||||||
break;
|
break;
|
||||||
case ACTION_DELETE:
|
case ACTION_DELETE:
|
||||||
|
|||||||
@@ -1390,9 +1390,9 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
|||||||
const Course *crs = courses[i];
|
const Course *crs = courses[i];
|
||||||
|
|
||||||
bool bUsesThisSong = false;
|
bool bUsesThisSong = false;
|
||||||
for( unsigned e = 0; e < crs->m_entries.size(); ++e )
|
for( unsigned e = 0; e < crs->m_vEntries.size(); ++e )
|
||||||
{
|
{
|
||||||
if( crs->m_entries[e].pSong != m_pSong )
|
if( crs->m_vEntries[e].pSong != m_pSong )
|
||||||
continue;
|
continue;
|
||||||
bUsesThisSong = true;
|
bUsesThisSong = true;
|
||||||
}
|
}
|
||||||
@@ -2812,12 +2812,12 @@ void ScreenEdit::SetupCourseAttacks()
|
|||||||
m_pAttacksFromCourse->LoadFromCRSFile( m_pAttacksFromCourse->m_sPath );
|
m_pAttacksFromCourse->LoadFromCRSFile( m_pAttacksFromCourse->m_sPath );
|
||||||
|
|
||||||
AttackArray Attacks;
|
AttackArray Attacks;
|
||||||
for( unsigned e = 0; e < m_pAttacksFromCourse->m_entries.size(); ++e )
|
for( unsigned e = 0; e < m_pAttacksFromCourse->m_vEntries.size(); ++e )
|
||||||
{
|
{
|
||||||
if( m_pAttacksFromCourse->m_entries[e].pSong != m_pSong )
|
if( m_pAttacksFromCourse->m_vEntries[e].pSong != m_pSong )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Attacks = m_pAttacksFromCourse->m_entries[e].attacks;
|
Attacks = m_pAttacksFromCourse->m_vEntries[e].attacks;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ enum EditCourseRow
|
|||||||
ROW_TYPE_METER,
|
ROW_TYPE_METER,
|
||||||
ROW_EDIT_ENTRY,
|
ROW_EDIT_ENTRY,
|
||||||
ROW_INSERT_ENTRY,
|
ROW_INSERT_ENTRY,
|
||||||
|
ROW_DELETE_ENTRY,
|
||||||
ROW_DONE,
|
ROW_DONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,14 +57,18 @@ void ScreenEditCourse::Init()
|
|||||||
{
|
{
|
||||||
ScreenOptions::Init();
|
ScreenOptions::Init();
|
||||||
|
|
||||||
|
|
||||||
|
// save a backup that we'll use if we revert.
|
||||||
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
|
m_Original = *pCourse;
|
||||||
|
|
||||||
|
|
||||||
vector<OptionRowDefinition> vDefs;
|
vector<OptionRowDefinition> vDefs;
|
||||||
vector<OptionRowHandler*> vHands;
|
vector<OptionRowHandler*> vHands;
|
||||||
|
|
||||||
OptionRowDefinition def;
|
OptionRowDefinition def;
|
||||||
def.layoutType = LAYOUT_SHOW_ONE_IN_ROW;
|
def.layoutType = LAYOUT_SHOW_ONE_IN_ROW;
|
||||||
|
|
||||||
Course *pCourse = GAMESTATE->m_pCurCourse;
|
|
||||||
|
|
||||||
def.name = "Title";
|
def.name = "Title";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
def.choices.push_back( pCourse->GetTranslitFullTitle() );
|
def.choices.push_back( pCourse->GetTranslitFullTitle() );
|
||||||
@@ -94,7 +99,6 @@ void ScreenEditCourse::Init()
|
|||||||
|
|
||||||
def.name = "Type";
|
def.name = "Type";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
|
|
||||||
FOREACH_CONST( StepsType, STEPS_TYPES_TO_SHOW.GetValue(), st )
|
FOREACH_CONST( StepsType, STEPS_TYPES_TO_SHOW.GetValue(), st )
|
||||||
def.choices.push_back( GAMEMAN->StepsTypeToString(*st) );
|
def.choices.push_back( GAMEMAN->StepsTypeToString(*st) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
@@ -102,19 +106,36 @@ void ScreenEditCourse::Init()
|
|||||||
|
|
||||||
def.name = "Type Meter";
|
def.name = "Type Meter";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
def.choices.push_back( "" );
|
for( int i=MIN_METER; i<=MAX_METER; i++ )
|
||||||
|
def.choices.push_back( ssprintf("%d",i) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
vHands.push_back( NULL );
|
vHands.push_back( NULL );
|
||||||
|
|
||||||
def.name = "Edit Entry";
|
def.name = "Edit Entry";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
def.choices.push_back( "" );
|
for( unsigned i=0; i<pCourse->m_vEntries.size(); i++ )
|
||||||
|
def.choices.push_back( ssprintf("%u of %u",i+1,pCourse->m_vEntries.size()) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
vHands.push_back( NULL );
|
vHands.push_back( NULL );
|
||||||
|
|
||||||
def.name = "Insert Entry";
|
def.name = "Insert Entry";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
def.choices.push_back( "" );
|
for( unsigned i=0; i<=pCourse->m_vEntries.size(); i++ )
|
||||||
|
{
|
||||||
|
CString s;
|
||||||
|
if( i == pCourse->m_vEntries.size() )
|
||||||
|
s = ssprintf("After %u",i);
|
||||||
|
else
|
||||||
|
s = ssprintf("Before %u",i+1);
|
||||||
|
def.choices.push_back( s );
|
||||||
|
}
|
||||||
|
vDefs.push_back( def );
|
||||||
|
vHands.push_back( NULL );
|
||||||
|
|
||||||
|
def.name = "Delete Entry";
|
||||||
|
def.choices.clear();
|
||||||
|
for( unsigned i=0; i<pCourse->m_vEntries.size(); i++ )
|
||||||
|
def.choices.push_back( ssprintf("%u of %u",i+1,pCourse->m_vEntries.size()) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
vHands.push_back( NULL );
|
vHands.push_back( NULL );
|
||||||
|
|
||||||
@@ -131,6 +152,7 @@ void ScreenEditCourse::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
void ScreenEditCourse::AfterChangeValueInRow( PlayerNumber pn )
|
void ScreenEditCourse::AfterChangeValueInRow( PlayerNumber pn )
|
||||||
{
|
{
|
||||||
ScreenOptions::AfterChangeValueInRow( pn );
|
ScreenOptions::AfterChangeValueInRow( pn );
|
||||||
|
|
||||||
Course *pCourse = GAMESTATE->m_pCurCourse;
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
StepsType st = STEPS_TYPE_INVALID;
|
StepsType st = STEPS_TYPE_INVALID;
|
||||||
CourseDifficulty cd = DIFFICULTY_INVALID;
|
CourseDifficulty cd = DIFFICULTY_INVALID;
|
||||||
@@ -174,48 +196,8 @@ void ScreenEditCourse::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
OptionRow &row = *m_pRows[ROW_TYPE_METER];
|
OptionRow &row = *m_pRows[ROW_TYPE_METER];
|
||||||
OptionRowDefinition def = row.GetRowDef();
|
OptionRowDefinition def = row.GetRowDef();
|
||||||
Trail *pTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber];
|
Trail *pTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber];
|
||||||
def.choices.clear();
|
ASSERT( pTrail );
|
||||||
if( pTrail != NULL )
|
|
||||||
{
|
|
||||||
for( int i=MIN_METER; i<=MAX_METER; i++ )
|
|
||||||
def.choices.push_back( ssprintf("%d",i) );
|
|
||||||
row.SetOneSharedSelection( pTrail->GetMeter()-MIN_METER );
|
row.SetOneSharedSelection( pTrail->GetMeter()-MIN_METER );
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
def.choices.push_back( "N/A" );
|
|
||||||
}
|
|
||||||
row.Reload( def );
|
|
||||||
}
|
|
||||||
// refresh edit entry
|
|
||||||
{
|
|
||||||
OptionRow &row = *m_pRows[ROW_EDIT_ENTRY];
|
|
||||||
OptionRowDefinition def = row.GetRowDef();
|
|
||||||
def.choices.clear();
|
|
||||||
Trail *pTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber];
|
|
||||||
ASSERT( pTrail );
|
|
||||||
for( unsigned i=0; i<pTrail->m_vEntries.size(); i++ )
|
|
||||||
def.choices.push_back( ssprintf("%u of %u",i+1,pTrail->m_vEntries.size()) );
|
|
||||||
row.SetOneSharedSelection( 0 );
|
|
||||||
row.Reload( def );
|
|
||||||
}
|
|
||||||
// refresh insert entry
|
|
||||||
{
|
|
||||||
OptionRow &row = *m_pRows[ROW_INSERT_ENTRY];
|
|
||||||
OptionRowDefinition def = row.GetRowDef();
|
|
||||||
def.choices.clear();
|
|
||||||
Trail *pTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber];
|
|
||||||
ASSERT( pTrail );
|
|
||||||
for( unsigned i=0; i<=pTrail->m_vEntries.size(); i++ )
|
|
||||||
{
|
|
||||||
CString s;
|
|
||||||
if( i == pTrail->m_vEntries.size() )
|
|
||||||
s = ssprintf("After %u",i);
|
|
||||||
else
|
|
||||||
s = ssprintf("Before %u",i+1);
|
|
||||||
def.choices.push_back( s );
|
|
||||||
}
|
|
||||||
row.SetOneSharedSelection( 0 );
|
|
||||||
row.Reload( def );
|
row.Reload( def );
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
@@ -228,8 +210,6 @@ void ScreenEditCourse::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case ROW_EDIT_ENTRY:
|
case ROW_EDIT_ENTRY:
|
||||||
// fall through
|
|
||||||
case ROW_INSERT_ENTRY:
|
|
||||||
// export entry number
|
// export entry number
|
||||||
{
|
{
|
||||||
EditCourseRow ecr = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber] == ROW_EDIT_ENTRY ? ROW_EDIT_ENTRY : ROW_INSERT_ENTRY;
|
EditCourseRow ecr = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber] == ROW_EDIT_ENTRY ? ROW_EDIT_ENTRY : ROW_INSERT_ENTRY;
|
||||||
@@ -238,14 +218,28 @@ void ScreenEditCourse::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
GAMESTATE->m_iEditCourseEntryIndex.Set( iChoice );
|
GAMESTATE->m_iEditCourseEntryIndex.Set( iChoice );
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
|
case ROW_INSERT_ENTRY:
|
||||||
|
// fall through
|
||||||
|
case ROW_DELETE_ENTRY:
|
||||||
|
// fall through
|
||||||
case ROW_DONE:
|
case ROW_DONE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEditCourse::ImportOptions( int row, const vector<PlayerNumber> &vpns )
|
void ScreenEditCourse::ImportOptions( int iRow, const vector<PlayerNumber> &vpns )
|
||||||
{
|
{
|
||||||
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
|
|
||||||
|
switch( iRow )
|
||||||
|
{
|
||||||
|
case ROW_EDIT_ENTRY:
|
||||||
|
case ROW_INSERT_ENTRY:
|
||||||
|
case ROW_DELETE_ENTRY:
|
||||||
|
OptionRow &row = *m_pRows[iRow];
|
||||||
|
row.SetChoiceInRowWithFocusShared( GAMESTATE->m_iEditCourseEntryIndex );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEditCourse::ExportOptions( int row, const vector<PlayerNumber> &vpns )
|
void ScreenEditCourse::ExportOptions( int row, const vector<PlayerNumber> &vpns )
|
||||||
@@ -265,6 +259,10 @@ void ScreenEditCourse::GoToNextScreen()
|
|||||||
case ROW_TYPE:
|
case ROW_TYPE:
|
||||||
case ROW_TYPE_METER:
|
case ROW_TYPE_METER:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
case ROW_INSERT_ENTRY:
|
||||||
|
case ROW_DELETE_ENTRY:
|
||||||
|
SCREENMAN->SetNewScreen( "ScreenEditCourse" );
|
||||||
|
break;
|
||||||
case ROW_EDIT_ENTRY:
|
case ROW_EDIT_ENTRY:
|
||||||
SCREENMAN->SetNewScreen( "ScreenEditCourseEntry" );
|
SCREENMAN->SetNewScreen( "ScreenEditCourseEntry" );
|
||||||
break;
|
break;
|
||||||
@@ -276,11 +274,17 @@ void ScreenEditCourse::GoToNextScreen()
|
|||||||
|
|
||||||
void ScreenEditCourse::GoToPrevScreen()
|
void ScreenEditCourse::GoToPrevScreen()
|
||||||
{
|
{
|
||||||
|
// revert
|
||||||
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
|
*pCourse = m_Original;
|
||||||
|
|
||||||
SCREENMAN->SetNewScreen( "ScreenCourseManager" );
|
SCREENMAN->SetNewScreen( "ScreenCourseManager" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEditCourse::ProcessMenuStart( PlayerNumber pn, const InputEventType type )
|
void ScreenEditCourse::ProcessMenuStart( PlayerNumber pn, const InputEventType type )
|
||||||
{
|
{
|
||||||
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
|
|
||||||
switch( m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber] )
|
switch( m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber] )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@@ -293,16 +297,23 @@ void ScreenEditCourse::ProcessMenuStart( PlayerNumber pn, const InputEventType t
|
|||||||
case ROW_TYPE_METER:
|
case ROW_TYPE_METER:
|
||||||
SCREENMAN->PlayInvalidSound();
|
SCREENMAN->PlayInvalidSound();
|
||||||
break;
|
break;
|
||||||
case ROW_EDIT_ENTRY:
|
|
||||||
case ROW_INSERT_ENTRY:
|
case ROW_INSERT_ENTRY:
|
||||||
{
|
{
|
||||||
Trail *pTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber];
|
OptionRow &row = *m_pRows[ROW_INSERT_ENTRY];
|
||||||
if( pTrail == NULL )
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
|
pCourse->m_vEntries.insert( pCourse->m_vEntries.begin()+iChoice, CourseEntry() );
|
||||||
|
ScreenOptions::BeginFadingOut();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ROW_DELETE_ENTRY:
|
||||||
{
|
{
|
||||||
SCREENMAN->PlayInvalidSound();
|
OptionRow &row = *m_pRows[ROW_DELETE_ENTRY];
|
||||||
return;
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
}
|
pCourse->m_vEntries.erase( pCourse->m_vEntries.begin()+iChoice );
|
||||||
|
ScreenOptions::BeginFadingOut();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ROW_EDIT_ENTRY:
|
||||||
case ROW_DONE:
|
case ROW_DONE:
|
||||||
ScreenOptions::BeginFadingOut();
|
ScreenOptions::BeginFadingOut();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define ScreenEditCourse_H
|
#define ScreenEditCourse_H
|
||||||
|
|
||||||
#include "ScreenOptions.h"
|
#include "ScreenOptions.h"
|
||||||
|
#include "Course.h"
|
||||||
|
|
||||||
class ScreenEditCourse : public ScreenOptions
|
class ScreenEditCourse : public ScreenOptions
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,8 @@ protected:
|
|||||||
|
|
||||||
virtual void AfterChangeValueInRow( PlayerNumber pn );
|
virtual void AfterChangeValueInRow( PlayerNumber pn );
|
||||||
virtual void ProcessMenuStart( PlayerNumber pn, const InputEventType type );
|
virtual void ProcessMenuStart( PlayerNumber pn, const InputEventType type );
|
||||||
|
|
||||||
|
Course m_Original;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ enum EditCourseEntryRow
|
|||||||
ROW_BASE_DIFFICULTY,
|
ROW_BASE_DIFFICULTY,
|
||||||
ROW_LOW_METER,
|
ROW_LOW_METER,
|
||||||
ROW_HIGH_METER,
|
ROW_HIGH_METER,
|
||||||
ROW_BEST_WORST_VALUE,
|
ROW_SORT,
|
||||||
|
ROW_CHOOSE_INDEX,
|
||||||
ROW_SET_MODS,
|
ROW_SET_MODS,
|
||||||
ROW_DONE,
|
ROW_DONE,
|
||||||
NUM_EditCourseEntryRow
|
NUM_EditCourseEntryRow
|
||||||
};
|
};
|
||||||
#define FOREACH_EditCourseEntryRow( i ) FOREACH_ENUM( EditCourseEntryRow, NUM_EditCourseEntryRow, i )
|
#define FOREACH_EditCourseEntryRow( i ) FOREACH_ENUM( EditCourseEntryRow, NUM_EditCourseEntryRow, i )
|
||||||
|
|
||||||
|
|
||||||
REGISTER_SCREEN_CLASS( ScreenEditCourseEntry );
|
REGISTER_SCREEN_CLASS( ScreenEditCourseEntry );
|
||||||
ScreenEditCourseEntry::ScreenEditCourseEntry( CString sName ) : ScreenOptions( sName )
|
ScreenEditCourseEntry::ScreenEditCourseEntry( CString sName ) : ScreenOptions( sName )
|
||||||
{
|
{
|
||||||
@@ -31,6 +33,12 @@ void ScreenEditCourseEntry::Init()
|
|||||||
{
|
{
|
||||||
ScreenOptions::Init();
|
ScreenOptions::Init();
|
||||||
|
|
||||||
|
|
||||||
|
// save a backup that we'll use if we revert.
|
||||||
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
|
m_Original = pCourse->m_vEntries[ GAMESTATE->m_iEditCourseEntryIndex ];
|
||||||
|
|
||||||
|
|
||||||
vector<OptionRowDefinition> vDefs;
|
vector<OptionRowDefinition> vDefs;
|
||||||
vector<OptionRowHandler*> vHands;
|
vector<OptionRowHandler*> vHands;
|
||||||
|
|
||||||
@@ -41,6 +49,7 @@ void ScreenEditCourseEntry::Init()
|
|||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
vector<CString> vsSongGroups;
|
vector<CString> vsSongGroups;
|
||||||
SONGMAN->GetSongGroupNames( vsSongGroups );
|
SONGMAN->GetSongGroupNames( vsSongGroups );
|
||||||
|
def.choices.push_back( "(any)" );
|
||||||
FOREACH_CONST( CString, vsSongGroups, s )
|
FOREACH_CONST( CString, vsSongGroups, s )
|
||||||
def.choices.push_back( *s );
|
def.choices.push_back( *s );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
@@ -54,6 +63,7 @@ void ScreenEditCourseEntry::Init()
|
|||||||
|
|
||||||
def.name = "Base Difficulty";
|
def.name = "Base Difficulty";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
|
def.choices.push_back( "(any)" );
|
||||||
FOREACH_CONST( Difficulty, DIFFICULTIES_TO_SHOW.GetValue(), dc )
|
FOREACH_CONST( Difficulty, DIFFICULTIES_TO_SHOW.GetValue(), dc )
|
||||||
def.choices.push_back( DifficultyToThemedString(*dc) );
|
def.choices.push_back( DifficultyToThemedString(*dc) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
@@ -61,6 +71,7 @@ void ScreenEditCourseEntry::Init()
|
|||||||
|
|
||||||
def.name = "Low Meter";
|
def.name = "Low Meter";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
|
def.choices.push_back( "(any)" );
|
||||||
for( int i=MIN_METER; i<=MAX_METER; i++ )
|
for( int i=MIN_METER; i<=MAX_METER; i++ )
|
||||||
def.choices.push_back( ssprintf("%i",i) );
|
def.choices.push_back( ssprintf("%i",i) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
@@ -68,15 +79,23 @@ void ScreenEditCourseEntry::Init()
|
|||||||
|
|
||||||
def.name = "High Meter";
|
def.name = "High Meter";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
|
def.choices.push_back( "(any)" );
|
||||||
for( int i=MIN_METER; i<=MAX_METER; i++ )
|
for( int i=MIN_METER; i<=MAX_METER; i++ )
|
||||||
def.choices.push_back( ssprintf("%i",i) );
|
def.choices.push_back( ssprintf("%i",i) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
vHands.push_back( NULL );
|
vHands.push_back( NULL );
|
||||||
|
|
||||||
def.name = "Best/Worst Value";
|
def.name = "Sort";
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
for( int i=1; i<=20; i++ )
|
FOREACH_SongSort( i )
|
||||||
def.choices.push_back( ssprintf("%i",i) );
|
def.choices.push_back( SongSortToThemedString(i) );
|
||||||
|
vDefs.push_back( def );
|
||||||
|
vHands.push_back( NULL );
|
||||||
|
|
||||||
|
def.name = "Choose";
|
||||||
|
def.choices.clear();
|
||||||
|
for( int i=0; i<20; i++ )
|
||||||
|
def.choices.push_back( FormatNumberAndSuffix(i+1) );
|
||||||
vDefs.push_back( def );
|
vDefs.push_back( def );
|
||||||
vHands.push_back( NULL );
|
vHands.push_back( NULL );
|
||||||
|
|
||||||
@@ -88,7 +107,7 @@ void ScreenEditCourseEntry::Init()
|
|||||||
|
|
||||||
ScreenOptions::InitMenu( INPUTMODE_SHARE_CURSOR, vDefs, vHands );
|
ScreenOptions::InitMenu( INPUTMODE_SHARE_CURSOR, vDefs, vHands );
|
||||||
|
|
||||||
AfterChangeValueInRow( GAMESTATE->m_MasterPlayerNumber );
|
ImportAllOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEditCourseEntry::HandleScreenMessage( const ScreenMessage SM )
|
void ScreenEditCourseEntry::HandleScreenMessage( const ScreenMessage SM )
|
||||||
@@ -100,8 +119,7 @@ void ScreenEditCourseEntry::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
{
|
{
|
||||||
ScreenOptions::AfterChangeValueInRow( pn );
|
ScreenOptions::AfterChangeValueInRow( pn );
|
||||||
Course *pCourse = GAMESTATE->m_pCurCourse;
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
CourseEntry &ce = pCourse->m_entries[ GAMESTATE->m_iEditCourseEntryIndex ];
|
CourseEntry &ce = pCourse->m_vEntries[ GAMESTATE->m_iEditCourseEntryIndex ];
|
||||||
CString sSongGroup;
|
|
||||||
|
|
||||||
switch( m_iCurrentRow[pn] )
|
switch( m_iCurrentRow[pn] )
|
||||||
{
|
{
|
||||||
@@ -110,22 +128,29 @@ void ScreenEditCourseEntry::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
{
|
{
|
||||||
OptionRow &row = *m_pRows[ROW_SONG_GROUP];
|
OptionRow &row = *m_pRows[ROW_SONG_GROUP];
|
||||||
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
sSongGroup = row.GetRowDef().choices[ iChoice ];
|
if( iChoice == 0 )
|
||||||
|
ce.sSongGroup = "";
|
||||||
|
else
|
||||||
|
ce.sSongGroup = row.GetRowDef().choices[ iChoice ];
|
||||||
}
|
}
|
||||||
// refresh songs
|
// refresh songs
|
||||||
{
|
{
|
||||||
OptionRow &row = *m_pRows[ROW_SONG];
|
OptionRow &row = *m_pRows[ROW_SONG];
|
||||||
OptionRowDefinition def = row.GetRowDef();
|
OptionRowDefinition def = row.GetRowDef();
|
||||||
def.choices.clear();
|
def.choices.clear();
|
||||||
|
def.choices.push_back( "(any)" );
|
||||||
vector<Song*> vpSongs;
|
vector<Song*> vpSongs;
|
||||||
SONGMAN->GetSongs( vpSongs, sSongGroup );
|
if( ce.sSongGroup.empty() )
|
||||||
|
SONGMAN->GetSongs( vpSongs );
|
||||||
|
else
|
||||||
|
SONGMAN->GetSongs( vpSongs, ce.sSongGroup );
|
||||||
FOREACH_CONST( Song*, vpSongs, s )
|
FOREACH_CONST( Song*, vpSongs, s )
|
||||||
def.choices.push_back( (*s)->GetTranslitFullTitle() );
|
def.choices.push_back( (*s)->GetTranslitFullTitle() );
|
||||||
vector<Song*>::const_iterator iter = find( vpSongs.begin(), vpSongs.end(), ce.pSong );
|
vector<Song*>::const_iterator iter = find( vpSongs.begin(), vpSongs.end(), ce.pSong );
|
||||||
if( iter != vpSongs.end() )
|
if( iter != vpSongs.end() )
|
||||||
{
|
{
|
||||||
int iSongIndex = iter - vpSongs.begin();
|
int iSongIndex = iter - vpSongs.begin();
|
||||||
row.SetOneSharedSelection( iSongIndex );
|
row.SetOneSharedSelection( iSongIndex+1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -139,7 +164,10 @@ void ScreenEditCourseEntry::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
{
|
{
|
||||||
OptionRow &row = *m_pRows[ROW_SONG];
|
OptionRow &row = *m_pRows[ROW_SONG];
|
||||||
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
ce.pSong = SONGMAN->GetAllSongs()[iChoice];
|
if( iChoice == 0 )
|
||||||
|
ce.pSong = NULL;
|
||||||
|
else
|
||||||
|
ce.pSong = SONGMAN->GetAllSongs()[iChoice-1];
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case ROW_BASE_DIFFICULTY:
|
case ROW_BASE_DIFFICULTY:
|
||||||
@@ -153,16 +181,39 @@ void ScreenEditCourseEntry::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
case ROW_LOW_METER:
|
case ROW_LOW_METER:
|
||||||
// export low meter
|
// export low meter
|
||||||
{
|
{
|
||||||
|
OptionRow &row = *m_pRows[ROW_LOW_METER];
|
||||||
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
|
if( iChoice == 0 )
|
||||||
|
ce.iLowMeter = -1;
|
||||||
|
else
|
||||||
|
ce.iLowMeter = iChoice;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case ROW_HIGH_METER:
|
case ROW_HIGH_METER:
|
||||||
// export high meter
|
// export high meter
|
||||||
{
|
{
|
||||||
|
OptionRow &row = *m_pRows[ROW_HIGH_METER];
|
||||||
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
|
if( iChoice == 0 )
|
||||||
|
ce.iHighMeter = -1;
|
||||||
|
else
|
||||||
|
ce.iHighMeter = iChoice;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case ROW_BEST_WORST_VALUE:
|
case ROW_SORT:
|
||||||
// export best/worst value
|
// export sort
|
||||||
{
|
{
|
||||||
|
OptionRow &row = *m_pRows[ROW_SORT];
|
||||||
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
|
ce.songSort = (SongSort)iChoice;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case ROW_CHOOSE_INDEX:
|
||||||
|
// export choose index
|
||||||
|
{
|
||||||
|
OptionRow &row = *m_pRows[ROW_CHOOSE_INDEX];
|
||||||
|
int iChoice = row.GetChoiceInRowWithFocus( GAMESTATE->m_MasterPlayerNumber );
|
||||||
|
ce.iChooseIndex = iChoice;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case ROW_SET_MODS:
|
case ROW_SET_MODS:
|
||||||
@@ -172,33 +223,77 @@ void ScreenEditCourseEntry::AfterChangeValueInRow( PlayerNumber pn )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEditCourseEntry::ImportOptions( int row, const vector<PlayerNumber> &vpns )
|
void ScreenEditCourseEntry::ImportAllOptions()
|
||||||
{
|
{
|
||||||
Course *pCourse = GAMESTATE->m_pCurCourse;
|
// fill choices before importing
|
||||||
CourseEntry &ce = pCourse->m_entries[ GAMESTATE->m_iEditCourseEntryIndex ];
|
AfterChangeValueInRow( GAMESTATE->m_MasterPlayerNumber );
|
||||||
|
|
||||||
// import entry song
|
|
||||||
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
|
CourseEntry &ce = pCourse->m_vEntries[ GAMESTATE->m_iEditCourseEntryIndex ];
|
||||||
|
|
||||||
|
// import song group
|
||||||
{
|
{
|
||||||
int iSongIndex = -1;
|
OptionRow &row = *m_pRows[ROW_SONG_GROUP];
|
||||||
vector<Song*>::const_iterator iter = find( SONGMAN->GetAllSongs().begin(), SONGMAN->GetAllSongs().end(), ce.pSong );
|
FOREACH_CONST( CString, row.GetRowDef().choices, s )
|
||||||
if( iter != SONGMAN->GetAllSongs().end() )
|
{
|
||||||
iSongIndex = iter - SONGMAN->GetAllSongs().begin();
|
if( *s == ce.sSongGroup )
|
||||||
|
{
|
||||||
|
int iChoice = s - row.GetRowDef().choices.begin();
|
||||||
|
row.SetOneSharedSelection( iChoice );
|
||||||
|
AfterChangeValueInRow( GAMESTATE->m_MasterPlayerNumber );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// import song
|
||||||
|
{
|
||||||
|
vector<Song*> vpSongs;
|
||||||
|
SONGMAN->GetSongs( vpSongs, ce.sSongGroup );
|
||||||
|
vector<Song*>::const_iterator iter = find( vpSongs.begin(), vpSongs.end(), ce.pSong );
|
||||||
|
int iChoice = 0;
|
||||||
|
if( iter != vpSongs.end() )
|
||||||
|
iChoice = iter - vpSongs.begin() + 1;
|
||||||
OptionRow &row = *m_pRows[ROW_SONG];
|
OptionRow &row = *m_pRows[ROW_SONG];
|
||||||
if( iSongIndex != -1 )
|
row.SetOneSharedSelection( iChoice );
|
||||||
row.SetOneSharedSelection( iSongIndex );
|
|
||||||
}
|
}
|
||||||
/*
|
// import base difficulty
|
||||||
// import entry difficulty
|
|
||||||
{
|
{
|
||||||
int iDifficultyIndex = -1;
|
vector<Difficulty>::const_iterator iter = find( DIFFICULTIES_TO_SHOW.GetValue().begin(), DIFFICULTIES_TO_SHOW.GetValue().end(), ce.baseDifficulty );
|
||||||
vector<Difficulty>::const_iterator iter = find( DIFFICULTIES_TO_SHOW.GetValue().begin(), DIFFICULTIES_TO_SHOW.GetValue().end(), ce.difficulty );
|
int iChoice = 0;
|
||||||
if( iter != DIFFICULTIES_TO_SHOW.GetValue().end() )
|
if( iter != DIFFICULTIES_TO_SHOW.GetValue().end() )
|
||||||
iDifficultyIndex = iter - DIFFICULTIES_TO_SHOW.GetValue().begin();
|
iChoice = iter - DIFFICULTIES_TO_SHOW.GetValue().begin() + 1;
|
||||||
OptionRow &row = *m_pRows[ROW_DIFFICULTY];
|
OptionRow &row = *m_pRows[ROW_BASE_DIFFICULTY];
|
||||||
if( iDifficultyIndex != -1 )
|
row.SetOneSharedSelection( iChoice );
|
||||||
row.SetOneSharedSelection( iDifficultyIndex );
|
}
|
||||||
|
// import low meter
|
||||||
|
{
|
||||||
|
int iChoice = 0;
|
||||||
|
if( ce.iLowMeter != -1 )
|
||||||
|
iChoice = ce.iLowMeter;
|
||||||
|
OptionRow &row = *m_pRows[ROW_LOW_METER];
|
||||||
|
row.SetOneSharedSelection( iChoice );
|
||||||
|
}
|
||||||
|
// import high meter
|
||||||
|
{
|
||||||
|
int iChoice = 0;
|
||||||
|
if( ce.iHighMeter != -1 )
|
||||||
|
iChoice = ce.iHighMeter;
|
||||||
|
OptionRow &row = *m_pRows[ROW_HIGH_METER];
|
||||||
|
row.SetOneSharedSelection( iChoice );
|
||||||
|
}
|
||||||
|
// import sort
|
||||||
|
{
|
||||||
|
int iChoice = ce.songSort;
|
||||||
|
OptionRow &row = *m_pRows[ROW_SORT];
|
||||||
|
row.SetOneSharedSelection( iChoice );
|
||||||
|
}
|
||||||
|
// import choose index
|
||||||
|
{
|
||||||
|
int iChoice = ce.iChooseIndex;
|
||||||
|
OptionRow &row = *m_pRows[ROW_CHOOSE_INDEX];
|
||||||
|
row.SetOneSharedSelection( iChoice );
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEditCourseEntry::ExportOptions( int row, const vector<PlayerNumber> &vpns )
|
void ScreenEditCourseEntry::ExportOptions( int row, const vector<PlayerNumber> &vpns )
|
||||||
@@ -215,7 +310,7 @@ void ScreenEditCourseEntry::GoToNextScreen()
|
|||||||
case ROW_BASE_DIFFICULTY:
|
case ROW_BASE_DIFFICULTY:
|
||||||
case ROW_LOW_METER:
|
case ROW_LOW_METER:
|
||||||
case ROW_HIGH_METER:
|
case ROW_HIGH_METER:
|
||||||
case ROW_BEST_WORST_VALUE:
|
case ROW_CHOOSE_INDEX:
|
||||||
break;
|
break;
|
||||||
case ROW_SET_MODS:
|
case ROW_SET_MODS:
|
||||||
SCREENMAN->SetNewScreen( "ScreenEditCourseMods" );
|
SCREENMAN->SetNewScreen( "ScreenEditCourseMods" );
|
||||||
@@ -228,6 +323,10 @@ void ScreenEditCourseEntry::GoToNextScreen()
|
|||||||
|
|
||||||
void ScreenEditCourseEntry::GoToPrevScreen()
|
void ScreenEditCourseEntry::GoToPrevScreen()
|
||||||
{
|
{
|
||||||
|
// revert
|
||||||
|
Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||||
|
pCourse->m_vEntries[ GAMESTATE->m_iEditCourseEntryIndex ] = m_Original;
|
||||||
|
|
||||||
SCREENMAN->SetNewScreen( "ScreenEditCourse" );
|
SCREENMAN->SetNewScreen( "ScreenEditCourse" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +339,8 @@ void ScreenEditCourseEntry::ProcessMenuStart( PlayerNumber pn, const InputEventT
|
|||||||
case ROW_BASE_DIFFICULTY:
|
case ROW_BASE_DIFFICULTY:
|
||||||
case ROW_LOW_METER:
|
case ROW_LOW_METER:
|
||||||
case ROW_HIGH_METER:
|
case ROW_HIGH_METER:
|
||||||
case ROW_BEST_WORST_VALUE:
|
case ROW_SORT:
|
||||||
|
case ROW_CHOOSE_INDEX:
|
||||||
break;
|
break;
|
||||||
case ROW_SET_MODS:
|
case ROW_SET_MODS:
|
||||||
case ROW_DONE:
|
case ROW_DONE:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define ScreenEditCourseEntry_H
|
#define ScreenEditCourseEntry_H
|
||||||
|
|
||||||
#include "ScreenOptions.h"
|
#include "ScreenOptions.h"
|
||||||
|
#include "Course.h"
|
||||||
|
|
||||||
class ScreenEditCourseEntry : public ScreenOptions
|
class ScreenEditCourseEntry : public ScreenOptions
|
||||||
{
|
{
|
||||||
@@ -13,7 +14,7 @@ public:
|
|||||||
virtual void HandleScreenMessage( const ScreenMessage SM );
|
virtual void HandleScreenMessage( const ScreenMessage SM );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void ImportOptions( int row, const vector<PlayerNumber> &vpns );
|
virtual void ImportOptions( int row, const vector<PlayerNumber> &vpns ) {}
|
||||||
virtual void ExportOptions( int row, const vector<PlayerNumber> &vpns );
|
virtual void ExportOptions( int row, const vector<PlayerNumber> &vpns );
|
||||||
|
|
||||||
virtual void GoToNextScreen();
|
virtual void GoToNextScreen();
|
||||||
@@ -21,6 +22,10 @@ protected:
|
|||||||
|
|
||||||
virtual void AfterChangeValueInRow( PlayerNumber pn );
|
virtual void AfterChangeValueInRow( PlayerNumber pn );
|
||||||
virtual void ProcessMenuStart( PlayerNumber pn, const InputEventType type );
|
virtual void ProcessMenuStart( PlayerNumber pn, const InputEventType type );
|
||||||
|
|
||||||
|
void ImportAllOptions();
|
||||||
|
|
||||||
|
CourseEntry m_Original;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ void ScreenJukebox::SetSong()
|
|||||||
//then we pick a song from this course.
|
//then we pick a song from this course.
|
||||||
Course *pCourse = SONGMAN->GetCourseFromName( THEME->GetCurThemeName() );
|
Course *pCourse = SONGMAN->GetCourseFromName( THEME->GetCurThemeName() );
|
||||||
if( pCourse != NULL )
|
if( pCourse != NULL )
|
||||||
for ( unsigned i = 0; i < pCourse->m_entries.size(); i++ )
|
for ( unsigned i = 0; i < pCourse->m_vEntries.size(); i++ )
|
||||||
vSongs.push_back( pCourse->m_entries[i].pSong );
|
vSongs.push_back( pCourse->m_vEntries[i].pSong );
|
||||||
|
|
||||||
if ( vSongs.size() == 0 )
|
if ( vSongs.size() == 0 )
|
||||||
SONGMAN->GetSongs( vSongs, GAMESTATE->m_sPreferredSongGroup );
|
SONGMAN->GetSongs( vSongs, GAMESTATE->m_sPreferredSongGroup );
|
||||||
|
|||||||
@@ -107,8 +107,10 @@ void AppendOctal( int n, int digits, CString &out )
|
|||||||
|
|
||||||
bool CompDescending( const pair<Song *, CString> &a, const pair<Song *, CString> &b )
|
bool CompDescending( const pair<Song *, CString> &a, const pair<Song *, CString> &b )
|
||||||
{ return a.second > b.second; }
|
{ return a.second > b.second; }
|
||||||
|
bool CompAscending( const pair<Song *, CString> &a, const pair<Song *, CString> &b )
|
||||||
|
{ return a.second < b.second; }
|
||||||
|
|
||||||
void SongUtil::SortSongPointerArrayByGrade( vector<Song*> &vpSongsInOut )
|
void SongUtil::SortSongPointerArrayByGrades( vector<Song*> &vpSongsInOut, bool bDescending )
|
||||||
{
|
{
|
||||||
/* Optimize by pre-writing a string to compare, since doing GetNumNotesWithGrade
|
/* Optimize by pre-writing a string to compare, since doing GetNumNotesWithGrade
|
||||||
* inside the sort is too slow. */
|
* inside the sort is too slow. */
|
||||||
@@ -130,7 +132,7 @@ void SongUtil::SortSongPointerArrayByGrade( vector<Song*> &vpSongsInOut )
|
|||||||
vals.push_back( val(pSong, foo) );
|
vals.push_back( val(pSong, foo) );
|
||||||
}
|
}
|
||||||
|
|
||||||
sort( vals.begin(), vals.end(), CompDescending );
|
sort( vals.begin(), vals.end(), bDescending ? CompDescending : CompAscending );
|
||||||
|
|
||||||
for( unsigned i = 0; i < vpSongsInOut.size(); ++i )
|
for( unsigned i = 0; i < vpSongsInOut.size(); ++i )
|
||||||
vpSongsInOut[i] = vals[i].first;
|
vpSongsInOut[i] = vals[i].first;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace SongUtil
|
|||||||
CString MakeSortString( CString s );
|
CString MakeSortString( CString s );
|
||||||
void SortSongPointerArrayByTitle( vector<Song*> &vpSongsInOut );
|
void SortSongPointerArrayByTitle( vector<Song*> &vpSongsInOut );
|
||||||
void SortSongPointerArrayByBPM( vector<Song*> &vpSongsInOut );
|
void SortSongPointerArrayByBPM( vector<Song*> &vpSongsInOut );
|
||||||
void SortSongPointerArrayByGrade( vector<Song*> &vpSongsInOut );
|
void SortSongPointerArrayByGrades( vector<Song*> &vpSongsInOut, bool bDescending );
|
||||||
void SortSongPointerArrayByArtist( vector<Song*> &vpSongsInOut );
|
void SortSongPointerArrayByArtist( vector<Song*> &vpSongsInOut );
|
||||||
void SortSongPointerArrayByDisplayArtist( vector<Song*> &vpSongsInOut );
|
void SortSongPointerArrayByDisplayArtist( vector<Song*> &vpSongsInOut );
|
||||||
void SortSongPointerArrayByGenre( vector<Song*> &vpSongsInOut );
|
void SortSongPointerArrayByGenre( vector<Song*> &vpSongsInOut );
|
||||||
|
|||||||
Reference in New Issue
Block a user