const RadarValues &Trail::GetRadarValues() const { if( m_bRadarValuesCached ) { return m_CachedRadarValues; } if( IsSecret() ) { // Don't calculate RadarValues for a non-fixed Course. They values are // worthless because they'll change every time this Trail is // regenerated. m_CachedRadarValues = RadarValues(); return m_CachedRadarValues; } else { RadarValues rv; rv.Zero(); FOREACH_CONST( TrailEntry, m_vEntries, e ) { const Steps *pSteps = e->pSteps; ASSERT( pSteps != NULL ); // Hack: don't calculate for autogen entries if( !pSteps->IsAutogen() && e->ContainsTransformOrTurn() ) { NoteData nd; pSteps->GetNoteData( nd ); RadarValues rv_orig; GAMESTATE->SetProcessedTimingData(const_cast<TimingData *>(pSteps->GetTimingData())); NoteDataUtil::CalculateRadarValues( nd, e->pSong->m_fMusicLengthSeconds, rv_orig ); PlayerOptions po; po.FromString( e->Modifiers ); if( po.ContainsTransformOrTurn() ) { NoteDataUtil::TransformNoteData(nd, *(pSteps->GetTimingData()), po, pSteps->m_StepsType); } NoteDataUtil::TransformNoteData(nd, *(pSteps->GetTimingData()), e->Attacks, pSteps->m_StepsType, e->pSong); RadarValues transformed_rv; NoteDataUtil::CalculateRadarValues( nd, e->pSong->m_fMusicLengthSeconds, transformed_rv ); GAMESTATE->SetProcessedTimingData(NULL); rv += transformed_rv; } else { rv += pSteps->GetRadarValues( PLAYER_1 ); } } /* Hack: SetRadarValues is non-const (a const setter doesn't * make sense), but it only modifies a mutable value. Just * cast away const. */ const_cast<Trail*>(this)->SetRadarValues( rv ); return m_CachedRadarValues; } }
const RadarValues &Trail::GetRadarValues() const { if( m_bRadarValuesCached ) { return m_CachedRadarValues; } else if( IsSecret() ) { // Don't calculate RadarValues for a non-fixed Course. The values are // worthless because they'll change every time this Trail is // regenerated. m_CachedRadarValues = RadarValues(); return m_CachedRadarValues; } else { RadarValues rv; rv.Zero(); FOREACH_CONST( TrailEntry, m_vEntries, e ) { const Steps *pSteps = e->pSteps; ASSERT( pSteps ); /* Hack: don't calculate for autogen entries; it makes writing Catalog.xml * take way too long. (Tournamix 4 Sample.crs takes me ~10s.) */ if( !pSteps->IsAutogen() && e->ContainsTransformOrTurn() ) { NoteData nd; pSteps->GetNoteData( nd ); RadarValues rv_orig; NoteDataUtil::CalculateRadarValues( nd, e->pSong->MusicLengthSeconds(), rv_orig ); PlayerOptions po; po.FromString( e->Modifiers ); if( po.ContainsTransformOrTurn() ) NoteDataUtil::TransformNoteData( nd, po, pSteps->m_StepsType ); NoteDataUtil::TransformNoteData( nd, e->Attacks, pSteps->m_StepsType, e->pSong ); RadarValues transformed_rv; NoteDataUtil::CalculateRadarValues( nd, e->pSong->MusicLengthSeconds(), transformed_rv ); rv += transformed_rv; } else { rv += pSteps->GetRadarValues(); } } /* Hack: SetRadarValues is non-const (a const setter doesn't * make sense), but it only modifies a mutable value. Just * cast away const. */ const_cast<Trail*>(this)->SetRadarValues( rv ); return m_CachedRadarValues; } }
XNode *HighScoreImpl::CreateNode() const { XNode *pNode = new XNode( "HighScore" ); const bool bWriteSimpleValues = RadarValues::WRITE_SIMPLE_VALIES; const bool bWriteComplexValues = RadarValues::WRITE_COMPLEX_VALIES; // TRICKY: Don't write "name to fill in" markers. pNode->AppendChild( "Name", IsRankingToFillIn(sName) ? RString("") : sName ); pNode->AppendChild( "Grade", GradeToString(grade) ); pNode->AppendChild( "Score", iScore ); pNode->AppendChild( "PercentDP", fPercentDP ); pNode->AppendChild( "SurviveSeconds", fSurviveSeconds ); pNode->AppendChild( "MaxCombo", iMaxCombo ); pNode->AppendChild( "StageAward", StageAwardToString(stageAward) ); pNode->AppendChild( "PeakComboAward", PeakComboAwardToString(peakComboAward) ); pNode->AppendChild( "Modifiers", sModifiers ); pNode->AppendChild( "DateTime", dateTime.GetString() ); pNode->AppendChild( "PlayerGuid", sPlayerGuid ); pNode->AppendChild( "MachineGuid", sMachineGuid ); pNode->AppendChild( "ProductID", iProductID ); XNode* pTapNoteScores = pNode->AppendChild( "TapNoteScores" ); FOREACH_ENUM( TapNoteScore, tns ) if( tns != TNS_None ) // HACK: don't save meaningless "none" count pTapNoteScores->AppendChild( TapNoteScoreToString(tns), iTapNoteScores[tns] ); XNode* pHoldNoteScores = pNode->AppendChild( "HoldNoteScores" ); FOREACH_ENUM( HoldNoteScore, hns ) if( hns != HNS_None ) // HACK: don't save meaningless "none" count pHoldNoteScores->AppendChild( HoldNoteScoreToString(hns), iHoldNoteScores[hns] ); pNode->AppendChild( radarValues.CreateNode(bWriteSimpleValues, bWriteComplexValues) ); pNode->AppendChild( "LifeRemainingSeconds", fLifeRemainingSeconds ); pNode->AppendChild( "Disqualified", bDisqualified); return pNode; }
void HighScoreImpl::LoadFromNode( const XNode *pNode ) { ASSERT( pNode->GetName() == "HighScore" ); RString s; pNode->GetChildValue( "Name", sName ); pNode->GetChildValue( "Grade", s ); grade = StringToGrade( s ); pNode->GetChildValue( "Score", iScore ); pNode->GetChildValue( "PercentDP", fPercentDP ); pNode->GetChildValue( "SurviveSeconds", fSurviveSeconds ); pNode->GetChildValue( "MaxCombo", iMaxCombo ); pNode->GetChildValue( "StageAward", s ); stageAward = StringToStageAward(s); pNode->GetChildValue( "PeakComboAward", s ); peakComboAward = StringToPeakComboAward(s); pNode->GetChildValue( "Modifiers", sModifiers ); pNode->GetChildValue( "DateTime", s ); dateTime.FromString( s ); pNode->GetChildValue( "PlayerGuid", sPlayerGuid ); pNode->GetChildValue( "MachineGuid", sMachineGuid ); pNode->GetChildValue( "ProductID", iProductID ); const XNode* pTapNoteScores = pNode->GetChild( "TapNoteScores" ); if( pTapNoteScores ) FOREACH_ENUM( TapNoteScore, tns ) pTapNoteScores->GetChildValue( TapNoteScoreToString(tns), iTapNoteScores[tns] ); const XNode* pHoldNoteScores = pNode->GetChild( "HoldNoteScores" ); if( pHoldNoteScores ) FOREACH_ENUM( HoldNoteScore, hns ) pHoldNoteScores->GetChildValue( HoldNoteScoreToString(hns), iHoldNoteScores[hns] ); const XNode* pRadarValues = pNode->GetChild( "RadarValues" ); if( pRadarValues ) radarValues.LoadFromNode( pRadarValues ); pNode->GetChildValue( "LifeRemainingSeconds", fLifeRemainingSeconds ); pNode->GetChildValue( "Disqualified", bDisqualified); // Validate input. grade = clamp( grade, Grade_Tier01, Grade_Failed ); }