Allow combined player steps to have per-player radar values. This doesn't work for trails where it just uses the PLAYER_1 values, same with writing to the catalog file.

This commit is contained in:
Steve Checkoway
2006-07-28 03:34:14 +00:00
parent 1b1f2a9790
commit 884af552ee
16 changed files with 70 additions and 55 deletions
+1 -1
View File
@@ -206,7 +206,7 @@ void CatalogXml::Save( LoadingWindow *loading_window )
pSongNode->AppendChild( pStepsIDNode ); pSongNode->AppendChild( pStepsIDNode );
pStepsIDNode->AppendChild( "Meter", pSteps->GetMeter() ); pStepsIDNode->AppendChild( "Meter", pSteps->GetMeter() );
pStepsIDNode->AppendChild( pSteps->GetRadarValues().CreateNode() ); pStepsIDNode->AppendChild( pSteps->GetRadarValues(PLAYER_1).CreateNode() );
} }
} }
} }
+2 -10
View File
@@ -1129,17 +1129,9 @@ bool GameState::IsDisqualified( PlayerNumber pn )
// Check the stored player options for disqualify. Don't disqualify because // Check the stored player options for disqualify. Don't disqualify because
// of mods that were forced. // of mods that were forced.
if( GAMESTATE->IsCourseMode() ) if( GAMESTATE->IsCourseMode() )
{ return po.IsEasierForCourseAndTrail( GAMESTATE->m_pCurCourse, GAMESTATE->m_pCurTrail[pn] );
return po.IsEasierForCourseAndTrail(
GAMESTATE->m_pCurCourse,
GAMESTATE->m_pCurTrail[pn] );
}
else else
{ return po.IsEasierForSongAndSteps( GAMESTATE->m_pCurSong, GAMESTATE->m_pCurSteps[pn], pn);
return po.IsEasierForSongAndSteps(
GAMESTATE->m_pCurSong,
GAMESTATE->m_pCurSteps[pn] );
}
} }
void GameState::GetAllUsedNoteSkins( vector<RString> &out ) const void GameState::GetAllUsedNoteSkins( vector<RString> &out ) const
+2 -2
View File
@@ -92,7 +92,7 @@ GrooveRadar::GrooveRadarValueMap::GrooveRadarValueMap()
} }
} }
void GrooveRadar::GrooveRadarValueMap::SetFromSteps( const Steps* pSteps ) // NULL means no song void GrooveRadar::GrooveRadarValueMap::SetFromSteps( PlayerNumber pn, const Steps* pSteps ) // NULL means no song
{ {
if( pSteps != NULL ) if( pSteps != NULL )
{ {
@@ -100,7 +100,7 @@ void GrooveRadar::GrooveRadarValueMap::SetFromSteps( const Steps* pSteps ) // N
{ {
const float fValueCurrent = m_fValuesOld[c] * (1-m_PercentTowardNew) + m_fValuesNew[c] * m_PercentTowardNew; const float fValueCurrent = m_fValuesOld[c] * (1-m_PercentTowardNew) + m_fValuesNew[c] * m_PercentTowardNew;
m_fValuesOld[c] = fValueCurrent; m_fValuesOld[c] = fValueCurrent;
m_fValuesNew[c] = pSteps->GetRadarValues()[c]; m_fValuesNew[c] = pSteps->GetRadarValues( pn )[c];
} }
if( !m_bValuesVisible ) // the values WERE invisible if( !m_bValuesVisible ) // the values WERE invisible
+2 -2
View File
@@ -22,7 +22,7 @@ public:
void SetFromSteps( PlayerNumber pn, Steps* pSteps ) // NULL means no Song void SetFromSteps( PlayerNumber pn, Steps* pSteps ) // NULL means no Song
{ {
m_GrooveRadarValueMap[pn].SetFromSteps( pSteps ); m_GrooveRadarValueMap[pn].SetFromSteps( pn, pSteps );
} }
void TweenOnScreen(); void TweenOnScreen();
@@ -39,7 +39,7 @@ protected:
virtual void Update( float fDeltaTime ); virtual void Update( float fDeltaTime );
virtual void DrawPrimitives(); virtual void DrawPrimitives();
void SetFromSteps( const Steps* pSteps ); // NULL means no Song void SetFromSteps( PlayerNumber pn, const Steps* pSteps ); // NULL means no Song
void SetRadius( float f ) { m_size.x = f; m_size.y = f; } void SetRadius( float f ) { m_size.x = f; m_size.y = f; }
+6 -5
View File
@@ -49,12 +49,13 @@ void SMLoader::LoadFromSMTokens(
out.SetMeter( atoi(sMeter) ); out.SetMeter( atoi(sMeter) );
vector<RString> saValues; vector<RString> saValues;
split( sRadarValues, ",", saValues, true ); split( sRadarValues, ",", saValues, true );
if( saValues.size() == NUM_RadarCategory ) if( saValues.size() == NUM_RadarCategory * NUM_PLAYERS )
{ {
RadarValues v; RadarValues v[NUM_PLAYERS];
FOREACH_RadarCategory( rc ) FOREACH_PlayerNumber( pn )
v[rc] = StringToFloat( saValues[rc] ); FOREACH_RadarCategory( rc )
out.SetCachedRadarValues( v ); v[pn][rc] = StringToFloat( saValues[pn*NUM_RadarCategory + rc] );
out.SetCachedRadarValues( v );
} }
out.SetSMNoteData( sNoteData ); out.SetSMNoteData( sNoteData );
+6 -2
View File
@@ -171,8 +171,12 @@ RString NotesWriterSM::GetSMNotesTag( const Song &song, const Steps &in, bool bS
lines.push_back( ssprintf( " %d:", in.GetMeter() ) ); lines.push_back( ssprintf( " %d:", in.GetMeter() ) );
vector<RString> asRadarValues; vector<RString> asRadarValues;
for( int r=0; r < NUM_RadarCategory; r++ ) FOREACH_PlayerNumber( pn )
asRadarValues.push_back( ssprintf("%.3f", in.GetRadarValues()[r]) ); {
const RadarValues &rv = in.GetRadarValues( pn );
FOREACH_RadarCategory( rc )
asRadarValues.push_back( ssprintf("%.3f", rv[rc]) );
}
/* Don't append a newline here; it's added in NoteDataUtil::GetSMNoteDataString. /* Don't append a newline here; it's added in NoteDataUtil::GetSMNoteDataString.
* If we add it here, then every time we write unmodified data we'll add an extra * If we add it here, then every time we write unmodified data we'll add an extra
* newline and they'll accumulate. */ * newline and they'll accumulate. */
+1 -1
View File
@@ -145,7 +145,7 @@ void PaneDisplay::SetContent( PaneContents c )
RadarValues rv; RadarValues rv;
if( g_Contents[c].req&NEED_NOTES ) if( g_Contents[c].req&NEED_NOTES )
rv = pSteps->GetRadarValues(); rv = pSteps->GetRadarValues( m_PlayerNumber );
else if( g_Contents[c].req&NEED_COURSE ) else if( g_Contents[c].req&NEED_COURSE )
rv = pTrail->GetRadarValues(); rv = pTrail->GetRadarValues();
+9 -8
View File
@@ -588,21 +588,22 @@ bool PlayerOptions::operator==( const PlayerOptions &other ) const
return true; return true;
} }
bool PlayerOptions::IsEasierForSongAndSteps( Song* pSong, Steps* pSteps ) const bool PlayerOptions::IsEasierForSongAndSteps( Song* pSong, Steps* pSteps, PlayerNumber pn ) const
{ {
if( m_fTimeSpacing && pSong->HasSignificantBpmChangesOrStops() ) if( m_fTimeSpacing && pSong->HasSignificantBpmChangesOrStops() )
return true; return true;
if( m_bTransforms[TRANSFORM_NOHOLDS] && pSteps->GetRadarValues()[RadarCategory_Holds]>0 ) const RadarValues &rv = pSteps->GetRadarValues( pn );
if( m_bTransforms[TRANSFORM_NOHOLDS] && rv[RadarCategory_Holds]>0 )
return true; return true;
if( m_bTransforms[TRANSFORM_NOROLLS] && pSteps->GetRadarValues()[RadarCategory_Rolls]>0 ) if( m_bTransforms[TRANSFORM_NOROLLS] && rv[RadarCategory_Rolls]>0 )
return true; return true;
if( m_bTransforms[TRANSFORM_NOMINES] && pSteps->GetRadarValues()[RadarCategory_Mines]>0 ) if( m_bTransforms[TRANSFORM_NOMINES] && rv[RadarCategory_Mines]>0 )
return true; return true;
if( m_bTransforms[TRANSFORM_NOHANDS] && pSteps->GetRadarValues()[RadarCategory_Hands]>0 ) if( m_bTransforms[TRANSFORM_NOHANDS] && rv[RadarCategory_Hands]>0 )
return true; return true;
if( m_bTransforms[TRANSFORM_NOQUADS] && pSteps->GetRadarValues()[RadarCategory_Hands]>0 ) if( m_bTransforms[TRANSFORM_NOQUADS] && rv[RadarCategory_Hands]>0 )
return true; return true;
if( m_bTransforms[TRANSFORM_NOJUMPS] && pSteps->GetRadarValues()[RadarCategory_Jumps]>0 ) if( m_bTransforms[TRANSFORM_NOJUMPS] && rv[RadarCategory_Jumps]>0 )
return true; return true;
if( m_bTransforms[TRANSFORM_NOSTRETCH] ) if( m_bTransforms[TRANSFORM_NOSTRETCH] )
return true; return true;
@@ -628,7 +629,7 @@ bool PlayerOptions::IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail )
FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e )
{ {
if( e->pSong && IsEasierForSongAndSteps(e->pSong, e->pSteps) ) if( e->pSong && IsEasierForSongAndSteps(e->pSong, e->pSteps, PLAYER_1) )
return true; return true;
} }
return false; return false;
+1 -1
View File
@@ -158,7 +158,7 @@ public:
// return true if any mods being used will make the song(s) easier // return true if any mods being used will make the song(s) easier
bool IsEasierForSongAndSteps( Song* pSong, Steps* pSteps ) const; bool IsEasierForSongAndSteps( Song* pSong, Steps* pSteps, PlayerNumber pn ) const;
bool IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail ) const; bool IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail ) const;
}; };
+1 -1
View File
@@ -279,7 +279,7 @@ int PlayerStageStats::GetLessonScoreNeeded() const
float fScore = 0; float fScore = 0;
FOREACH_CONST( Steps*, vpPossibleSteps, steps ) FOREACH_CONST( Steps*, vpPossibleSteps, steps )
fScore += (*steps)->GetRadarValues().m_Values.v.fNumTapsAndHolds; fScore += (*steps)->GetRadarValues( PLAYER_1 ).m_Values.v.fNumTapsAndHolds;
return lrintf( fScore * LESSON_PASS_THRESHOLD ); return lrintf( fScore * LESSON_PASS_THRESHOLD );
} }
+1 -1
View File
@@ -34,7 +34,7 @@
#include <set> #include <set>
#include <float.h> #include <float.h>
const int FILE_CACHE_VERSION = 147; // increment this to invalidate cache const int FILE_CACHE_VERSION = 148; // increment this to invalidate cache
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
+1 -1
View File
@@ -657,7 +657,7 @@ void SongUtil::SortSongPointerArrayByMeter( vector<Song*> &vpSongsInOut, Difficu
s += ssprintf( "%c", (pSteps? pSteps->GetDifficulty():0) + '0' ); s += ssprintf( "%c", (pSteps? pSteps->GetDifficulty():0) + '0' );
if( PREFSMAN->m_bSubSortByNumSteps ) if( PREFSMAN->m_bSubSortByNumSteps )
s += ssprintf("%06.0f",pSteps ? pSteps->GetRadarValues()[RadarCategory_TapsAndHolds] : 0); s += ssprintf("%06.0f",pSteps ? pSteps->GetRadarValues(PLAYER_1)[RadarCategory_TapsAndHolds] : 0);
} }
stable_sort( vpSongsInOut.begin(), vpSongsInOut.end(), CompareSongPointersBySortValueAscending ); stable_sort( vpSongsInOut.begin(), vpSongsInOut.end(), CompareSongPointersBySortValueAscending );
} }
+31 -14
View File
@@ -24,6 +24,8 @@
#include "NoteDataUtil.h" #include "NoteDataUtil.h"
#include "NotesLoaderSM.h" #include "NotesLoaderSM.h"
#include <algorithm>
Steps::Steps() Steps::Steps()
{ {
m_bSavedToDisk = false; m_bSavedToDisk = false;
@@ -109,8 +111,9 @@ float Steps::PredictMeter() const
10.1f, 5.27f,-0.905f, -1.10f, 2.86f, 10.1f, 5.27f,-0.905f, -1.10f, 2.86f,
0,0,0,0,0,0 0,0,0,0,0,0
}; };
const RadarValues &rv = GetRadarValues( PLAYER_1 );
for( int r = 0; r < NUM_RadarCategory; ++r ) for( int r = 0; r < NUM_RadarCategory; ++r )
pMeter += this->GetRadarValues()[r] * RadarCoeffs[r]; pMeter += rv[r] * RadarCoeffs[r];
const float DifficultyCoeffs[NUM_Difficulty] = const float DifficultyCoeffs[NUM_Difficulty] =
{ {
@@ -119,8 +122,8 @@ float Steps::PredictMeter() const
pMeter += DifficultyCoeffs[this->GetDifficulty()]; pMeter += DifficultyCoeffs[this->GetDifficulty()];
// Init non-radar values // Init non-radar values
const float SV = this->GetRadarValues()[RadarCategory_Stream] * this->GetRadarValues()[RadarCategory_Voltage]; const float SV = rv[RadarCategory_Stream] * rv[RadarCategory_Voltage];
const float ChaosSquare = this->GetRadarValues()[RadarCategory_Chaos] * this->GetRadarValues()[RadarCategory_Chaos]; const float ChaosSquare = rv[RadarCategory_Chaos] * rv[RadarCategory_Chaos];
pMeter += -6.35f * SV; pMeter += -6.35f * SV;
pMeter += -2.58f * ChaosSquare; pMeter += -2.58f * ChaosSquare;
if (pMeter < 1) pMeter = 1; if (pMeter < 1) pMeter = 1;
@@ -146,12 +149,10 @@ void Steps::TidyUpData()
void Steps::CalculateRadarValues( float fMusicLengthSeconds ) void Steps::CalculateRadarValues( float fMusicLengthSeconds )
{ {
m_CachedRadarValues = RadarValues();
// If we're autogen, don't calculate values. GetRadarValues will take from our parent. // If we're autogen, don't calculate values. GetRadarValues will take from our parent.
if( parent != NULL ) if( parent != NULL )
return; return;
// Do write radar values, and leave it up to the reading app whether they want to trust // Do write radar values, and leave it up to the reading app whether they want to trust
// the cached values without recalculating them. // the cached values without recalculating them.
/* /*
@@ -162,7 +163,23 @@ void Steps::CalculateRadarValues( float fMusicLengthSeconds )
NoteData tempNoteData; NoteData tempNoteData;
this->GetNoteData( tempNoteData ); this->GetNoteData( tempNoteData );
NoteDataUtil::CalculateRadarValues( tempNoteData, fMusicLengthSeconds, m_CachedRadarValues );
FOREACH_PlayerNumber( pn )
m_CachedRadarValues[pn].Zero();
if( tempNoteData.IsComposite() )
{
vector<NoteData> vParts;
NoteDataUtil::SplitCompositeNoteData( tempNoteData, vParts );
for( size_t pn = 0; pn < min(vParts.size(), size_t(NUM_PLAYERS)); ++pn )
NoteDataUtil::CalculateRadarValues( vParts[pn], fMusicLengthSeconds, m_CachedRadarValues[pn] );
}
else
{
NoteDataUtil::CalculateRadarValues( tempNoteData, fMusicLengthSeconds, m_CachedRadarValues[0] );
fill_n( m_CachedRadarValues + 1, NUM_PLAYERS-1, m_CachedRadarValues[0] );
}
} }
void Steps::Decompress() const void Steps::Decompress() const
@@ -170,7 +187,7 @@ void Steps::Decompress() const
if( m_bNoteDataIsFilled ) if( m_bNoteDataIsFilled )
return; // already decompressed return; // already decompressed
if(parent) if( parent )
{ {
// get autogen m_pNoteData // get autogen m_pNoteData
NoteData notedata; NoteData notedata;
@@ -238,7 +255,7 @@ void Steps::Compress() const
/* Always leave lights data uncompressed. */ /* Always leave lights data uncompressed. */
if( this->m_StepsType == STEPS_TYPE_LIGHTS_CABINET && m_bNoteDataIsFilled ) if( this->m_StepsType == STEPS_TYPE_LIGHTS_CABINET && m_bNoteDataIsFilled )
{ {
m_sNoteDataCompressed = RString(""); m_sNoteDataCompressed = EMPTY_STRING;
return; return;
} }
@@ -257,7 +274,7 @@ void Steps::Compress() const
/* Be careful; 'x = ""', m_sNoteDataCompressed.clear() and m_sNoteDataCompressed.reserve(0) /* Be careful; 'x = ""', m_sNoteDataCompressed.clear() and m_sNoteDataCompressed.reserve(0)
* don't always free the allocated memory. */ * don't always free the allocated memory. */
m_sNoteDataCompressed = RString(""); m_sNoteDataCompressed = EMPTY_STRING;
return; return;
} }
@@ -277,7 +294,7 @@ void Steps::Compress() const
* to normal. (needed?) */ * to normal. (needed?) */
void Steps::DeAutogen() void Steps::DeAutogen()
{ {
if(!parent) if( !parent )
return; /* OK */ return; /* OK */
Decompress(); // fills in m_pNoteData with sliding window transform Decompress(); // fills in m_pNoteData with sliding window transform
@@ -285,7 +302,7 @@ void Steps::DeAutogen()
m_sDescription = Real()->m_sDescription; m_sDescription = Real()->m_sDescription;
m_Difficulty = Real()->m_Difficulty; m_Difficulty = Real()->m_Difficulty;
m_iMeter = Real()->m_iMeter; m_iMeter = Real()->m_iMeter;
m_CachedRadarValues = Real()->m_CachedRadarValues; copy( Real()->m_CachedRadarValues, Real()->m_CachedRadarValues + NUM_PLAYERS, m_CachedRadarValues );
parent = NULL; parent = NULL;
@@ -357,10 +374,10 @@ void Steps::SetMeter(int meter)
m_iMeter = meter; m_iMeter = meter;
} }
void Steps::SetCachedRadarValues( const RadarValues& v ) void Steps::SetCachedRadarValues( const RadarValues v[NUM_PLAYERS] )
{ {
DeAutogen(); DeAutogen();
m_CachedRadarValues = v; copy( v, v + NUM_PLAYERS, m_CachedRadarValues );
} }
+3 -3
View File
@@ -39,7 +39,7 @@ public:
RString GetDescription() const { return Real()->m_sDescription; } RString GetDescription() const { return Real()->m_sDescription; }
Difficulty GetDifficulty() const { return Real()->m_Difficulty; } Difficulty GetDifficulty() const { return Real()->m_Difficulty; }
int GetMeter() const { return Real()->m_iMeter; } int GetMeter() const { return Real()->m_iMeter; }
const RadarValues& GetRadarValues() const { return Real()->m_CachedRadarValues; } const RadarValues& GetRadarValues( PlayerNumber pn ) const { return Real()->m_CachedRadarValues[pn]; }
void SetFilename( RString fn ) { m_sFilename = fn; } void SetFilename( RString fn ) { m_sFilename = fn; }
RString GetFilename() const { return m_sFilename; } RString GetFilename() const { return m_sFilename; }
@@ -52,7 +52,7 @@ public:
void SetLoadedFromProfile( ProfileSlot slot ) { m_LoadedFromProfile = slot; } void SetLoadedFromProfile( ProfileSlot slot ) { m_LoadedFromProfile = slot; }
void SetMeter(int meter); void SetMeter(int meter);
void SetCachedRadarValues( const RadarValues& v ); void SetCachedRadarValues( const RadarValues v[NUM_PLAYERS] );
bool IsAutogen() const; // Was created by autogen? bool IsAutogen() const; // Was created by autogen?
float PredictMeter() const; float PredictMeter() const;
@@ -92,7 +92,7 @@ protected:
RString m_sDescription; // Step author, edit name, or something meaningful RString m_sDescription; // Step author, edit name, or something meaningful
Difficulty m_Difficulty; // difficulty classification Difficulty m_Difficulty; // difficulty classification
int m_iMeter; // difficulty rating from MIN_METER to MAX_METER int m_iMeter; // difficulty rating from MIN_METER to MAX_METER
RadarValues m_CachedRadarValues; RadarValues m_CachedRadarValues[NUM_PLAYERS];
}; };
#endif #endif
+2 -2
View File
@@ -118,8 +118,8 @@ bool StepsUtil::CompareNotesPointersByRadarValues(const Steps* pSteps1, const St
float fScore1 = 0; float fScore1 = 0;
float fScore2 = 0; float fScore2 = 0;
fScore1 += pSteps1->GetRadarValues()[RadarCategory_TapsAndHolds]; fScore1 += pSteps1->GetRadarValues( PLAYER_1 )[RadarCategory_TapsAndHolds];
fScore2 += pSteps2->GetRadarValues()[RadarCategory_TapsAndHolds]; fScore2 += pSteps2->GetRadarValues( PLAYER_1 )[RadarCategory_TapsAndHolds];
return fScore1 < fScore2; return fScore1 < fScore2;
} }
+1 -1
View File
@@ -87,7 +87,7 @@ RadarValues Trail::GetRadarValues() const
} }
else else
{ {
rv += pSteps->GetRadarValues(); rv += pSteps->GetRadarValues( PLAYER_1 );
} }
} }