diff --git a/stepmania/src/NoteData.cpp b/stepmania/src/NoteData.cpp index 04136ff9b0..d6f5fc9ea4 100644 --- a/stepmania/src/NoteData.cpp +++ b/stepmania/src/NoteData.cpp @@ -174,40 +174,66 @@ void NoteData::RemoveHoldNote( int iHoldIndex ) m_HoldNotes.erase(m_HoldNotes.begin()+iHoldIndex, m_HoldNotes.begin()+iHoldIndex+1); } -void NoteData::AddAttackNote( AttackNote an ) +void NoteData::AddAttackNote( int track, int row, Attack attack ) { - m_AttackNotes.push_back(an); -} + PruneUnusedAttacksFromMap(); -void NoteData::RemoveAttackNote( int index ) -{ - m_AttackNotes.erase( m_AttackNotes.begin()+index ); -} - -bool CompareAttackNotes( const AttackNote& an1, const AttackNote& an2 ) -{ - return an1.fBeat < an2.fBeat; -} - -void NoteData::ShuffleAttackNotesOnSameRow() -{ - // sort, then shuffle - sort( m_AttackNotes.begin(), m_AttackNotes.end(), CompareAttackNotes ); - - for( int i=0; i mapAttackToNothing; + + int max_row = GetMaxRow(); + for( int t=0; t +#include "Attack.h" class NoteData @@ -25,7 +27,7 @@ class NoteData vector m_HoldNotes; - vector m_AttackNotes; + map m_AttackMap; /* Pad m_TapNotes so it includes the row "rows". */ void PadTapNotes(int rows); @@ -134,20 +136,22 @@ public: void GetTracksHeldAtRow( int row, vector& viTracksOut ); int GetNumTracksHeldAtRow( int row ); + // // used in edit/record + // void AddHoldNote( HoldNote newNote ); // add note hold note merging overlapping HoldNotes and destroying TapNotes underneath void RemoveHoldNote( int index ); HoldNote &GetHoldNote( int index ) { return m_HoldNotes[index]; } const HoldNote &GetHoldNote( int index ) const { return m_HoldNotes[index]; } - // used in edit/record - void AddAttackNote( AttackNote an ); // add note hold note merging overlapping HoldNotes and destroying TapNotes underneath - void RemoveAttackNote( int index ); - const AttackNote& GetAttackNote( int index ) { return m_AttackNotes[index]; } - void ShuffleAttackNotesOnSameRow(); + void AddAttackNote( int track, int row, Attack attack ); + void PruneUnusedAttacksFromMap(); // slow + const Attack& GetAttackAt( int track, int row ); + // remove Attacks with SetTapNote(TAP_EMPTY) + // // statistics - + // /* Return the highest beat/row that might contain notes. (Use GetLastBeat if you need * accuracy.) */ float GetMaxBeat() const { return NoteRowToBeat(GetMaxRow()); } @@ -164,7 +168,6 @@ public: /* optimization: for the default of start to end, use the second (faster) */ int GetNumHoldNotes( const float fStartBeat, const float fEndBeat = -1 ) const; int GetNumHoldNotes() const { return m_HoldNotes.size(); } - int GetNumAttackNotes() const { return m_AttackNotes.size(); } // Transformations void LoadTransformed( const NoteData* pOriginal, int iNewNumTracks, const int iOriginalTrackToTakeFrom[] ); // -1 for iOriginalTracksToTakeFrom means no track diff --git a/stepmania/src/NoteField.cpp b/stepmania/src/NoteField.cpp index 0fe38260b0..0b01f38a6a 100644 --- a/stepmania/src/NoteField.cpp +++ b/stepmania/src/NoteField.cpp @@ -543,38 +543,24 @@ void NoteField::DrawPrimitives() bool bIsAddition = (tn == TAP_ADDITION); bool bIsMine = (tn == TAP_MINE); + bool bIsAttack = IsTapAttack(tn); SearchForBeat( CurDisplay, NextDisplay, NoteRowToBeat(i) ); NoteDisplayCols *nd = CurDisplay->second; - nd->display[c].DrawTap( c, NoteRowToBeat(i), bHoldNoteBeginsOnThisBeat, bIsAddition, bIsMine, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, 1, m_fYReverseOffsetPixels ); - } - - - // - // Draw all AttackNotes in this column - // - for( i=0; i < GetNumAttackNotes(); i++ ) - { - const AttackNote& an = GetAttackNote( i ); - - // If this AttackNote isn't on the screen, skip it - if( an.iTrack != c || - an.fBeat < fFirstBeatToDraw || - an.fBeat > fLastBeatToDraw ) - continue; // skip - - bool bIsInSelectionRange = false; - if( m_fBeginMarker!=-1 && m_fEndMarker!=-1 ) + if( bIsAttack ) { - bIsInSelectionRange = m_fBeginMarker<=an.fBeat && an.fBeat<=m_fEndMarker; + const Attack& attack = GetAttackAt( c, i ); + Sprite sprite; + sprite.Load( THEME->GetPathToG("NoteField attack "+attack.sModifier) ); + float fBeat = NoteRowToBeat(i); + SearchForBeat( CurDisplay, NextDisplay, fBeat ); + NoteDisplayCols *nd = CurDisplay->second; + nd->display[c].DrawActor( &sprite, c, fBeat, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, 1, m_fYReverseOffsetPixels ); + } + else + { + nd->display[c].DrawTap( c, NoteRowToBeat(i), bHoldNoteBeginsOnThisBeat, bIsAddition, bIsMine, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, 1, m_fYReverseOffsetPixels ); } - - - Sprite sprite; - sprite.Load( THEME->GetPathToG("NoteField attack "+an.sModifiers) ); - SearchForBeat( CurDisplay, NextDisplay, an.fBeat ); - NoteDisplayCols *nd = CurDisplay->second; - nd->display[c].DrawActor( &sprite, an.iTrack, an.fBeat, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, 1, m_fYReverseOffsetPixels ); } diff --git a/stepmania/src/NoteTypes.h b/stepmania/src/NoteTypes.h index 760a6394a2..9bc28aa6fc 100644 --- a/stepmania/src/NoteTypes.h +++ b/stepmania/src/NoteTypes.h @@ -70,6 +70,11 @@ static const TapNote TAP_REMOVED_HOLD_TAIL = '\''; // MD 11/12/03 end +// mine note - don't step! +static const TapNote TAP_ATTACK_BEGIN = 'a'; +static const TapNote TAP_ATTACK_END = 'z'; + +inline bool IsTapAttack( TapNote tn ) { return tn>=TAP_ATTACK_BEGIN && tn<=TAP_ATTACK_END; } enum { @@ -132,15 +137,6 @@ struct HoldNote float fEndBeat; }; -struct AttackNote -{ - AttackNote( int t, float b, CString m, float d ) { iTrack=t; fBeat=b; sModifiers=m; fDurationSeconds=d; } - int iTrack; - float fBeat; - CString sModifiers; - float fDurationSeconds; -}; - inline int BeatToNoteRow( float fBeatNum ) { return int( fBeatNum * ROWS_PER_BEAT + 0.5f); }; // round inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * ROWS_PER_BEAT ); }; diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index 2d405d1857..ef26900e57 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -495,6 +495,9 @@ void PlayerMinus::Step( int col, RageTimer tm ) ASSERT( col >= 0 && col <= GetNumTracks() ); + // + // Check for step on a TapNote + // int iIndexOverlappingNote = GetClosestNote( col, GAMESTATE->m_fSongBeat, StepSearchDistanceForwards * GAMESTATE->m_fCurBPS * GAMESTATE->m_SongOptions.m_fMusicRate, StepSearchDistanceBackwards * GAMESTATE->m_fCurBPS * GAMESTATE->m_SongOptions.m_fMusicRate ); @@ -557,8 +560,23 @@ void PlayerMinus::Step( int col, RageTimer tm ) } - if( tn == TAP_MINE ) + switch( tn ) { +// case TAP_ATTACK: +// // stepped too close to mine? +// if( fScaledSecondsFromPerfect <= PREFSMAN->m_fJudgeWindowAttackSeconds ) +// { +// m_soundAttack.Play(); +// score = TNS_MISS; +// // put attack in effect +// } +// else +// { +// score = TNS_NONE; +// } +// break; + + case TAP_MINE: // stepped too close to mine? if( fScaledSecondsFromPerfect <= PREFSMAN->m_fJudgeWindowMineSeconds ) { @@ -575,9 +593,9 @@ void PlayerMinus::Step( int col, RageTimer tm ) { score = TNS_NONE; } - } - else // not a mine - { + break; + + default: // not a mine if(GAMESTATE->m_CurGame == GAME_EZ2) { /* 1 is normal. 2 means scoring is half as hard; .5 means it's twice as hard. */ @@ -599,6 +617,7 @@ void PlayerMinus::Step( int col, RageTimer tm ) else if( fScaledSecondsFromPerfect <= PREFSMAN->m_fJudgeWindowBooSeconds ) score = TNS_BOO; else score = TNS_NONE; } + break; } break; } diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 5aae093ff5..361b20aaa1 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -677,17 +677,6 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ } } - // check for to see if the user intended to remove an AttackNote - for( i=0; im_PlayerOptions[PLAYER_1]; CString sMods = poChosen.GetString(); - m_NoteFieldEdit.AddAttackNote( AttackNote(g_iLastInsertAttackTrack,GAMESTATE->m_fSongBeat,sMods,g_fLastInsertAttackDurationSeconds) ); + const int iSongIndex = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + + Attack attack; + attack.level = ATTACK_LEVEL_1; // does this matter? + attack.fSecsRemaining = g_fLastInsertAttackDurationSeconds; + attack.sModifier = sMods; + + m_NoteFieldEdit.AddAttackNote( g_iLastInsertAttackTrack, iSongIndex, attack ); GAMESTATE->RestoreSelectedOptions(); // restore the edit and playback options } break;