Use a map for hold grades, so it doesn't get desynced if the number

of hold notes changes.
This commit is contained in:
Glenn Maynard
2003-12-16 06:10:50 +00:00
parent 1f5e97f975
commit cd0162cff3
4 changed files with 40 additions and 45 deletions
+17 -14
View File
@@ -100,7 +100,9 @@ int NoteDataWithScoring::GetNumHoldNotesWithScore( HoldNoteScore hns, const floa
for( int i=0; i<GetNumHoldNotes(); i++ ) for( int i=0; i<GetNumHoldNotes(); i++ )
{ {
const HoldNote &hn = GetHoldNote(i); const HoldNote &hn = GetHoldNote(i);
if( iStartIndex <= hn.iStartRow && hn.iEndRow <= iEndIndex && m_HoldNoteScores[i] == hns ) if( iStartIndex > hn.iStartRow || hn.iEndRow > iEndIndex )
continue;
if( GetHoldNoteScore(hn) == hns )
iNumSuccessfulHolds++; iNumSuccessfulHolds++;
} }
return iNumSuccessfulHolds; return iNumSuccessfulHolds;
@@ -315,29 +317,30 @@ void NoteDataWithScoring::SetTapNoteOffset(unsigned track, unsigned row, float o
m_TapNoteOffset[track][row] = offset; m_TapNoteOffset[track][row] = offset;
} }
HoldNoteScore NoteDataWithScoring::GetHoldNoteScore(unsigned h) const /* 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
{ {
if(h >= m_HoldNoteScores.size()) map<RowTrack, HoldNoteScore>::const_iterator it = m_HoldNoteScores.find( RowTrack(hn.iEndRow, hn.iTrack) );
if( it == m_HoldNoteScores.end() )
return HNS_NONE; return HNS_NONE;
return m_HoldNoteScores[h]; return it->second;
} }
void NoteDataWithScoring::SetHoldNoteScore(unsigned h, HoldNoteScore hns) void NoteDataWithScoring::SetHoldNoteScore( const HoldNote &hn, HoldNoteScore hns )
{ {
extend(m_HoldNoteScores, HNS_NONE, h); m_HoldNoteScores[RowTrack(hn.iEndRow, hn.iTrack)] = hns;
m_HoldNoteScores[h] = hns;
} }
void NoteDataWithScoring::SetHoldNoteLife(unsigned h, float f) void NoteDataWithScoring::SetHoldNoteLife( const HoldNote &hn, float f )
{ {
extend(m_fHoldNoteLife, 1.0f, h); m_fHoldNoteLife[RowTrack(hn.iEndRow, hn.iTrack)] = f;
m_fHoldNoteLife[h] = f;
} }
float NoteDataWithScoring::GetHoldNoteLife(unsigned h) const float NoteDataWithScoring::GetHoldNoteLife( const HoldNote &hn ) const
{ {
// start with full life map<RowTrack, float>::const_iterator it = m_fHoldNoteLife.find( RowTrack(hn.iEndRow, hn.iTrack) );
if(h >= m_fHoldNoteLife.size()) if( it == m_fHoldNoteLife.end() )
return 1.0f; return 1.0f;
return m_fHoldNoteLife[h]; return it->second;
} }
+9 -6
View File
@@ -14,12 +14,14 @@
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
#include "NoteData.h" #include "NoteData.h"
#include "PlayerNumber.h" #include "PlayerNumber.h"
#include <map>
class NoteDataWithScoring : public NoteData class NoteDataWithScoring : public NoteData
{ {
// maintain this extra data in addition to the NoteData // maintain this extra data in addition to the NoteData
vector<TapNoteScore> m_TapNoteScores[MAX_NOTE_TRACKS]; vector<TapNoteScore> m_TapNoteScores[MAX_NOTE_TRACKS];
vector<HoldNoteScore> m_HoldNoteScores; typedef pair<int,int> RowTrack;
map<RowTrack, HoldNoteScore> m_HoldNoteScores;
/* Offset, in seconds, for each tap grade. Negative numbers mean the note /* Offset, in seconds, for each tap grade. Negative numbers mean the note
* was hit early; positive numbers mean it was hit late. These values are * was hit early; positive numbers mean it was hit late. These values are
@@ -30,7 +32,7 @@ class NoteDataWithScoring : public NoteData
* 0.0 means this HoldNote is dead * 0.0 means this HoldNote is dead
* When this value hits 0.0 for the first time, m_HoldScore becomes HSS_NG. * When this value hits 0.0 for the first time, m_HoldScore becomes HSS_NG.
* If the life is > 0.0 when the HoldNote ends, then m_HoldScore becomes HSS_OK. */ * If the life is > 0.0 when the HoldNote ends, then m_HoldScore becomes HSS_OK. */
vector<float> m_fHoldNoteLife; map<RowTrack, float> m_fHoldNoteLife;
public: public:
NoteDataWithScoring(); NoteDataWithScoring();
@@ -46,10 +48,11 @@ public:
void SetTapNoteScore(unsigned track, unsigned row, TapNoteScore tns); void SetTapNoteScore(unsigned track, unsigned row, TapNoteScore tns);
float GetTapNoteOffset(unsigned track, unsigned row) const; float GetTapNoteOffset(unsigned track, unsigned row) const;
void SetTapNoteOffset(unsigned track, unsigned row, float offset); void SetTapNoteOffset(unsigned track, unsigned row, float offset);
HoldNoteScore GetHoldNoteScore(unsigned h) const;
void SetHoldNoteScore(unsigned h, HoldNoteScore hns); HoldNoteScore GetHoldNoteScore( const HoldNote &hn ) const;
float GetHoldNoteLife(unsigned h) const; void SetHoldNoteScore( const HoldNote &hn, HoldNoteScore hns );
void SetHoldNoteLife(unsigned h, float f); float GetHoldNoteLife( const HoldNote &hn ) const;
void SetHoldNoteLife( const HoldNote &hn, float f );
bool IsRowCompletelyJudged(unsigned row) const; bool IsRowCompletelyJudged(unsigned row) const;
TapNoteScore MinTapNoteScore(unsigned row) const; TapNoteScore MinTapNoteScore(unsigned row) const;
+2 -2
View File
@@ -517,8 +517,8 @@ void NoteField::DrawPrimitives()
for( i=0; i < GetNumHoldNotes(); i++ ) for( i=0; i < GetNumHoldNotes(); i++ )
{ {
const HoldNote &hn = GetHoldNote(i); const HoldNote &hn = GetHoldNote(i);
const HoldNoteScore hns = GetHoldNoteScore(i); const HoldNoteScore hns = GetHoldNoteScore( hn );
const float fLife = GetHoldNoteLife(i); const float fLife = GetHoldNoteLife( hn );
const bool bIsHoldingNote = (i < int(m_bIsHoldingHoldNote.size()))? const bool bIsHoldingNote = (i < int(m_bIsHoldingHoldNote.size()))?
m_bIsHoldingHoldNote[i]: false; m_bIsHoldingHoldNote[i]: false;
+12 -23
View File
@@ -281,22 +281,25 @@ void PlayerMinus::Update( float fDeltaTime )
for( int i=0; i < GetNumHoldNotes(); i++ ) // for each HoldNote for( int i=0; i < GetNumHoldNotes(); i++ ) // for each HoldNote
{ {
const HoldNote &hn = GetHoldNote(i); const HoldNote &hn = GetHoldNote(i);
HoldNoteScore hns = GetHoldNoteScore(i); HoldNoteScore hns = GetHoldNoteScore(hn);
float fLife = GetHoldNoteLife(i);
int iHoldStartIndex = hn.iStartRow;
m_pNoteField->m_bIsHoldingHoldNote[i] = false; // set host flag so NoteField can do intelligent drawing m_pNoteField->m_bIsHoldingHoldNote[i] = false; // set host flag so NoteField can do intelligent drawing
if( hns != HNS_NONE ) // if this HoldNote already has a result if( hns != HNS_NONE ) // if this HoldNote already has a result
continue; // we don't need to update the logic for this one continue; // we don't need to update the logic for this one
if( iSongRow < hn.iStartRow )
continue; // hold hasn't happened yet
const StyleInput StyleI( m_PlayerNumber, hn.iTrack ); const StyleInput StyleI( m_PlayerNumber, hn.iTrack );
const GameInput GameI = GAMESTATE->GetCurrentStyleDef()->StyleInputToGameInput( StyleI ); const GameInput GameI = GAMESTATE->GetCurrentStyleDef()->StyleInputToGameInput( StyleI );
// if they got a bad score or haven't stepped on the corresponding tap yet // if they got a bad score or haven't stepped on the corresponding tap yet
const TapNoteScore tns = GetTapNoteScore(hn.iTrack, iHoldStartIndex); const TapNoteScore tns = GetTapNoteScore( hn.iTrack, hn.iStartRow );
const bool bSteppedOnTapNote = tns != TNS_NONE && tns != TNS_MISS; // did they step on the start of this hold? const bool bSteppedOnTapNote = tns != TNS_NONE && tns != TNS_MISS; // did they step on the start of this hold?
float fLife = GetHoldNoteLife(hn);
// If the song beat is in the range of this hold: // If the song beat is in the range of this hold:
if( hn.iStartRow <= iSongRow && iSongRow <= hn.iEndRow ) if( hn.iStartRow <= iSongRow && iSongRow <= hn.iEndRow )
{ {
@@ -312,12 +315,7 @@ void PlayerMinus::Update( float fDeltaTime )
if( bSteppedOnTapNote ) // this note is not judged and we stepped on its head if( bSteppedOnTapNote ) // this note is not judged and we stepped on its head
{ {
// Move the start of this Hold // Move the start of this Hold
// m_pNoteField->GetHoldNote(i).iStartRow = min( iSongRow, m_pNoteField->GetHoldNote(i).iEndRow );
// IMPORTANT: Every HoldNote::fStartBeat must be at least 1 index less than
// its HoldNote::fEndBeat. Otherwise, when HoldNotes are converted to the
// 4s representation, it disappears, which causes problems for the way we
// store HoldNote life (by index of the hold).
m_pNoteField->GetHoldNote(i).iStartRow = min( iSongRow, m_pNoteField->GetHoldNote(i).iEndRow-1 );
} }
if( bSteppedOnTapNote && bIsHoldingButton ) if( bSteppedOnTapNote && bIsHoldingButton )
@@ -368,11 +366,11 @@ void PlayerMinus::Update( float fDeltaTime )
m_ProTimingDisplay.SetJudgment( ms_error, TNS_MISS ); m_ProTimingDisplay.SetJudgment( ms_error, TNS_MISS );
} }
m_pNoteField->SetHoldNoteLife(i, fLife); // update the NoteField display m_pNoteField->SetHoldNoteLife(hn, fLife); // update the NoteField display
m_pNoteField->SetHoldNoteScore(i, hns); // update the NoteField display m_pNoteField->SetHoldNoteScore(hn, hns); // update the NoteField display
SetHoldNoteLife(i, fLife); SetHoldNoteLife(hn, fLife);
SetHoldNoteScore(i, hns); SetHoldNoteScore(hn, hns);
} }
// Why was this originally "BeatToNoteRowNotRounded"? It should be rounded. -Chris // Why was this originally "BeatToNoteRowNotRounded"? It should be rounded. -Chris
@@ -398,15 +396,6 @@ void PlayerMinus::Update( float fDeltaTime )
po.m_sNoteSkin = ""; po.m_sNoteSkin = "";
po.FromString( mod.sModifier ); po.FromString( mod.sModifier );
/* Note that runtime effects like these currently must not change hold
* notes. CopyRange below converts through 4s, which means the hold note
* array will be reconstructed; if hold notes end up in a different order,
* they won't align with this->m_HoldNoteScores. */
if( po.m_bTransforms[PlayerOptions::TRANSFORM_NOHOLDS] )
RageException::Throw("Can't use NoHolds as a battle attack");
if( po.m_bTransforms[PlayerOptions::TRANSFORM_NOMINES] )
RageException::Throw("Can't use NoMines as a battle attack");
float fStartBeat, fEndBeat; float fStartBeat, fEndBeat;
mod.GetAttackBeats( GAMESTATE->m_pCurSong, m_PlayerNumber, fStartBeat, fEndBeat ); mod.GetAttackBeats( GAMESTATE->m_pCurSong, m_PlayerNumber, fStartBeat, fEndBeat );
fEndBeat = min( fEndBeat, GetMaxBeat() ); fEndBeat = min( fEndBeat, GetMaxBeat() );