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++ )
{
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++;
}
return iNumSuccessfulHolds;
@@ -315,29 +317,30 @@ void NoteDataWithScoring::SetTapNoteOffset(unsigned track, unsigned row, float o
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 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[h] = hns;
m_HoldNoteScores[RowTrack(hn.iEndRow, hn.iTrack)] = hns;
}
void NoteDataWithScoring::SetHoldNoteLife(unsigned h, float f)
void NoteDataWithScoring::SetHoldNoteLife( const HoldNote &hn, float f )
{
extend(m_fHoldNoteLife, 1.0f, h);
m_fHoldNoteLife[h] = f;
m_fHoldNoteLife[RowTrack(hn.iEndRow, hn.iTrack)] = f;
}
float NoteDataWithScoring::GetHoldNoteLife(unsigned h) const
float NoteDataWithScoring::GetHoldNoteLife( const HoldNote &hn ) const
{
// start with full life
if(h >= m_fHoldNoteLife.size())
map<RowTrack, float>::const_iterator it = m_fHoldNoteLife.find( RowTrack(hn.iEndRow, hn.iTrack) );
if( it == m_fHoldNoteLife.end() )
return 1.0f;
return m_fHoldNoteLife[h];
return it->second;
}
+9 -6
View File
@@ -14,12 +14,14 @@
#include "GameConstantsAndTypes.h"
#include "NoteData.h"
#include "PlayerNumber.h"
#include <map>
class NoteDataWithScoring : public NoteData
{
// maintain this extra data in addition to the NoteData
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
* 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
* 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. */
vector<float> m_fHoldNoteLife;
map<RowTrack, float> m_fHoldNoteLife;
public:
NoteDataWithScoring();
@@ -46,10 +48,11 @@ public:
void SetTapNoteScore(unsigned track, unsigned row, TapNoteScore tns);
float GetTapNoteOffset(unsigned track, unsigned row) const;
void SetTapNoteOffset(unsigned track, unsigned row, float offset);
HoldNoteScore GetHoldNoteScore(unsigned h) const;
void SetHoldNoteScore(unsigned h, HoldNoteScore hns);
float GetHoldNoteLife(unsigned h) const;
void SetHoldNoteLife(unsigned h, float f);
HoldNoteScore GetHoldNoteScore( const HoldNote &hn ) const;
void SetHoldNoteScore( const HoldNote &hn, HoldNoteScore hns );
float GetHoldNoteLife( const HoldNote &hn ) const;
void SetHoldNoteLife( const HoldNote &hn, float f );
bool IsRowCompletelyJudged(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++ )
{
const HoldNote &hn = GetHoldNote(i);
const HoldNoteScore hns = GetHoldNoteScore(i);
const float fLife = GetHoldNoteLife(i);
const HoldNoteScore hns = GetHoldNoteScore( hn );
const float fLife = GetHoldNoteLife( hn );
const bool bIsHoldingNote = (i < int(m_bIsHoldingHoldNote.size()))?
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
{
const HoldNote &hn = GetHoldNote(i);
HoldNoteScore hns = GetHoldNoteScore(i);
float fLife = GetHoldNoteLife(i);
int iHoldStartIndex = hn.iStartRow;
HoldNoteScore hns = GetHoldNoteScore(hn);
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
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 GameInput GameI = GAMESTATE->GetCurrentStyleDef()->StyleInputToGameInput( StyleI );
// 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?
float fLife = GetHoldNoteLife(hn);
// If the song beat is in the range of this hold:
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
{
// Move the start of this Hold
//
// 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 );
m_pNoteField->GetHoldNote(i).iStartRow = min( iSongRow, m_pNoteField->GetHoldNote(i).iEndRow );
}
if( bSteppedOnTapNote && bIsHoldingButton )
@@ -368,11 +366,11 @@ void PlayerMinus::Update( float fDeltaTime )
m_ProTimingDisplay.SetJudgment( ms_error, TNS_MISS );
}
m_pNoteField->SetHoldNoteLife(i, fLife); // update the NoteField display
m_pNoteField->SetHoldNoteScore(i, hns); // update the NoteField display
m_pNoteField->SetHoldNoteLife(hn, fLife); // update the NoteField display
m_pNoteField->SetHoldNoteScore(hn, hns); // update the NoteField display
SetHoldNoteLife(i, fLife);
SetHoldNoteScore(i, hns);
SetHoldNoteLife(hn, fLife);
SetHoldNoteScore(hn, hns);
}
// Why was this originally "BeatToNoteRowNotRounded"? It should be rounded. -Chris
@@ -398,15 +396,6 @@ void PlayerMinus::Update( float fDeltaTime )
po.m_sNoteSkin = "";
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;
mod.GetAttackBeats( GAMESTATE->m_pCurSong, m_PlayerNumber, fStartBeat, fEndBeat );
fEndBeat = min( fEndBeat, GetMaxBeat() );