#include "global.h" #include "NoteDataWithScoring.h" #include "GameState.h" #include "RageUtil.h" #include "StageStats.h" NoteDataWithScoring::NoteDataWithScoring() { Init(); } void NoteDataWithScoring::Init() { NoteData::Init(); for( int t=0; t= tns ) iNumSuccessfulTapNotes++; } } return iNumSuccessfulTapNotes; } int NoteDataWithScoring::GetNumNWithScore( TapNoteScore tns, int MinTaps, const float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetLastBeat(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); iStartIndex = max( iStartIndex, 0 ); iEndIndex = min( iEndIndex, GetLastRow() ); int iNumSuccessfulDoubles = 0; for( int i=iStartIndex; i<=iEndIndex; i++ ) { int iNumNotesThisIndex = 0; TapNoteScore minTapNoteScore = TNS_MARVELOUS; for( int t=0; t= MinTaps && minTapNoteScore >= tns ) iNumSuccessfulDoubles++; } return iNumSuccessfulDoubles; } int NoteDataWithScoring::GetNumHoldNotesWithScore( HoldNoteScore hns, const float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetLastBeat(); int iNumSuccessfulHolds = 0; int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); for( int i=0; i hn.iStartRow || hn.iEndRow > iEndIndex ) continue; if( GetHoldNoteScore(hn) == hns ) iNumSuccessfulHolds++; } return iNumSuccessfulHolds; } int NoteDataWithScoring::GetSuccessfulMines( float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetLastBeat(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); iStartIndex = max( iStartIndex, 0 ); iEndIndex = min( iEndIndex, GetLastRow() ); int iNumSuccessfulMinesNotes = 0; for( int i=iStartIndex; i<=iEndIndex; i++ ) { for( int t=0; tGetTapNote(t,i).type == TapNote::mine && GetTapNoteScore(t, i) != TNS_HIT_MINE ) iNumSuccessfulMinesNotes++; } } return iNumSuccessfulMinesNotes; } /* See NoteData::GetNumHands(). */ int NoteDataWithScoring::GetSuccessfulHands( float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetLastBeat(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); /* Clamp to known-good ranges. */ iStartIndex = max( iStartIndex, 0 ); iEndIndex = min( iEndIndex, GetLastRow() ); int iNum = 0; for( int i=iStartIndex; i<=iEndIndex; i++ ) { if( !RowNeedsHands(i) ) continue; bool Missed = false; for( int t=0; t= TNS_MISS; } /* Return the last tap score of a row: the grade of the tap that completed * the row. If the row has no tap notes, return -1. If any tap notes aren't * graded (any tap is TNS_NONE) or are missed (TNS_MISS), return it. */ int NoteDataWithScoring::LastTapNoteScoreTrack(unsigned row) const { float scoretime = -9999; int best_track = -1; for( int t=0; t void extend(vector &v, T val, unsigned pos) { int needed = pos - v.size() + 1; if(needed > 0) { needed += 100; /* optimization: give it a little more than it needs */ v.insert(v.end(), needed, val); } } TapNoteScore NoteDataWithScoring::GetTapNoteScore(unsigned track, unsigned row) const { if(row >= m_TapNoteScores[track].size()) return TNS_NONE; return m_TapNoteScores[track][row]; } void NoteDataWithScoring::SetTapNoteScore(unsigned track, unsigned row, TapNoteScore tns) { extend(m_TapNoteScores[track], TNS_NONE, row); m_TapNoteScores[track][row] = tns; } float NoteDataWithScoring::GetTapNoteOffset(unsigned track, unsigned row) const { if(row >= m_TapNoteOffset[track].size()) return 0; return m_TapNoteOffset[track][row]; } void NoteDataWithScoring::SetTapNoteOffset(unsigned track, unsigned row, float offset) { extend(m_TapNoteOffset[track], 0.f, row); m_TapNoteOffset[track][row] = offset; } /* We use the end row to index hold notes, instead of the start row, because the start row * changes when hold notes are being stepped on, but end rows never change. */ HoldNoteScore NoteDataWithScoring::GetHoldNoteScore( const HoldNote &hn ) const { return GetHoldNoteResult(hn).hns; } void NoteDataWithScoring::SetHoldNoteScore( const HoldNote &hn, HoldNoteScore hns ) { HoldNoteResult *hnr = CreateHoldNoteResult( hn ); hnr->hns = hns; } void NoteDataWithScoring::SetHoldNoteLife( const HoldNote &hn, float f ) { HoldNoteResult *hnr = CreateHoldNoteResult( hn ); hnr->fLife = f; } float NoteDataWithScoring::GetHoldNoteLife( const HoldNote &hn ) const { return GetHoldNoteResult(hn).fLife; } const HoldNoteResult NoteDataWithScoring::GetHoldNoteResult( const HoldNote &hn ) const { map::const_iterator it = m_HoldNoteScores.find( RowTrack(hn) ); if( it == m_HoldNoteScores.end() ) return HoldNoteResult(hn); return it->second; } HoldNoteResult *NoteDataWithScoring::CreateHoldNoteResult( const HoldNote &hn ) { map::iterator it = m_HoldNoteScores.find( RowTrack(hn) ); if( it == m_HoldNoteScores.end() ) { HoldNoteResult *ret = &m_HoldNoteScores[hn]; ret->iLastHeldRow = hn.iStartRow; return ret; } return &it->second; } HoldNoteResult::HoldNoteResult( const HoldNote &hn ) { hns = HNS_NONE; fLife = 1.0f; iLastHeldRow = hn.iStartRow; } /* * (c) 2001-2004 Chris Danford, Glenn Maynard * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, provided that the above * copyright notice(s) and this permission notice appear in all copies of * the Software and that both the above copyright notice(s) and this * permission notice appear in supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */