use SongCriteria and StepsCriteria to resolve songs for Trail
This commit is contained in:
+67
-118
@@ -375,60 +375,39 @@ bool Course::GetTrailSorted( StepsType st, CourseDifficulty cd, Trail &trail ) c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move Course initialization after PROFILEMAN is created
|
// TODO: Move Course initialization after PROFILEMAN is created
|
||||||
static void CourseSortSongs( SongSort sort, vector<Song*> &vpPossibleSongs, RandomGen &rnd )
|
static void CourseSortSongs( SongSort sort, vector<SongAndSteps> &vPossible, RandomGen &rnd )
|
||||||
{
|
{
|
||||||
switch( sort )
|
switch( sort )
|
||||||
{
|
{
|
||||||
default:
|
DEFAULT_FAIL(sort);
|
||||||
ASSERT(0);
|
|
||||||
case SongSort_Randomize:
|
case SongSort_Randomize:
|
||||||
random_shuffle( vpPossibleSongs.begin(), vpPossibleSongs.end(), rnd );
|
random_shuffle( vPossible.begin(), vPossible.end(), rnd );
|
||||||
break;
|
break;
|
||||||
case SongSort_MostPlays:
|
case SongSort_MostPlays:
|
||||||
if( PROFILEMAN )
|
ASSERT(0);
|
||||||
SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), true ); // descending
|
// TODO: fix
|
||||||
|
//if( PROFILEMAN )
|
||||||
|
// SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), true ); // descending
|
||||||
break;
|
break;
|
||||||
case SongSort_FewestPlays:
|
case SongSort_FewestPlays:
|
||||||
if( PROFILEMAN )
|
ASSERT(0);
|
||||||
SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), false ); // ascending
|
// TODO: fix
|
||||||
|
//if( PROFILEMAN )
|
||||||
|
// SongUtil::SortSongPointerArrayByNumPlays( vpPossibleSongs, PROFILEMAN->GetMachineProfile(), false ); // ascending
|
||||||
break;
|
break;
|
||||||
case SongSort_TopGrades:
|
case SongSort_TopGrades:
|
||||||
SongUtil::SortSongPointerArrayByGrades( vpPossibleSongs, true ); // descending
|
ASSERT(0);
|
||||||
|
// TODO: fix
|
||||||
|
//SongUtil::SortSongPointerArrayByGrades( vpPossibleSongs, true ); // descending
|
||||||
break;
|
break;
|
||||||
case SongSort_LowestGrades:
|
case SongSort_LowestGrades:
|
||||||
SongUtil::SortSongPointerArrayByGrades( vpPossibleSongs, false ); // ascending
|
ASSERT(0);
|
||||||
|
// TODO: fix
|
||||||
|
//SongUtil::SortSongPointerArrayByGrades( vpPossibleSongs, false ); // ascending
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetSongsValidForRandom( vector<Song*> &vpSongsOut )
|
|
||||||
{
|
|
||||||
const vector<Song*> &vpAllSongs = SONGMAN->GetAllSongs();
|
|
||||||
|
|
||||||
FOREACH_CONST( Song*, vpAllSongs, song )
|
|
||||||
{
|
|
||||||
// Ignore locked songs when choosing randomly
|
|
||||||
// TODO: Move Course initialization after UNLOCKMAN is created
|
|
||||||
if( UNLOCKMAN && UNLOCKMAN->SongIsLocked(*song) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Ignore boring tutorial songs
|
|
||||||
if( (*song)->IsTutorial() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Don't allow long songs
|
|
||||||
if( SONGMAN->GetNumStagesForSong(*song) > 1 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vpSongsOut.push_back( *song );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool StepsIsLocked( const Song *pSong, const Steps *pSteps )
|
|
||||||
{
|
|
||||||
return UNLOCKMAN->StepsIsLocked( pSong, pSteps );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const
|
bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const
|
||||||
{
|
{
|
||||||
trail.Init();
|
trail.Init();
|
||||||
@@ -469,102 +448,72 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
bool bCourseDifficultyIsSignificant = (cd == DIFFICULTY_MEDIUM);
|
bool bCourseDifficultyIsSignificant = (cd == DIFFICULTY_MEDIUM);
|
||||||
|
|
||||||
vector<Song*> vpAllPossibleSongs;
|
vector<Song*> vpAllPossibleSongs;
|
||||||
bool bHaveAllSongs = false; // true if vpAllPossibleSongs has been generated
|
|
||||||
|
|
||||||
// Resolve each entry to a Song and Steps.
|
// Resolve each entry to a Song and Steps.
|
||||||
FOREACH_CONST( CourseEntry, entries, e )
|
FOREACH_CONST( CourseEntry, entries, e )
|
||||||
{
|
{
|
||||||
Song* pResolvedSong = NULL; // fill this in
|
SongAndSteps resolved = { NULL, NULL }; // fill this in
|
||||||
Steps* pResolvedSteps = NULL; // fill this in
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create a list of matching songs.
|
|
||||||
//
|
|
||||||
|
|
||||||
// Start with all songs
|
|
||||||
vector<Steps*> vpPossibleSteps;
|
|
||||||
|
|
||||||
|
SongCriteria soc = e->songCriteria;
|
||||||
if( e->pSong )
|
if( e->pSong )
|
||||||
{
|
{
|
||||||
if( IsAnEdit() && UNLOCKMAN->SongIsLocked(e->pSong) )
|
soc.m_bUseSongAllowedList = true;
|
||||||
continue;
|
soc.m_vpSongAllowedList.push_back( e->pSong );
|
||||||
// Choose an exact song, if we have matching steps and all
|
|
||||||
SongUtil::GetSteps( e->pSong, vpPossibleSteps, st, e->stepsCriteria.m_difficulty, e->stepsCriteria.m_iLowMeter, e->stepsCriteria.m_iHighMeter );
|
|
||||||
// Remove all locked steps.
|
|
||||||
if( IsAnEdit() )
|
|
||||||
RemoveIf( vpPossibleSteps, bind1st(ptr_fun(StepsIsLocked), e->pSong) );
|
|
||||||
if( !vpPossibleSteps.empty() )
|
|
||||||
pResolvedSong = e->pSong;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
soc.m_Tutorial = SongCriteria::Tutorial_No;
|
||||||
|
soc.m_Locked = SongCriteria::Locked_Unlocked;
|
||||||
|
soc.m_Locked = SongCriteria::Locked_Unlocked;
|
||||||
|
if( !soc.m_bUseSongAllowedList )
|
||||||
|
soc.m_iStagesForSong = 1;
|
||||||
|
|
||||||
|
StepsCriteria stc = e->stepsCriteria;
|
||||||
|
stc.m_st = st;
|
||||||
|
stc.m_Locked = StepsCriteria::Locked_Unlocked;
|
||||||
|
|
||||||
|
vector<SongAndSteps> vSongAndSteps;
|
||||||
|
StepsUtil::GetAllMatching( soc, stc, vSongAndSteps );
|
||||||
|
|
||||||
|
// It looks bad to have the same song 2x in a row in a randomly generated course.
|
||||||
|
// Don't allow the same song to be played 2x in a row, unless there's only
|
||||||
|
// one song in vpPossibleSongs.
|
||||||
|
if( trail.m_vEntries.size() > 0 && vSongAndSteps.size() > 1 )
|
||||||
{
|
{
|
||||||
/* Generate vpAllPossibleSongs, if we havn't yet. */
|
const TrailEntry &teLast = trail.m_vEntries[trail.m_vEntries.size()-1];
|
||||||
if( !bHaveAllSongs )
|
bool bExistsDifferentSongThanLast = false;
|
||||||
|
FOREACH_CONST( SongAndSteps, vSongAndSteps, sas )
|
||||||
{
|
{
|
||||||
GetSongsValidForRandom( vpAllPossibleSongs );
|
if( sas->pSong != teLast.pSong )
|
||||||
bHaveAllSongs = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy over any songs that match our group filter, if one is set, and match our
|
|
||||||
// steps filter.
|
|
||||||
vector<Song*> vpPossibleSongs;
|
|
||||||
FOREACH( Song*, vpAllPossibleSongs, song )
|
|
||||||
{
|
|
||||||
if( !e->songCriteria.Matches( *song ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vector<Steps*> vpMatchingSteps;
|
|
||||||
SongUtil::GetSteps( *song, vpMatchingSteps, st, e->stepsCriteria.m_difficulty, e->stepsCriteria.m_iLowMeter, e->stepsCriteria.m_iHighMeter );
|
|
||||||
StepsUtil::RemoveLockedSteps( *song, vpMatchingSteps );
|
|
||||||
|
|
||||||
if( vpMatchingSteps.empty() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vpPossibleSongs.push_back( *song );
|
|
||||||
}
|
|
||||||
|
|
||||||
// It looks bad to have the same song 2x in a row in a randomly generated course.
|
|
||||||
// Don't allow the same song to be played 2x in a row, unless there's only
|
|
||||||
// one song in vpPossibleSongs.
|
|
||||||
if( trail.m_vEntries.size() > 0 && vpPossibleSongs.size() > 1 )
|
|
||||||
{
|
|
||||||
const TrailEntry &teLast = trail.m_vEntries[trail.m_vEntries.size()-1];
|
|
||||||
for( int i=vpPossibleSongs.size()-1; i>=0; i-- )
|
|
||||||
{
|
{
|
||||||
if( vpPossibleSongs[i] == teLast.pSong )
|
bExistsDifferentSongThanLast = true;
|
||||||
vpPossibleSongs.erase( vpPossibleSongs.begin()+i );
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there are no songs to choose from, abort now
|
for( int i=vSongAndSteps.size()-1; i>=0; i-- )
|
||||||
if( vpPossibleSongs.empty() )
|
{
|
||||||
continue;
|
if( vSongAndSteps[i].pSong == teLast.pSong )
|
||||||
|
vSongAndSteps.erase( vSongAndSteps.begin()+i );
|
||||||
CourseSortSongs( e->songSort, vpPossibleSongs, rnd );
|
}
|
||||||
|
|
||||||
ASSERT( e->iChooseIndex >= 0 );
|
|
||||||
if( e->iChooseIndex < int(vpPossibleSongs.size()) )
|
|
||||||
pResolvedSong = vpPossibleSongs[e->iChooseIndex];
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
SongUtil::GetSteps( pResolvedSong, vpPossibleSteps, st, e->stepsCriteria.m_difficulty, e->stepsCriteria.m_iLowMeter, e->stepsCriteria.m_iHighMeter );
|
|
||||||
StepsUtil::RemoveLockedSteps( pResolvedSong, vpPossibleSteps );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT( !vpPossibleSteps.empty() ); // if no steps are playable, this shouldn't be a possible song
|
// if there are no songs to choose from, abort this CourseEntry
|
||||||
random_shuffle( vpPossibleSteps.begin(), vpPossibleSteps.end(), rnd );
|
if( vSongAndSteps.empty() )
|
||||||
pResolvedSteps = vpPossibleSteps[0];
|
continue;
|
||||||
|
|
||||||
if( pResolvedSong == NULL || pResolvedSteps == NULL )
|
|
||||||
continue; // this song entry isn't playable. Skip.
|
|
||||||
|
|
||||||
|
// TODO: fixme
|
||||||
|
CourseSortSongs( e->songSort, vSongAndSteps, rnd );
|
||||||
|
|
||||||
|
ASSERT( e->iChooseIndex >= 0 );
|
||||||
|
if( e->iChooseIndex < int(vSongAndSteps.size()) )
|
||||||
|
resolved = vSongAndSteps[e->iChooseIndex];
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
/* If we're not COURSE_DIFFICULTY_REGULAR, then we should be choosing steps that are
|
/* If we're not COURSE_DIFFICULTY_REGULAR, then we should be choosing steps that are
|
||||||
* either easier or harder than the base difficulty. If no such steps exist, then
|
* either easier or harder than the base difficulty. If no such steps exist, then
|
||||||
* just use the one we already have. */
|
* just use the one we already have. */
|
||||||
Difficulty dc = pResolvedSteps->GetDifficulty();
|
Difficulty dc = resolved.pSteps->GetDifficulty();
|
||||||
int iLowMeter = e->stepsCriteria.m_iLowMeter;
|
int iLowMeter = e->stepsCriteria.m_iLowMeter;
|
||||||
int iHighMeter = e->stepsCriteria.m_iHighMeter;
|
int iHighMeter = e->stepsCriteria.m_iHighMeter;
|
||||||
if( cd != DIFFICULTY_MEDIUM && !e->bNoDifficult )
|
if( cd != DIFFICULTY_MEDIUM && !e->bNoDifficult )
|
||||||
@@ -575,11 +524,11 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
bool bChangedDifficulty = false;
|
bool bChangedDifficulty = false;
|
||||||
if( new_dc != dc )
|
if( new_dc != dc )
|
||||||
{
|
{
|
||||||
Steps* pNewSteps = SongUtil::GetStepsByDifficulty( pResolvedSong, st, new_dc );
|
Steps* pNewSteps = SongUtil::GetStepsByDifficulty( resolved.pSong, st, new_dc );
|
||||||
if( pNewSteps )
|
if( pNewSteps )
|
||||||
{
|
{
|
||||||
dc = new_dc;
|
dc = new_dc;
|
||||||
pResolvedSteps = pNewSteps;
|
resolved.pSteps = pNewSteps;
|
||||||
bChangedDifficulty = true;
|
bChangedDifficulty = true;
|
||||||
bCourseDifficultyIsSignificant = true;
|
bCourseDifficultyIsSignificant = true;
|
||||||
}
|
}
|
||||||
@@ -596,8 +545,8 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
{
|
{
|
||||||
/* Minimum and maximum to add to make the meter range contain the actual
|
/* Minimum and maximum to add to make the meter range contain the actual
|
||||||
* meter: */
|
* meter: */
|
||||||
int iMinDist = pResolvedSteps->GetMeter() - iHighMeter;
|
int iMinDist = resolved.pSteps->GetMeter() - iHighMeter;
|
||||||
int iMaxDist = pResolvedSteps->GetMeter() - iLowMeter;
|
int iMaxDist = resolved.pSteps->GetMeter() - iLowMeter;
|
||||||
|
|
||||||
/* Clamp the possible adjustments to try to avoid going under 1 or over
|
/* Clamp the possible adjustments to try to avoid going under 1 or over
|
||||||
* MAX_BOTTOM_RANGE. */
|
* MAX_BOTTOM_RANGE. */
|
||||||
@@ -615,8 +564,8 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
}
|
}
|
||||||
|
|
||||||
TrailEntry te;
|
TrailEntry te;
|
||||||
te.pSong = pResolvedSong;
|
te.pSong = resolved.pSong;
|
||||||
te.pSteps = pResolvedSteps;
|
te.pSteps = resolved.pSteps;
|
||||||
te.Modifiers = e->sModifiers;
|
te.Modifiers = e->sModifiers;
|
||||||
te.Attacks = e->attacks;
|
te.Attacks = e->attacks;
|
||||||
te.bSecret = e->bSecret;
|
te.bSecret = e->bSecret;
|
||||||
|
|||||||
@@ -15,12 +15,62 @@
|
|||||||
#include "LocalizedString.h"
|
#include "LocalizedString.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
|
|
||||||
bool SongCriteria::Matches( const Song *p ) const
|
bool SongCriteria::Matches( const Song *pSong ) const
|
||||||
{
|
{
|
||||||
if( !m_sGroupName.empty() && m_sGroupName != p->m_sGroupName )
|
if( !m_sGroupName.empty() && m_sGroupName != pSong->m_sGroupName )
|
||||||
return false;
|
return false;
|
||||||
if( !m_sGenre.empty() && m_sGenre != p->m_sGenre )
|
if( !m_sGenre.empty() && m_sGenre != pSong->m_sGenre )
|
||||||
return false;
|
return false;
|
||||||
|
switch( m_Selectable )
|
||||||
|
{
|
||||||
|
DEFAULT_FAIL(m_Selectable);
|
||||||
|
case Selectable_Yes:
|
||||||
|
if( pSong->m_SelectionDisplay != Song::SHOW_ALWAYS )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Selectable_No:
|
||||||
|
if( pSong->m_SelectionDisplay != Song::SHOW_NEVER )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Selectable_DontCare:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( m_bUseSongAllowedList )
|
||||||
|
{
|
||||||
|
if( find(m_vpSongAllowedList.begin(),m_vpSongAllowedList.end(),pSong) == m_vpSongAllowedList.end() )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if( m_iStagesForSong != -1 && SONGMAN->GetNumStagesForSong(pSong) != m_iStagesForSong )
|
||||||
|
return false;
|
||||||
|
switch( m_Tutorial )
|
||||||
|
{
|
||||||
|
DEFAULT_FAIL(m_Tutorial);
|
||||||
|
case Tutorial_Yes:
|
||||||
|
if( !pSong->IsTutorial() )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Tutorial_No:
|
||||||
|
if( pSong->IsTutorial() )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Tutorial_DontCare:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch( m_Locked )
|
||||||
|
{
|
||||||
|
DEFAULT_FAIL(m_Locked);
|
||||||
|
case Locked_Locked:
|
||||||
|
if( UNLOCKMAN && !UNLOCKMAN->SongIsLocked(pSong) )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Locked_Unlocked:
|
||||||
|
if( UNLOCKMAN && UNLOCKMAN->SongIsLocked(pSong) )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Locked_DontCare:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,6 +786,17 @@ void SongUtil::GetAllSongGenres( vector<RString> &vsOut )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SongUtil::FilterSongs( const SongCriteria &sc, const vector<Song*> &in, vector<Song*> &out )
|
||||||
|
{
|
||||||
|
FOREACH_CONST( Song*, in, s )
|
||||||
|
{
|
||||||
|
if( sc.Matches( *s ) )
|
||||||
|
{
|
||||||
|
out.push_back( *s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// SongID
|
// SongID
|
||||||
|
|||||||
@@ -11,17 +11,27 @@ class Steps;
|
|||||||
class Profile;
|
class Profile;
|
||||||
class XNode;
|
class XNode;
|
||||||
|
|
||||||
|
|
||||||
class SongCriteria
|
class SongCriteria
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RString m_sGroupName; // "" means don't match
|
RString m_sGroupName; // "" means don't match
|
||||||
RString m_sGenre; // "" means don't match
|
RString m_sGenre; // "" means don't match
|
||||||
|
enum Selectable { Selectable_Yes, Selectable_No, Selectable_DontCare } m_Selectable;
|
||||||
|
bool m_bUseSongAllowedList;
|
||||||
|
vector<Song*> m_vpSongAllowedList;
|
||||||
|
int m_iStagesForSong; // don't filter if -1
|
||||||
|
enum Tutorial { Tutorial_Yes, Tutorial_No, Tutorial_DontCare } m_Tutorial;
|
||||||
|
enum Locked { Locked_Locked, Locked_Unlocked, Locked_DontCare } m_Locked;
|
||||||
|
|
||||||
SongCriteria()
|
SongCriteria()
|
||||||
{
|
{
|
||||||
|
m_Selectable = Selectable_DontCare;
|
||||||
|
m_bUseSongAllowedList = false;
|
||||||
|
m_iStagesForSong = -1;
|
||||||
|
m_Tutorial = Tutorial_DontCare;
|
||||||
|
m_Locked = Locked_DontCare;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Matches( const Song *p ) const;
|
bool Matches( const Song *p ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,6 +106,10 @@ public:
|
|||||||
{
|
{
|
||||||
return sDir < other.sDir;
|
return sDir < other.sDir;
|
||||||
}
|
}
|
||||||
|
bool operator==( const SongID &other ) const
|
||||||
|
{
|
||||||
|
return sDir == other.sDir;
|
||||||
|
}
|
||||||
|
|
||||||
XNode* CreateNode() const;
|
XNode* CreateNode() const;
|
||||||
void LoadFromNode( const XNode* pNode );
|
void LoadFromNode( const XNode* pNode );
|
||||||
|
|||||||
@@ -11,14 +11,31 @@
|
|||||||
#include "SongUtil.h"
|
#include "SongUtil.h"
|
||||||
|
|
||||||
|
|
||||||
bool StepsCriteria::Matches( const Steps *p ) const
|
bool StepsCriteria::Matches( const Song *pSong, const Steps *pSteps ) const
|
||||||
{
|
{
|
||||||
if( m_difficulty != DIFFICULTY_INVALID && p->GetDifficulty() != m_difficulty )
|
if( m_difficulty != DIFFICULTY_INVALID && pSteps->GetDifficulty() != m_difficulty )
|
||||||
return false;
|
return false;
|
||||||
if( m_iLowMeter != -1 && p->GetMeter() < m_iLowMeter )
|
if( m_iLowMeter != -1 && pSteps->GetMeter() < m_iLowMeter )
|
||||||
return false;
|
return false;
|
||||||
if( m_iHighMeter != -1 && p->GetMeter() > m_iHighMeter )
|
if( m_iHighMeter != -1 && pSteps->GetMeter() > m_iHighMeter )
|
||||||
return false;
|
return false;
|
||||||
|
if( m_st != STEPS_TYPE_INVALID && pSteps->m_StepsType != m_st )
|
||||||
|
return false;
|
||||||
|
switch( m_Locked )
|
||||||
|
{
|
||||||
|
DEFAULT_FAIL(m_Locked);
|
||||||
|
case Locked_Locked:
|
||||||
|
if( UNLOCKMAN && !UNLOCKMAN->StepsIsLocked(pSong,pSteps) )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Locked_Unlocked:
|
||||||
|
if( UNLOCKMAN && UNLOCKMAN->StepsIsLocked(pSong,pSteps) )
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case Locked_DontCare:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,9 +47,10 @@ void StepsUtil::GetAllMatching( const SongCriteria &soc, const StepsCriteria &st
|
|||||||
continue;
|
continue;
|
||||||
FOREACH_CONST( Steps*, (*so)->GetAllSteps(), st )
|
FOREACH_CONST( Steps*, (*so)->GetAllSteps(), st )
|
||||||
{
|
{
|
||||||
if( !stc.Matches(*st) )
|
if( !stc.Matches(*so,*st) )
|
||||||
continue;
|
continue;
|
||||||
|
SongAndSteps sas = { *so, *st };
|
||||||
|
out.push_back( sas );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,19 @@ public:
|
|||||||
Difficulty m_difficulty; // don't filter if DIFFICULTY_INVALID
|
Difficulty m_difficulty; // don't filter if DIFFICULTY_INVALID
|
||||||
int m_iLowMeter; // don't filter if -1
|
int m_iLowMeter; // don't filter if -1
|
||||||
int m_iHighMeter; // don't filter if -1
|
int m_iHighMeter; // don't filter if -1
|
||||||
|
StepsType m_st; // don't filter if STEPS_TYPE_INVALID
|
||||||
|
enum Locked { Locked_Locked, Locked_Unlocked, Locked_DontCare } m_Locked;
|
||||||
|
|
||||||
StepsCriteria()
|
StepsCriteria()
|
||||||
{
|
{
|
||||||
m_difficulty = DIFFICULTY_INVALID;
|
m_difficulty = DIFFICULTY_INVALID;
|
||||||
m_iLowMeter = -1;
|
m_iLowMeter = -1;
|
||||||
m_iHighMeter = -1;
|
m_iHighMeter = -1;
|
||||||
|
m_st = STEPS_TYPE_INVALID;
|
||||||
|
m_Locked = Locked_DontCare;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Matches( const Steps *p ) const;
|
bool Matches( const Song *pSong, const Steps *pSteps ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SongAndSteps
|
class SongAndSteps
|
||||||
@@ -38,7 +42,6 @@ public:
|
|||||||
|
|
||||||
namespace StepsUtil
|
namespace StepsUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
void GetAllMatching( const SongCriteria &soc, const StepsCriteria &stc, vector<SongAndSteps> &out ); // look up in SONGMAN
|
void GetAllMatching( const SongCriteria &soc, const StepsCriteria &stc, vector<SongAndSteps> &out ); // look up in SONGMAN
|
||||||
|
|
||||||
bool CompareNotesPointersByRadarValues(const Steps* pSteps1, const Steps* pSteps2);
|
bool CompareNotesPointersByRadarValues(const Steps* pSteps1, const Steps* pSteps2);
|
||||||
|
|||||||
Reference in New Issue
Block a user