From 807e24827cf24d8b7ca59bc411eec71e172669b0 Mon Sep 17 00:00:00 2001 From: Steve Checkoway Date: Mon, 17 Jul 2006 00:54:19 +0000 Subject: [PATCH] Keep a (nonconst) reference to a NoteData rather than owning the NoteData. Replace calls to Load( nd ) by making the changes to the underlying NoteData and calling Load(). (This breaks other code, commits coming.) --- stepmania/src/Player.cpp | 156 ++++++++++++++++++++------------------- stepmania/src/Player.h | 21 ++++-- 2 files changed, 95 insertions(+), 82 deletions(-) diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index 1e34e99893..4c3b76cddb 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -61,7 +61,7 @@ float AdjustedWindowSeconds( TimingWindow tw ) #define ADJUSTED_WINDOW_SECONDS( tw ) AdjustedWindowSeconds( tw ) -Player::Player( bool bShowNoteField, bool bShowJudgment ) +Player::Player( NoteData &nd, bool bShowNoteField, bool bShowJudgment ) : m_NoteData(nd) { m_bLoaded = false; @@ -318,7 +318,7 @@ void Player::Init( m_pNoteField->Init( m_pPlayerState, m_fNoteFieldHeight ); } -void Player::Load( const NoteData& noteData ) +void Player::Load() { m_bLoaded = true; @@ -326,16 +326,13 @@ void Player::Load( const NoteData& noteData ) m_iRowLastCrossed = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ) - 1; // why this? m_iMineRowLastCrossed = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ) - 1; // why this? + m_iRowLastJudged = m_iRowLastCrossed; // TODO: Remove use of PlayerNumber. PlayerNumber pn = m_pPlayerState->m_PlayerNumber; - // init steps - m_NoteData.Init(); bool bOniDead = GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && (m_pPlayerStageStats == NULL || m_pPlayerStageStats->bFailed); - if( !bOniDead ) - m_NoteData.CopyAll( noteData ); /* The editor reuses Players ... so we really need to make sure everything * is reset and not tweening. Perhaps ActorFrame should recurse to subactors; @@ -533,6 +530,8 @@ void Player::Update( float fDeltaTime ) // Check for TapNote misses // UpdateTapNotesMissedOlderThan( GetMaxStepDistanceSeconds() ); + // Check for completely judged rows. + UpdateJudgedRows(); // // update pressed flag @@ -1227,30 +1226,6 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld ) } } - if( score == TNS_HitMine ) - { - if( tn.bKeysound && tn.iKeysoundIndex < (int) m_vKeysounds.size() ) - m_vKeysounds[tn.iKeysoundIndex].Play(); - else - m_soundMine.Play(); - - if( m_pLifeMeter ) - m_pLifeMeter->ChangeLife( score ); - if( m_pScoreDisplay ) - m_pScoreDisplay->OnJudgment( score ); - if( m_pSecondaryScoreDisplay ) - m_pSecondaryScoreDisplay->OnJudgment( score ); - // TODO: Remove use of PlayerNumber - PlayerNumber pn = m_pPlayerState->m_PlayerNumber; - if( m_pCombinedLifeMeter ) - m_pCombinedLifeMeter->ChangeLife( pn, score ); - - tn.result.bHidden = true; - m_NoteData.SetTapNote( col, iIndexOverlappingNote, tn ); - if( m_pNoteField ) - m_pNoteField->DidTapNote( col, score, false ); - } - if( m_pPlayerState->m_PlayerController == PC_HUMAN && score >= TNS_W3 ) AdjustSync::HandleAutosync( fNoteOffset ); @@ -1270,27 +1245,9 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld ) m_NoteData.SetTapNote( col, iIndexOverlappingNote, tn ); - - // TODO: Remove use of PlayerNumber. - PlayerNumber pn = m_pPlayerState->m_PlayerNumber; - // Keep this here so we get the same data as Autosync - NSMAN->ReportTiming( fNoteOffset,pn ); + NSMAN->ReportTiming( fNoteOffset, m_pPlayerState->m_PlayerNumber ); - if( m_pPrimaryScoreKeeper ) - m_pPrimaryScoreKeeper->HandleTapScore( tn ); - if( m_pSecondaryScoreKeeper ) - m_pSecondaryScoreKeeper->HandleTapScore( tn ); - - switch( tn.type ) - { - case TapNote::tap: - case TapNote::hold_head: - // don't judge the row if this note is a mine or tap attack - if( NoteDataWithScoring::IsRowCompletelyJudged( m_NoteData, iIndexOverlappingNote ) ) - OnRowCompletelyJudged( iIndexOverlappingNote ); - } - m_LastTapNoteScore = score; } @@ -1307,7 +1264,7 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld ) * backwards indefinitely, and ignore grading. */ if( iIndexOverlappingNote == -1 ) iIndexOverlappingNote = GetClosestNote( col, BeatToNoteRow(fSongBeat), - iStepSearchRows, MAX_NOTE_ROW, true ); + iStepSearchRows, MAX_NOTE_ROW, true ); if( iIndexOverlappingNote != -1 ) { TapNote tn = m_NoteData.GetTapNote( col, iIndexOverlappingNote ); @@ -1319,7 +1276,7 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld ) void Player::DisplayJudgedRow( int iIndexThatWasSteppedOn, TapNoteScore score, int iTrack ) { - TapNote tn = m_NoteData.GetTapNote(iTrack, iIndexThatWasSteppedOn); + TapNote tn = m_NoteData.GetTapNote( iTrack, iIndexThatWasSteppedOn ); // If the score is W3 or better, remove the note from the screen to // indicate success. (Or always if blind is on.) @@ -1331,17 +1288,10 @@ void Player::DisplayJudgedRow( int iIndexThatWasSteppedOn, TapNoteScore score, i // show the ghost arrow for this column bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; - if (m_pPlayerState->m_PlayerOptions.m_fBlind) - { - if( m_pNoteField ) - m_pNoteField->DidTapNote( iTrack, TNS_W1, bBright ); - } - else - { - bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; - if( m_pNoteField ) - m_pNoteField->DidTapNote( iTrack, score, bBright ); - } + + bBright = bBright || m_pPlayerState->m_PlayerOptions.m_fBlind; + if( m_pNoteField ) + m_pNoteField->DidTapNote( iTrack, TNS_W1, bBright ); } void Player::OnRowCompletelyJudged( int iIndexThatWasSteppedOn ) @@ -1351,10 +1301,11 @@ void Player::OnRowCompletelyJudged( int iIndexThatWasSteppedOn ) /* Find the final score of the row. This will never be TNS_None, since this * function is only called when a row is completed. */ const Game *pCurGame = GAMESTATE->m_pCurGame; + PlayerNumber pn = m_pPlayerState->m_PlayerNumber; if( !pCurGame->m_bCountNotesSeparately ) { - TapNoteResult tnr = NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, iIndexThatWasSteppedOn ).result; + TapNoteResult tnr = NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, iIndexThatWasSteppedOn, pn ).result; TapNoteScore score = tnr.tns; ASSERT( score != TNS_None ); @@ -1366,11 +1317,12 @@ void Player::OnRowCompletelyJudged( int iIndexThatWasSteppedOn ) for( int c=0; cTrace( "iStartCheckingAt: %d iMissIfOlderThanThisIndex: %d", iStartCheckingAt, iMissIfOlderThanThisIndex ); @@ -1433,7 +1385,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) { /* XXX: cleaner to pick the things we do want to apply misses to, instead of * the things we don't? */ - TapNote tn = m_NoteData.GetTapNote(t, r); + TapNote tn = m_NoteData.GetTapNote( t, r ); switch( tn.type ) { case TapNote::empty: @@ -1441,7 +1393,9 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) continue; /* no note here */ } if( tn.result.tns != TNS_None ) /* note here is already hit */ - continue; + continue; + if( tn.pn != PLAYER_INVALID && tn.pn != m_pPlayerState->m_PlayerNumber ) + continue; if( tn.type == TapNote::mine ) { @@ -1476,11 +1430,26 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) } } +void Player::UpdateJudgedRows() +{ + const int iRow = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + PlayerNumber pn = m_pPlayerState->m_PlayerNumber; + + while( m_iRowLastJudged <= iRow ) + { + if( !NoteDataWithScoring::IsRowCompletelyJudged(m_NoteData, m_iRowLastJudged+1, pn) ) + break; + ++m_iRowLastJudged; + if( NoteDataWithScoring::LastTapNoteWithResult(m_NoteData, m_iRowLastJudged, pn).result.tns == TNS_None ) + continue; + OnRowCompletelyJudged( m_iRowLastJudged ); + } +} void Player::CrossedRow( int iNoteRow ) { // If we're doing random vanish, randomise notes on the fly. - if(m_pPlayerState->m_CurrentPlayerOptions.m_fAppearances[PlayerOptions::APPEARANCE_RANDOMVANISH]==1) + if( m_pPlayerState->m_CurrentPlayerOptions.m_fAppearances[PlayerOptions::APPEARANCE_RANDOMVANISH]==1 ) RandomizeNotes( iNoteRow ); // check to see if there's a note at the crossed row @@ -1561,7 +1530,8 @@ void Player::RandomizeNotes( int iNoteRow ) void Player::HandleTapRowScore( unsigned row ) { - const TapNote &lastTN = NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, row ); + PlayerNumber pn = m_pPlayerState->m_PlayerNumber; + const TapNote &lastTN = NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, row, pn ); TapNoteScore scoreOfLastTap = lastTN.result.tns; bool NoCheating = true; @@ -1608,7 +1578,41 @@ void Player::HandleTapRowScore( unsigned row ) /* The score keeper updates the hit combo. Remember the old combo for handling announcers. */ const int iOldCombo = iCurCombo; - + + for( int track = 0; track < m_NoteData.GetNumTracks(); ++track ) + { + const TapNote &tn = m_NoteData.GetTapNote( track, row ); + if( tn.pn != PLAYER_INVALID && tn.pn != pn ) + continue; + if( tn.result.tns == TNS_HitMine ) + { + if( tn.bKeysound && tn.iKeysoundIndex < (int) m_vKeysounds.size() ) + m_vKeysounds[tn.iKeysoundIndex].Play(); + else + m_soundMine.Play(); + + if( m_pLifeMeter ) + m_pLifeMeter->ChangeLife( tn.result.tns ); + if( m_pScoreDisplay ) + m_pScoreDisplay->OnJudgment( tn.result.tns ); + if( m_pSecondaryScoreDisplay ) + m_pSecondaryScoreDisplay->OnJudgment( tn.result.tns ); + if( m_pCombinedLifeMeter ) + m_pCombinedLifeMeter->ChangeLife( pn, tn.result.tns ); + + TapNote tn2 = tn; + tn2.result.bHidden = true; + m_NoteData.SetTapNote( track, row, tn2 ); + if( m_pNoteField ) + m_pNoteField->DidTapNote( track, tn.result.tns, false ); + } + + if( m_pPrimaryScoreKeeper ) + m_pPrimaryScoreKeeper->HandleTapScore( tn ); + if( m_pSecondaryScoreKeeper ) + m_pSecondaryScoreKeeper->HandleTapScore( tn ); + } + if( m_pPrimaryScoreKeeper != NULL ) m_pPrimaryScoreKeeper->HandleTapRowScore( m_NoteData, row ); if( m_pSecondaryScoreKeeper != NULL ) @@ -1660,9 +1664,6 @@ void Player::HandleTapRowScore( unsigned row ) if( m_pPlayerStageStats ) m_pPlayerStageStats->UpdateComboList( STATSMAN->m_CurStageStats.fStepsSeconds, false ); - // TODO: Remove use of PlayerNumber. - PlayerNumber pn = m_pPlayerState->m_PlayerNumber; - float life = -1; if( m_pLifeMeter ) { @@ -1699,6 +1700,7 @@ void Player::HandleTapRowScore( unsigned row ) if( m_pCombinedLifeMeter ) { m_pCombinedLifeMeter->ChangeLife( pn, scoreOfLastTap ); + // TODO: Remove use of PlayerNumber. m_pCombinedLifeMeter->OnDancePointsChange( pn ); // update oni life meter } } diff --git a/stepmania/src/Player.h b/stepmania/src/Player.h index 01aeeb2a9d..0bc9b0f20c 100644 --- a/stepmania/src/Player.h +++ b/stepmania/src/Player.h @@ -39,7 +39,8 @@ AutoScreenMessage( SM_MissComboAborted ); class Player: public ActorFrame { public: - Player( bool bShowNoteField = true, bool bShowJudgment = true ); + // The passed in NoteData isn't touched until Load() is called. + Player( NoteData &nd, bool bShowNoteField = true, bool bShowJudgment = true ); ~Player(); virtual void Update( float fDeltaTime ); @@ -57,7 +58,7 @@ public: Inventory* pInventory, ScoreKeeper* pPrimaryScoreKeeper, ScoreKeeper* pSecondaryScoreKeeper ); - void Load( const NoteData& noteData ); + void Load(); void CrossedRow( int iNoteRow ); void CrossedMineRow( int iNoteRow ); void Step( int col, const RageTimer &tm, bool bHeld = false ); @@ -72,13 +73,13 @@ public: // Returns -1 if no notes are close, otherwise return the distance to a nongraded note. int GetClosestNoteDistance( int col, int row ) const; - NoteData m_NoteData; - + const NoteData &GetNoteData() const { return m_NoteData; } bool HasNoteField() { return m_pNoteField != NULL; } protected: void HandleStep( int col, const RageTimer &tm, bool bHeld ); void UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat ); + void UpdateJudgedRows(); void DisplayJudgedRow( int iIndexThatWasSteppedOn, TapNoteScore score, int iTrack ); void OnRowCompletelyJudged( int iStepIndex ); void HandleTapRowScore( unsigned row ); @@ -96,11 +97,12 @@ protected: bool m_bLoaded; PlayerState *m_pPlayerState; - PlayerStageStats*m_pPlayerStageStats; + PlayerStageStats *m_pPlayerStageStats; float m_fNoteFieldHeight; bool m_bPaused; + NoteData &m_NoteData; NoteField *m_pNoteField; vector m_vHoldJudgment; @@ -123,6 +125,7 @@ protected: int m_iRowLastCrossed; int m_iMineRowLastCrossed; + int m_iRowLastJudged; // Everything up to and including this row has been judged. RageSound m_soundMine; RageSound m_soundAttackLaunch; @@ -155,6 +158,14 @@ protected: TweenState m_tsJudgment[NUM_REVERSE][NUM_CENTERED]; }; +class PlayerPlus : public Player +{ + NoteData m_NoteData; +public: + PlayerPlus() : Player(m_NoteData) { } + void Load( const NoteData &nd ) { m_NoteData = nd; Player::Load(); } +}; + #endif /*