CustomDifficulty fixup
fix stats.xml not saving experimental recentscores.xml saving
This commit is contained in:
@@ -115,6 +115,16 @@ function GetSongBackground()
|
||||
return THEME:GetPathG("Common","fallback background")
|
||||
end
|
||||
|
||||
function StepsOrTrailToCustomDifficulty( stepsOrTrail )
|
||||
if lua.CheckType("Steps", stepsOrTrail) then
|
||||
return StepsToCustomDifficulty( stepsOrTrail );
|
||||
end
|
||||
if lua.CheckType("Trail", stepsOrTrail) then
|
||||
return TrailToCustomDifficulty( stepsOrTrail );
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- (c) 2005 Glenn Maynard, Chris Danford
|
||||
-- All rights reserved.
|
||||
--
|
||||
|
||||
@@ -419,7 +419,7 @@ void EditCourseUtil::UpdateAndSetTrail()
|
||||
StepsType st = GAMESTATE->m_pCurStyle->m_StepsType;
|
||||
Trail *pTrail = NULL;
|
||||
if( GAMESTATE->m_pCurCourse )
|
||||
GAMESTATE->m_pCurCourse->GetTrailForceRegenCache( st );
|
||||
pTrail = GAMESTATE->m_pCurCourse->GetTrailForceRegenCache( st );
|
||||
GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail );
|
||||
}
|
||||
|
||||
|
||||
@@ -148,24 +148,9 @@ RString TrailToCustomDifficulty( const Trail *pTrail )
|
||||
|
||||
#include "LuaBinding.h"
|
||||
|
||||
static int StepsOrTrailToCustomDifficulty( lua_State *L )
|
||||
{
|
||||
Steps *pSteps = Luna<Steps>::check(L, 1);
|
||||
if( pSteps )
|
||||
{
|
||||
lua_pushstring(L, StepsToCustomDifficulty( pSteps ));
|
||||
return 1;
|
||||
}
|
||||
Trail *pTrail = Luna<Trail>::check(L, 1);
|
||||
if( pTrail )
|
||||
{
|
||||
lua_pushstring(L, TrailToCustomDifficulty( pTrail ));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
LuaFunction( StepsToCustomDifficulty, StepsToCustomDifficulty(Luna<Steps>::check(L, 1)) );
|
||||
LuaFunction( TrailToCustomDifficulty, TrailToCustomDifficulty(Luna<Trail>::check(L, 1)) );
|
||||
|
||||
LuaFunction2( StepsOrTrailToCustomDifficulty );
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Chris Danford
|
||||
|
||||
@@ -259,7 +259,7 @@ void StepsDisplayList::SetFromGameState()
|
||||
FOREACH_CONST( Difficulty, difficulties, d )
|
||||
{
|
||||
m_Rows[i].m_dc = *d;
|
||||
m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficulty( StepsType_Invalid, 0, *d );
|
||||
m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GAMESTATE->m_pCurStyle->m_StepsType, 0, *d, CourseType_Invalid );
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row )
|
||||
if( GetSelectedSteps() )
|
||||
m_StepsDisplay.SetFromSteps( GetSelectedSteps() );
|
||||
else
|
||||
m_StepsDisplay.SetFromStepsTypeAndMeterAndDifficulty( GetSelectedSourceStepsType(), 0, GetSelectedDifficulty() );
|
||||
m_StepsDisplay.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GetSelectedSourceStepsType(), 0, GetSelectedDifficulty(), CourseType_Invalid );
|
||||
// fall through
|
||||
case ROW_SOURCE_STEPS_TYPE:
|
||||
m_textLabel[ROW_SOURCE_STEPS_TYPE].SetVisible( GetSelectedSteps() ? false : true );
|
||||
@@ -535,7 +535,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row )
|
||||
else if( GetSelectedSourceSteps() )
|
||||
m_StepsDisplaySource.SetFromSteps( GetSelectedSourceSteps() );
|
||||
else
|
||||
m_StepsDisplaySource.SetFromStepsTypeAndMeterAndDifficulty( GetSelectedSourceStepsType(), 0, GetSelectedSourceDifficulty() );
|
||||
m_StepsDisplaySource.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GetSelectedSourceStepsType(), 0, GetSelectedSourceDifficulty(), CourseType_Invalid );
|
||||
m_StepsDisplaySource.SetVisible( !(bHideMeter || GetSelectedSteps()) );
|
||||
|
||||
m_Actions.clear();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Foreach.h"
|
||||
#include "RadarValues.h"
|
||||
|
||||
#define EMPTY_NAME THEME->GetMetric ("HighScore","EmptyName")
|
||||
ThemeMetric<RString> EMPTY_NAME("HighScore","EmptyName");
|
||||
|
||||
|
||||
struct HighScoreImpl
|
||||
@@ -27,6 +27,7 @@ struct HighScoreImpl
|
||||
int iHoldNoteScores[NUM_HoldNoteScore];
|
||||
RadarValues radarValues;
|
||||
float fLifeRemainingSeconds;
|
||||
bool bDisqualified;
|
||||
|
||||
HighScoreImpl();
|
||||
XNode *CreateNode() const;
|
||||
@@ -55,6 +56,7 @@ bool HighScoreImpl::operator==( const HighScoreImpl& other ) const
|
||||
COMPARE( iHoldNoteScores[hns] );
|
||||
COMPARE( radarValues );
|
||||
COMPARE( fLifeRemainingSeconds );
|
||||
COMPARE( bDisqualified );
|
||||
#undef COMPARE
|
||||
|
||||
return true;
|
||||
@@ -76,6 +78,7 @@ HighScoreImpl::HighScoreImpl()
|
||||
ZERO( iHoldNoteScores );
|
||||
radarValues.MakeUnknown();
|
||||
fLifeRemainingSeconds = 0;
|
||||
bDisqualified = false;
|
||||
}
|
||||
|
||||
XNode *HighScoreImpl::CreateNode() const
|
||||
@@ -105,6 +108,7 @@ XNode *HighScoreImpl::CreateNode() const
|
||||
pHoldNoteScores->AppendChild( HoldNoteScoreToString(hns), iHoldNoteScores[hns] );
|
||||
pNode->AppendChild( radarValues.CreateNode(bWriteSimpleValues, bWriteComplexValues) );
|
||||
pNode->AppendChild( "LifeRemainingSeconds", fLifeRemainingSeconds );
|
||||
pNode->AppendChild( "Disqualified", bDisqualified);
|
||||
|
||||
return pNode;
|
||||
}
|
||||
@@ -138,6 +142,7 @@ void HighScoreImpl::LoadFromNode( const XNode *pNode )
|
||||
if( pRadarValues )
|
||||
radarValues.LoadFromNode( pRadarValues );
|
||||
pNode->GetChildValue( "LifeRemainingSeconds", fLifeRemainingSeconds );
|
||||
pNode->GetChildValue( "Disqualified", bDisqualified);
|
||||
|
||||
/* Validate input. */
|
||||
grade = clamp( grade, Grade_Tier01, Grade_Failed );
|
||||
@@ -170,6 +175,7 @@ int HighScore::GetTapNoteScore( TapNoteScore tns ) const { return m_Impl->iTapNo
|
||||
int HighScore::GetHoldNoteScore( HoldNoteScore hns ) const { return m_Impl->iHoldNoteScores[hns]; }
|
||||
const RadarValues &HighScore::GetRadarValues() const { return m_Impl->radarValues; }
|
||||
float HighScore::GetLifeRemainingSeconds() const { return m_Impl->fLifeRemainingSeconds; }
|
||||
bool HighScore::GetDisqualified() const { return m_Impl->bDisqualified; }
|
||||
|
||||
void HighScore::SetName( const RString &sName ) { m_Impl->sName = sName; }
|
||||
void HighScore::SetGrade( Grade g ) { m_Impl->grade = g; }
|
||||
@@ -185,6 +191,7 @@ void HighScore::SetTapNoteScore( TapNoteScore tns, int i ) { m_Impl->iTapNoteSco
|
||||
void HighScore::SetHoldNoteScore( HoldNoteScore hns, int i ) { m_Impl->iHoldNoteScores[hns] = i; }
|
||||
void HighScore::SetRadarValues( const RadarValues &rv ) { m_Impl->radarValues = rv; }
|
||||
void HighScore::SetLifeRemainingSeconds( float f ) { m_Impl->fLifeRemainingSeconds = f; }
|
||||
void HighScore::SetDisqualified( bool b ) { m_Impl->bDisqualified = b; }
|
||||
|
||||
/* We normally don't give direct access to the members. We need this one
|
||||
* for NameToFillIn; use a special accessor so it's easy to find where this
|
||||
|
||||
@@ -32,6 +32,7 @@ struct HighScore
|
||||
int GetHoldNoteScore( HoldNoteScore tns ) const;
|
||||
const RadarValues &GetRadarValues() const;
|
||||
float GetLifeRemainingSeconds() const;
|
||||
bool GetDisqualified() const;
|
||||
|
||||
void SetName( const RString &sName );
|
||||
void SetGrade( Grade g );
|
||||
@@ -47,6 +48,7 @@ struct HighScore
|
||||
void SetHoldNoteScore( HoldNoteScore tns, int i );
|
||||
void SetRadarValues( const RadarValues &rv );
|
||||
void SetLifeRemainingSeconds( float f );
|
||||
void SetDisqualified( bool b );
|
||||
|
||||
RString *GetNameMutable();
|
||||
const RString *GetNameMutable() const { return const_cast<RString *> (const_cast<HighScore *>(this)->GetNameMutable()); }
|
||||
|
||||
@@ -214,9 +214,6 @@ int LuaFunc_##func( lua_State *L ) { \
|
||||
void LuaFunc_Register_##func( lua_State *L ) { lua_register( L, #func, LuaFunc_##func ); } \
|
||||
REGISTER_WITH_LUA_FUNCTION( LuaFunc_Register_##func );
|
||||
|
||||
#define LuaFunction2( func ) \
|
||||
void LuaFunc_Register_##func( lua_State *L ) { lua_register( L, #func, func ); } \
|
||||
REGISTER_WITH_LUA_FUNCTION( LuaFunc_Register_##func );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ const RString PUBLIC_KEY_FILE = "public.key";
|
||||
const RString SCREENSHOTS_SUBDIR = "Screenshots/";
|
||||
const RString EDIT_STEPS_SUBDIR = "Edits/";
|
||||
const RString EDIT_COURSES_SUBDIR = "EditCourses/";
|
||||
const RString UPLOAD_SUBDIR = "Upload/";
|
||||
|
||||
ThemeMetric<bool> SHOW_COIN_DATA( "Profile", "ShowCoinData" );
|
||||
static Preference<bool> g_bProfileDataCompress( "ProfileDataCompress", false );
|
||||
@@ -978,6 +977,9 @@ bool Profile::SaveStatsXmlToDir( RString sDir, bool bSignData ) const
|
||||
{
|
||||
RageFileObjGzip gzip( &f );
|
||||
gzip.Start();
|
||||
if( !XmlFileUtil::SaveToFile( xml.get(), gzip, "", false ) )
|
||||
return false;
|
||||
|
||||
if( gzip.Finish() == -1 )
|
||||
return false;
|
||||
|
||||
@@ -987,6 +989,9 @@ bool Profile::SaveStatsXmlToDir( RString sDir, bool bSignData ) const
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !XmlFileUtil::SaveToFile( xml.get(), f, "", false ) )
|
||||
return false;
|
||||
|
||||
/* After successfully saving STATS_XML, remove any stray STATS_XML_GZ. */
|
||||
if( FILEMAN->IsAFile(sDir + STATS_XML_GZ) )
|
||||
FILEMAN->Remove( sDir + STATS_XML_GZ );
|
||||
@@ -1717,75 +1722,6 @@ float Profile::GetCaloriesBurnedForDay( DateTime day ) const
|
||||
return i->second.fCals;
|
||||
}
|
||||
|
||||
static void SaveRecentScore( XNode* xml )
|
||||
{
|
||||
RString sDate = DateTime::GetNowDate().GetString();
|
||||
sDate.Replace(":","-");
|
||||
|
||||
RString sFileNameNoExtension = Profile::MakeUniqueFileNameNoExtension(UPLOAD_SUBDIR, sDate );
|
||||
RString fn = UPLOAD_SUBDIR + sFileNameNoExtension + ".xml";
|
||||
|
||||
RString sStatsXmlSigFile = fn+SIGNATURE_APPEND;
|
||||
CryptManager::SignFileToFile(fn, sStatsXmlSigFile);
|
||||
}
|
||||
|
||||
|
||||
XNode* Profile::HighScoreForASongAndSteps::CreateNode() const
|
||||
{
|
||||
XNode* pNode = new XNode( "HighScoreForASongAndSteps" );
|
||||
|
||||
pNode->AppendChild( songID.CreateNode() );
|
||||
pNode->AppendChild( stepsID.CreateNode() );
|
||||
pNode->AppendChild( hs.CreateNode() );
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void Profile::SaveStepsRecentScore( const Song* pSong, const Steps* pSteps, HighScore hs )
|
||||
{
|
||||
ASSERT( pSong );
|
||||
ASSERT( pSteps );
|
||||
HighScoreForASongAndSteps h;
|
||||
h.songID.FromSong( pSong );
|
||||
ASSERT( h.songID.IsValid() );
|
||||
h.stepsID.FromSteps( pSteps );
|
||||
ASSERT( h.stepsID.IsValid() );
|
||||
h.hs = hs;
|
||||
|
||||
auto_ptr<XNode> xml( new XNode("Stats") );
|
||||
xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid );
|
||||
XNode *recent = xml->AppendChild( new XNode("RecentSongScores") );
|
||||
recent->AppendChild( h.CreateNode() );
|
||||
|
||||
SaveRecentScore( xml.get() );
|
||||
}
|
||||
|
||||
|
||||
XNode* Profile::HighScoreForACourseAndTrail::CreateNode() const
|
||||
{
|
||||
XNode* pNode = new XNode( "HighScoreForACourseAndTrail" );
|
||||
|
||||
pNode->AppendChild( courseID.CreateNode() );
|
||||
pNode->AppendChild( trailID.CreateNode() );
|
||||
pNode->AppendChild( hs.CreateNode() );
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void Profile::SaveCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs )
|
||||
{
|
||||
HighScoreForACourseAndTrail h;
|
||||
h.courseID.FromCourse( pCourse );
|
||||
h.trailID.FromTrail( pTrail );
|
||||
h.hs = hs;
|
||||
|
||||
auto_ptr<XNode> xml( new XNode("Stats") );
|
||||
xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid );
|
||||
XNode *recent = xml->AppendChild( new XNode("RecentCourseScores") );
|
||||
recent->AppendChild( h.CreateNode() );
|
||||
|
||||
SaveRecentScore( xml.get() );
|
||||
}
|
||||
|
||||
const Profile::HighScoresForASong *Profile::GetHighScoresForASong( const SongID& songID ) const
|
||||
{
|
||||
@@ -1882,7 +1818,7 @@ RString Profile::MakeUniqueFileNameNoExtension( RString sDir, RString sFileNameB
|
||||
FILEMAN->FlushDirCache( sDir );
|
||||
|
||||
vector<RString> files;
|
||||
GetDirListing( sDir + "sFileNameBeginning*", files, false, false );
|
||||
GetDirListing( sDir + sFileNameBeginning+"*", files, false, false );
|
||||
sort( files.begin(), files.end() );
|
||||
|
||||
int iIndex = 0;
|
||||
|
||||
@@ -234,39 +234,6 @@ public:
|
||||
float GetCaloriesBurnedForDay( DateTime day ) const;
|
||||
|
||||
|
||||
//
|
||||
// RecentSongScores
|
||||
//
|
||||
struct HighScoreForASongAndSteps
|
||||
{
|
||||
StepsID stepsID;
|
||||
SongID songID;
|
||||
HighScore hs;
|
||||
|
||||
HighScoreForASongAndSteps() { Unset(); }
|
||||
void Unset() { stepsID.Unset(); songID.Unset(); hs.Unset(); }
|
||||
|
||||
XNode* CreateNode() const;
|
||||
};
|
||||
void SaveStepsRecentScore( const Song* pSong, const Steps* pSteps, HighScore hs );
|
||||
|
||||
|
||||
//
|
||||
// RecentCourseScores
|
||||
//
|
||||
struct HighScoreForACourseAndTrail
|
||||
{
|
||||
CourseID courseID;
|
||||
TrailID trailID;
|
||||
HighScore hs;
|
||||
|
||||
HighScoreForACourseAndTrail() { Unset(); }
|
||||
void Unset() { courseID.Unset(); hs.Unset(); }
|
||||
|
||||
XNode* CreateNode() const;
|
||||
};
|
||||
void SaveCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs );
|
||||
|
||||
//
|
||||
// Init'ing
|
||||
//
|
||||
|
||||
@@ -667,13 +667,6 @@ void ProfileManager::AddStepsScore( const Song* pSong, const Steps* pSteps, Play
|
||||
if( !pSteps->IsAPlayerEdit() )
|
||||
GetMachineProfile()->AddStepsHighScore( pSong, pSteps, hs, iMachineIndexOut );
|
||||
}
|
||||
|
||||
//
|
||||
// save recent score
|
||||
//
|
||||
if( IsPersistentProfile(pn) )
|
||||
GetProfile(pn)->SaveStepsRecentScore( pSong, pSteps, hs );
|
||||
GetMachineProfile()->SaveStepsRecentScore( pSong, pSteps, hs );
|
||||
}
|
||||
|
||||
void ProfileManager::IncrementStepsPlayCount( const Song* pSong, const Steps* pSteps, PlayerNumber pn )
|
||||
@@ -717,13 +710,6 @@ void ProfileManager::AddCourseScore( const Course* pCourse, const Trail* pTrail,
|
||||
GetProfile(pn)->AddCourseHighScore( pCourse, pTrail, hs, iPersonalIndexOut );
|
||||
if( hs.GetPercentDP() >= PREFSMAN->m_fMinPercentageForMachineCourseHighScore )
|
||||
GetMachineProfile()->AddCourseHighScore( pCourse, pTrail, hs, iMachineIndexOut );
|
||||
|
||||
//
|
||||
// save recent score
|
||||
//
|
||||
if( IsPersistentProfile(pn) )
|
||||
GetProfile(pn)->SaveCourseRecentScore( pCourse, pTrail, hs );
|
||||
GetMachineProfile()->SaveCourseRecentScore( pCourse, pTrail, hs );
|
||||
}
|
||||
|
||||
void ProfileManager::IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail, PlayerNumber pn )
|
||||
|
||||
@@ -237,7 +237,7 @@ void ScreenEvaluation::Init()
|
||||
// update persistent statistics
|
||||
//
|
||||
if( SUMMARY )
|
||||
m_pStageStats->CommitScores( true );
|
||||
m_pStageStats->FinalizeScores( true );
|
||||
|
||||
// Run this here, so STATSMAN->m_CurStageStats is available to overlays.
|
||||
ScreenWithMenuElements::Init();
|
||||
|
||||
@@ -2446,7 +2446,7 @@ void ScreenGameplay::StageFinished( bool bBackedOut )
|
||||
|
||||
FOREACH_HumanPlayer( pn )
|
||||
STATSMAN->m_CurStageStats.m_player[pn].CalcAwards( pn, STATSMAN->m_CurStageStats.m_bGaveUp, STATSMAN->m_CurStageStats.m_bUsedAutoplay );
|
||||
STATSMAN->m_CurStageStats.CommitScores( false );
|
||||
STATSMAN->m_CurStageStats.FinalizeScores( false );
|
||||
|
||||
GAMESTATE->CommitStageStats();
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ void ScreenGameplayLesson::HandleScreenMessage( const ScreenMessage SM )
|
||||
|
||||
// Commit scores here since we don't go through an eval screen.
|
||||
// Only commit if we've cleared. Don't commit if we've failed all 3 tries.
|
||||
STATSMAN->m_CurStageStats.CommitScores( false );
|
||||
STATSMAN->m_CurStageStats.FinalizeScores( false );
|
||||
}
|
||||
else if( bAnyTriesLeft )
|
||||
{
|
||||
|
||||
@@ -488,7 +488,7 @@ void ScreenNetSelectMusic::UpdateDifficulties( PlayerNumber pn )
|
||||
{
|
||||
if ( GAMESTATE->m_pCurSong == NULL )
|
||||
{
|
||||
m_StepsDisplays[pn].SetFromStepsTypeAndMeterAndDifficulty( StepsType_Invalid, 0, Difficulty_Beginner );
|
||||
m_StepsDisplays[pn].SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType_Invalid, 0, Difficulty_Beginner, CourseType_Invalid );
|
||||
m_DifficultyIcon[pn].SetFromSteps( pn, NULL ); //It will blank it out
|
||||
return;
|
||||
}
|
||||
@@ -510,7 +510,7 @@ void ScreenNetSelectMusic::UpdateDifficulties( PlayerNumber pn )
|
||||
if ( ( m_DC[pn] < NUM_Difficulty ) && ( m_DC[pn] >= Difficulty_Beginner ) )
|
||||
m_StepsDisplays[pn].SetFromSteps( pSteps );
|
||||
else
|
||||
m_StepsDisplays[pn].SetFromStepsTypeAndMeterAndDifficulty( StepsType_Invalid, 0, Difficulty_Beginner );
|
||||
m_StepsDisplays[pn].SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType_Invalid, 0, Difficulty_Beginner, CourseType_Invalid );
|
||||
}
|
||||
|
||||
void ScreenNetSelectMusic::MusicChanged()
|
||||
|
||||
@@ -129,7 +129,42 @@ float StageStats::GetTotalPossibleStepsSeconds() const
|
||||
return fSecs / m_fMusicRate;
|
||||
}
|
||||
|
||||
void StageStats::CommitScores( bool bSummary )
|
||||
static HighScore FillInHighScore( const PlayerStageStats &pss, const PlayerState &ps, RString sRankingToFillInMarker, RString sPlayerGuid )
|
||||
{
|
||||
HighScore hs;
|
||||
hs.SetName( sRankingToFillInMarker );
|
||||
hs.SetGrade( pss.GetGrade() );
|
||||
hs.SetScore( pss.m_iScore );
|
||||
hs.SetPercentDP( pss.GetPercentDancePoints() );
|
||||
hs.SetAliveSeconds( pss.m_fAliveSeconds );
|
||||
|
||||
vector<RString> asModifiers;
|
||||
{
|
||||
RString sPlayerOptions = ps.m_PlayerOptions.GetStage().GetString();
|
||||
if( !sPlayerOptions.empty() )
|
||||
asModifiers.push_back( sPlayerOptions );
|
||||
RString sSongOptions = GAMESTATE->m_SongOptions.GetStage().GetString();
|
||||
if( !sSongOptions.empty() )
|
||||
asModifiers.push_back( sSongOptions );
|
||||
}
|
||||
hs.SetModifiers( join(", ", asModifiers) );
|
||||
|
||||
hs.SetDateTime( DateTime::GetNowDateTime() );
|
||||
hs.SetPlayerGuid( sPlayerGuid );
|
||||
hs.SetMachineGuid( PROFILEMAN->GetMachineProfile()->m_sGuid );
|
||||
hs.SetProductID( PREFSMAN->m_iProductID );
|
||||
FOREACH_ENUM( TapNoteScore, tns )
|
||||
hs.SetTapNoteScore( tns, pss.m_iTapNoteScores[tns] );
|
||||
FOREACH_ENUM( HoldNoteScore, hns )
|
||||
hs.SetHoldNoteScore( hns, pss.m_iHoldNoteScores[hns] );
|
||||
hs.SetRadarValues( pss.m_radarActual );
|
||||
hs.SetLifeRemainingSeconds( pss.m_fLifeRemainingSeconds );
|
||||
hs.SetDisqualified( pss.IsDisqualified() );
|
||||
|
||||
return hs;
|
||||
}
|
||||
|
||||
void StageStats::FinalizeScores( bool bSummary )
|
||||
{
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
{
|
||||
@@ -153,44 +188,23 @@ void StageStats::CommitScores( bool bSummary )
|
||||
|
||||
LOG->Trace( "saving stats and high scores" );
|
||||
|
||||
//
|
||||
// generate a HighScore for each player
|
||||
//
|
||||
// whether or not to save scores when the stage was failed
|
||||
// depends on if this is a course or not ... it's handled
|
||||
// below in the switch
|
||||
FOREACH_HumanPlayer( p )
|
||||
{
|
||||
// don't save scores if the player is disqualified
|
||||
if( this->m_player[p].IsDisqualified() )
|
||||
RString sPlayerGuid = PROFILEMAN->IsPersistentProfile(p) ? PROFILEMAN->GetProfile(p)->m_sGuid : RString("");
|
||||
m_player[p].m_HighScore = FillInHighScore( m_player[p], *GAMESTATE->m_pPlayerState[p], RANKING_TO_FILL_IN_MARKER[p], sPlayerGuid );
|
||||
}
|
||||
FOREACH_MultiPlayer( mp )
|
||||
{
|
||||
if( !GAMESTATE->IsMultiPlayerEnabled(mp) )
|
||||
continue;
|
||||
|
||||
// whether or not to save scores when the stage was failed
|
||||
// depends on if this is a course or not ... it's handled
|
||||
// below in the switch
|
||||
|
||||
HighScore &hs = m_player[p].m_HighScore;
|
||||
hs.SetName( RANKING_TO_FILL_IN_MARKER[p] );
|
||||
hs.SetGrade( m_player[p].GetGrade() );
|
||||
hs.SetScore( m_player[p].m_iScore );
|
||||
hs.SetPercentDP( m_player[p].GetPercentDancePoints() );
|
||||
hs.SetAliveSeconds( m_player[p].m_fAliveSeconds );
|
||||
|
||||
vector<RString> asModifiers;
|
||||
{
|
||||
RString sPlayerOptions = GAMESTATE->m_pPlayerState[p]->m_PlayerOptions.GetStage().GetString();
|
||||
if( !sPlayerOptions.empty() )
|
||||
asModifiers.push_back( sPlayerOptions );
|
||||
RString sSongOptions = GAMESTATE->m_SongOptions.GetStage().GetString();
|
||||
if( !sSongOptions.empty() )
|
||||
asModifiers.push_back( sSongOptions );
|
||||
}
|
||||
hs.SetModifiers( join(", ", asModifiers) );
|
||||
|
||||
hs.SetDateTime( DateTime::GetNowDateTime() );
|
||||
hs.SetPlayerGuid( PROFILEMAN->IsPersistentProfile(p) ? PROFILEMAN->GetProfile(p)->m_sGuid : RString("") );
|
||||
hs.SetMachineGuid( PROFILEMAN->GetMachineProfile()->m_sGuid );
|
||||
hs.SetProductID( PREFSMAN->m_iProductID );
|
||||
FOREACH_ENUM( TapNoteScore, tns )
|
||||
hs.SetTapNoteScore( tns, m_player[p].m_iTapNoteScores[tns] );
|
||||
FOREACH_ENUM( HoldNoteScore, hns )
|
||||
hs.SetHoldNoteScore( hns, m_player[p].m_iHoldNoteScores[hns] );
|
||||
hs.SetRadarValues( m_player[p].m_radarActual );
|
||||
hs.SetLifeRemainingSeconds( m_player[p].m_fLifeRemainingSeconds );
|
||||
RString sPlayerGuid = "????"; // FIXME
|
||||
m_multiPlayer[mp].m_HighScore = FillInHighScore( m_multiPlayer[mp], *GAMESTATE->m_pMultiPlayerState[mp], "", sPlayerGuid );
|
||||
}
|
||||
|
||||
FOREACH_HumanPlayer( p )
|
||||
@@ -201,6 +215,10 @@ void StageStats::CommitScores( bool bSummary )
|
||||
const Song* pSong = GAMESTATE->m_pCurSong;
|
||||
const Steps* pSteps = GAMESTATE->m_pCurSteps[p];
|
||||
|
||||
// Don't save DQ'd scores
|
||||
if( hs.GetDisqualified() )
|
||||
continue;
|
||||
|
||||
if( bSummary )
|
||||
{
|
||||
// don't save scores if any stage was failed
|
||||
@@ -217,6 +235,8 @@ void StageStats::CommitScores( bool bSummary )
|
||||
}
|
||||
else if( GAMESTATE->IsCourseMode() )
|
||||
{
|
||||
// Save this stage to recent scores
|
||||
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
ASSERT( pCourse );
|
||||
Trail* pTrail = GAMESTATE->m_pCurTrail[p];
|
||||
@@ -231,8 +251,6 @@ void StageStats::CommitScores( bool bSummary )
|
||||
}
|
||||
}
|
||||
|
||||
LOG->Trace( "done saving stats and high scores" );
|
||||
|
||||
// If both players get a machine high score in the same HighScoreList,
|
||||
// then one player's score may have bumped the other player. Look in
|
||||
// the HighScoreList and re-get the high score index.
|
||||
@@ -272,7 +290,7 @@ void StageStats::CommitScores( bool bSummary )
|
||||
m_player[p].m_iMachineHighScoreIndex = iter - pHSL->vHighScores.begin();
|
||||
}
|
||||
|
||||
|
||||
LOG->Trace( "done saving stats and high scores" );
|
||||
}
|
||||
|
||||
bool StageStats::PlayerHasHighScore( PlayerNumber pn ) const
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
PlayerStageStats m_player[NUM_PLAYERS];
|
||||
PlayerStageStats m_multiPlayer[NUM_MultiPlayer];
|
||||
|
||||
void CommitScores( bool bSummary );
|
||||
void FinalizeScores( bool bSummary ); // finalize by filling in the HighScore structures for all players
|
||||
bool PlayerHasHighScore( PlayerNumber pn ) const;
|
||||
int GetMinimumMissCombo() const;
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include "Steps.h"
|
||||
#include "StyleUtil.h"
|
||||
#include "LuaManager.h"
|
||||
#include "Profile.h"
|
||||
#include "XmlFile.h"
|
||||
#include "CryptManager.h"
|
||||
#include "XmlFileUtil.h"
|
||||
|
||||
StatsManager* STATSMAN = NULL; // global object accessable from anywhere in the program
|
||||
|
||||
@@ -156,12 +160,47 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum
|
||||
}
|
||||
}
|
||||
|
||||
XNode* MakeRecentScoreNode( const StageStats &ss, Trail *pTrail, const PlayerStageStats &pss, MultiPlayer mp )
|
||||
{
|
||||
XNode* pNode = NULL;
|
||||
if( GAMESTATE->IsCourseMode() )
|
||||
{
|
||||
pNode = new XNode( "HighScoreForACourseAndTrail" );
|
||||
|
||||
CourseID courseID;
|
||||
courseID.FromCourse(GAMESTATE->m_pCurCourse );
|
||||
pNode->AppendChild( courseID.CreateNode() );
|
||||
|
||||
TrailID trailID;
|
||||
trailID.FromTrail( pTrail );
|
||||
pNode->AppendChild( trailID.CreateNode() );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
XNode* pNode = new XNode( "HighScoreForASongAndSteps" );
|
||||
|
||||
SongID songID;
|
||||
songID.FromSong( ss.m_vpPossibleSongs[0] );
|
||||
pNode->AppendChild( songID.CreateNode() );
|
||||
|
||||
StepsID stepsID;
|
||||
stepsID.FromSteps( pss.m_vpPossibleSteps[0] );
|
||||
pNode->AppendChild( stepsID.CreateNode() );
|
||||
}
|
||||
|
||||
XNode* pHighScore = pss.m_HighScore.CreateNode();
|
||||
pHighScore->AppendChild("Pad", mp);
|
||||
RString sStageGuid = ssprintf("%08x-0000-1000-0000-53FA337761C6", GAMESTATE->m_iStageSeed);
|
||||
pHighScore->AppendChild("StageGuid", sStageGuid);
|
||||
|
||||
pNode->AppendChild( pHighScore );
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void StatsManager::CommitStatsToProfiles( const StageStats *pSS )
|
||||
{
|
||||
if( GAMESTATE->m_bMultiplayer )
|
||||
return;
|
||||
|
||||
//
|
||||
// Add step totals. Use radarActual, since the player might have failed part way
|
||||
// through the song, in which case we don't want to give credit for the rest of the
|
||||
@@ -188,24 +227,63 @@ void StatsManager::CommitStatsToProfiles( const StageStats *pSS )
|
||||
pMachineProfile->m_iNumTotalSongsPlayed += pSS->m_vpPlayedSongs.size();
|
||||
|
||||
CHECKPOINT;
|
||||
FOREACH_HumanPlayer( pn )
|
||||
if( !GAMESTATE->m_bMultiplayer ) // FIXME
|
||||
{
|
||||
CHECKPOINT;
|
||||
|
||||
Profile* pPlayerProfile = PROFILEMAN->GetProfile( pn );
|
||||
if( pPlayerProfile )
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
pPlayerProfile->m_iTotalGameplaySeconds += iGameplaySeconds;
|
||||
pPlayerProfile->m_iNumTotalSongsPlayed += pSS->m_vpPlayedSongs.size();
|
||||
CHECKPOINT;
|
||||
|
||||
Profile* pPlayerProfile = PROFILEMAN->GetProfile( pn );
|
||||
if( pPlayerProfile )
|
||||
{
|
||||
pPlayerProfile->m_iTotalGameplaySeconds += iGameplaySeconds;
|
||||
pPlayerProfile->m_iNumTotalSongsPlayed += pSS->m_vpPlayedSongs.size();
|
||||
}
|
||||
|
||||
AddPlayerStatsToProfile( pMachineProfile, *pSS, pn );
|
||||
|
||||
if( pPlayerProfile )
|
||||
AddPlayerStatsToProfile( pPlayerProfile, *pSS, pn );
|
||||
|
||||
CHECKPOINT;
|
||||
}
|
||||
|
||||
AddPlayerStatsToProfile( pMachineProfile, *pSS, pn );
|
||||
|
||||
if( pPlayerProfile )
|
||||
AddPlayerStatsToProfile( pPlayerProfile, *pSS, pn );
|
||||
|
||||
CHECKPOINT;
|
||||
}
|
||||
|
||||
// Save recent scores
|
||||
{
|
||||
auto_ptr<XNode> xml( new XNode("Stats") );
|
||||
xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid );
|
||||
|
||||
XNode *recent = NULL;
|
||||
if( GAMESTATE->IsCourseMode() )
|
||||
recent = xml->AppendChild( new XNode("RecentCourseScores") );
|
||||
else
|
||||
recent = xml->AppendChild( new XNode("RecentSongScores") );
|
||||
|
||||
FOREACH_HumanPlayer( p )
|
||||
recent->AppendChild( MakeRecentScoreNode( *pSS, GAMESTATE->m_pCurTrail[p], pSS->m_player[p], MultiPlayer_Invalid ) );
|
||||
|
||||
FOREACH_EnabledMultiPlayer( mp )
|
||||
recent->AppendChild( MakeRecentScoreNode( *pSS, GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber], pSS->m_multiPlayer[mp], mp ) );
|
||||
|
||||
|
||||
RString sDate = DateTime::GetNowDate().GetString();
|
||||
sDate.Replace(":","-");
|
||||
|
||||
const RString UPLOAD_DIR = "Save/Upload/";
|
||||
RString sFileNameNoExtension = Profile::MakeUniqueFileNameNoExtension(UPLOAD_DIR, sDate + " " );
|
||||
RString fn = UPLOAD_DIR + sFileNameNoExtension + ".xml";
|
||||
|
||||
bool bSaved = XmlFileUtil::SaveToFile( xml.get(), fn, "", false );
|
||||
|
||||
if( bSaved )
|
||||
{
|
||||
RString sStatsXmlSigFile = fn + SIGNATURE_APPEND;
|
||||
CryptManager::SignFileToFile(fn, sStatsXmlSigFile);
|
||||
}
|
||||
}
|
||||
|
||||
FileCopy( "Data/TempTestGroups.xml", "Save/Upload/data.xml" );
|
||||
}
|
||||
|
||||
void StatsManager::UnjoinPlayer( PlayerNumber pn )
|
||||
|
||||
@@ -125,7 +125,7 @@ void StepsDisplay::SetFromGameState( PlayerNumber pn )
|
||||
if( pTrail )
|
||||
SetFromTrail( pTrail );
|
||||
else
|
||||
SetFromStepsTypeAndMeterAndCourseDifficulty( StepsType_Invalid, 0, GAMESTATE->m_PreferredCourseDifficulty[pn] );
|
||||
SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType_Invalid, 0, GAMESTATE->m_PreferredCourseDifficulty[pn], pTrail->m_CourseType );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -133,7 +133,7 @@ void StepsDisplay::SetFromGameState( PlayerNumber pn )
|
||||
if( pSteps )
|
||||
SetFromSteps( pSteps );
|
||||
else
|
||||
SetFromStepsTypeAndMeterAndDifficulty( StepsType_Invalid, 0, GAMESTATE->m_PreferredDifficulty[pn] );
|
||||
SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType_Invalid, 0, GAMESTATE->m_PreferredDifficulty[pn], CourseType_Invalid );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ void StepsDisplay::SetFromSteps( const Steps* pSteps )
|
||||
return;
|
||||
}
|
||||
|
||||
SetParams params = { pSteps, NULL, pSteps->GetMeter(), pSteps->m_StepsType, pSteps->GetDifficulty(), false, pSteps->GetDescription() };
|
||||
SetParams params = { pSteps, NULL, pSteps->GetMeter(), pSteps->m_StepsType, pSteps->GetDifficulty(), CourseType_Invalid };
|
||||
SetInternal( params );
|
||||
}
|
||||
|
||||
@@ -157,50 +157,50 @@ void StepsDisplay::SetFromTrail( const Trail* pTrail )
|
||||
return;
|
||||
}
|
||||
|
||||
SetParams params = { NULL, pTrail, pTrail->GetMeter(), pTrail->m_StepsType, pTrail->m_CourseDifficulty, true, RString() };
|
||||
SetParams params = { NULL, pTrail, pTrail->GetMeter(), pTrail->m_StepsType, pTrail->m_CourseDifficulty, pTrail->m_CourseType };
|
||||
SetInternal( params );
|
||||
}
|
||||
|
||||
void StepsDisplay::Unset()
|
||||
{
|
||||
SetParams params = { NULL, NULL, 0, StepsType_Invalid, Difficulty_Invalid, false, RString() };
|
||||
SetInternal( params );
|
||||
this->SetVisible( false );
|
||||
}
|
||||
|
||||
void StepsDisplay::SetFromStepsTypeAndMeterAndDifficulty( StepsType st, int iMeter, Difficulty dc )
|
||||
void StepsDisplay::SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType st, int iMeter, Difficulty dc, CourseType ct )
|
||||
{
|
||||
SetParams params = { NULL, NULL, iMeter, st, dc, false, RString() };
|
||||
SetInternal( params );
|
||||
}
|
||||
|
||||
void StepsDisplay::SetFromStepsTypeAndMeterAndCourseDifficulty( StepsType st, int iMeter, CourseDifficulty cd )
|
||||
{
|
||||
SetParams params = { NULL, NULL, 0, st, cd, true, RString() };
|
||||
SetParams params = { NULL, NULL, iMeter, st, dc, ct };
|
||||
SetInternal( params );
|
||||
}
|
||||
|
||||
void StepsDisplay::SetInternal( const SetParams ¶ms )
|
||||
{
|
||||
this->SetVisible( true );
|
||||
|
||||
Message msg( "Set" );
|
||||
|
||||
RString sCustomDifficulty;
|
||||
if( params.pSteps )
|
||||
sCustomDifficulty = StepsToCustomDifficulty(params.pSteps);
|
||||
else if( params.pTrail )
|
||||
sCustomDifficulty = TrailToCustomDifficulty(params.pTrail);
|
||||
else
|
||||
sCustomDifficulty = GetCustomDifficulty( params.st, params.dc, params.ct );
|
||||
msg.SetParam( "CustomDifficulty", sCustomDifficulty );
|
||||
|
||||
RString sDisplayDescription;
|
||||
if( params.pSteps && params.pSteps->IsAnEdit() )
|
||||
sDisplayDescription = params.pSteps->GetDescription();
|
||||
else
|
||||
sDisplayDescription = CustomDifficultyToLocalizedString( sCustomDifficulty );
|
||||
msg.SetParam( "DisplayDescription", sDisplayDescription );
|
||||
|
||||
if( params.pSteps )
|
||||
msg.SetParam( "Steps", LuaReference::CreateFromPush(*(Steps*)params.pSteps) );
|
||||
if( params.pTrail )
|
||||
msg.SetParam( "Trail", LuaReference::CreateFromPush(*(Trail*)params.pTrail) );
|
||||
msg.SetParam( "Meter", params.iMeter );
|
||||
msg.SetParam( "StepsType", params.st );
|
||||
msg.SetParam( "Difficulty", params.dc );
|
||||
msg.SetParam( "IsCourseDifficulty", params.bIsCourseDifficulty );
|
||||
msg.SetParam( "Description", params.sDescription );
|
||||
RString sCustomDifficulty;
|
||||
if( params.st != StepsType_Invalid )
|
||||
{
|
||||
if( params.pSteps )
|
||||
sCustomDifficulty = StepsToCustomDifficulty(params.pSteps);
|
||||
if( params.pTrail )
|
||||
sCustomDifficulty = TrailToCustomDifficulty(params.pTrail);
|
||||
msg.SetParam( "CustomDifficulty", sCustomDifficulty );
|
||||
}
|
||||
|
||||
|
||||
m_sprFrame->HandleMessage( msg );
|
||||
|
||||
if( m_bShowTicks )
|
||||
@@ -231,20 +231,7 @@ void StepsDisplay::SetInternal( const SetParams ¶ms )
|
||||
|
||||
if( m_bShowDescription )
|
||||
{
|
||||
RString s;
|
||||
if( params.bIsCourseDifficulty )
|
||||
{
|
||||
s = CourseDifficultyToLocalizedString(params.dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( params.pSteps && params.pSteps->IsAnEdit() )
|
||||
s = params.sDescription;
|
||||
else if( !sCustomDifficulty.empty() )
|
||||
s = CustomDifficultyToLocalizedString( sCustomDifficulty );
|
||||
}
|
||||
|
||||
m_textDescription.SetText( s );
|
||||
m_textDescription.SetText( sDisplayDescription );
|
||||
}
|
||||
|
||||
if( m_bShowAutogen )
|
||||
@@ -273,7 +260,6 @@ class LunaStepsDisplay: public Luna<StepsDisplay>
|
||||
{
|
||||
public:
|
||||
static int Load( T* p, lua_State *L ) { p->Load( SArg(1), NULL ); return 0; }
|
||||
static int SetFromStepsTypeAndMeterAndDifficulty( T* p, lua_State *L ) { p->SetFromStepsTypeAndMeterAndDifficulty( Enum::Check<StepsType>(L, 1), IArg(2), Enum::Check<Difficulty>(L, 3) ); return 0; }
|
||||
static int SetFromSteps( T* p, lua_State *L )
|
||||
{
|
||||
if( lua_isnil(L,1) )
|
||||
@@ -310,7 +296,6 @@ public:
|
||||
LunaStepsDisplay()
|
||||
{
|
||||
ADD_METHOD( Load );
|
||||
ADD_METHOD( SetFromStepsTypeAndMeterAndDifficulty );
|
||||
ADD_METHOD( SetFromSteps );
|
||||
ADD_METHOD( SetFromTrail );
|
||||
ADD_METHOD( SetFromGameState );
|
||||
|
||||
@@ -27,8 +27,7 @@ public:
|
||||
virtual StepsDisplay *Copy() const;
|
||||
|
||||
void SetFromGameState( PlayerNumber pn );
|
||||
void SetFromStepsTypeAndMeterAndDifficulty( StepsType st, int iMeter, Difficulty dc );
|
||||
void SetFromStepsTypeAndMeterAndCourseDifficulty( StepsType st, int iMeter, CourseDifficulty cd );
|
||||
void SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType st, int iMeter, Difficulty dc, CourseType ct );
|
||||
void SetFromSteps( const Steps* pSteps );
|
||||
void SetFromTrail( const Trail* pTrail );
|
||||
void Unset();
|
||||
@@ -42,10 +41,9 @@ private:
|
||||
const Steps *pSteps;
|
||||
const Trail *pTrail;
|
||||
int iMeter;
|
||||
StepsType st;
|
||||
StepsType st; // pass because there may be a StepType icons
|
||||
Difficulty dc;
|
||||
bool bIsCourseDifficulty;
|
||||
RString sDescription;
|
||||
CourseType ct;
|
||||
};
|
||||
void SetInternal( const SetParams ¶ms );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user