Use a map for hold grades, so it doesn't get desynced if the number
of hold notes changes.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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() );
|
||||
|
||||
Reference in New Issue
Block a user