working on battle attacks
This commit is contained in:
@@ -174,6 +174,40 @@ void NoteData::RemoveHoldNote( int iHoldIndex )
|
||||
m_HoldNotes.erase(m_HoldNotes.begin()+iHoldIndex, m_HoldNotes.begin()+iHoldIndex+1);
|
||||
}
|
||||
|
||||
void NoteData::AddAttackNote( AttackNote an )
|
||||
{
|
||||
m_AttackNotes.push_back(an);
|
||||
}
|
||||
|
||||
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<m_AttackNotes.size(); )
|
||||
{
|
||||
// Shuffle with other AttackNotes that are on the same row.
|
||||
// Lame shuffle...
|
||||
for( int j=i+1; j<m_AttackNotes.size(); j++ )
|
||||
{
|
||||
if( m_AttackNotes[i].fBeat != m_AttackNotes[j].fBeat )
|
||||
break; // stop searching
|
||||
if( rand()%2 )
|
||||
swap( m_AttackNotes[i].fBeat, m_AttackNotes[j].fBeat );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int NoteData::GetFirstRow() const
|
||||
{
|
||||
return BeatToNoteRow( GetFirstBeat() );
|
||||
@@ -602,15 +636,6 @@ void NoteData::SetTapNote(int track, int row, TapNote t)
|
||||
m_TapNotes[track][row]=t;
|
||||
}
|
||||
|
||||
void NoteData::SetTapNoteAttack( int track, int row, CString sMods, float fDurationSeconds )
|
||||
{
|
||||
if(row < 0) return;
|
||||
|
||||
PadTapNotes(row);
|
||||
// TODO: mark as TAP_ATTACK and save attack params to array
|
||||
m_TapNotes[track][row]=TAP_TAP;
|
||||
}
|
||||
|
||||
void NoteData::EliminateAllButOneTap(int row)
|
||||
{
|
||||
if(row < 0) return;
|
||||
@@ -652,3 +677,5 @@ int NoteData::GetNumTracksHeldAtRow( int row )
|
||||
GetTracksHeldAtRow( row, viTracks );
|
||||
return viTracks.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ class NoteData
|
||||
|
||||
vector<HoldNote> m_HoldNotes;
|
||||
|
||||
vector<AttackNote> m_AttackNotes;
|
||||
|
||||
/* Pad m_TapNotes so it includes the row "rows". */
|
||||
void PadTapNotes(int rows);
|
||||
|
||||
@@ -51,8 +53,7 @@ public:
|
||||
}
|
||||
void MoveTapNoteTrack(int dest, int src);
|
||||
void SetTapNote(int track, int row, TapNote t);
|
||||
void SetTapNoteAttack( int track, int row, CString sMods, float fDurationSeconds );
|
||||
|
||||
|
||||
void ClearRange( int iNoteIndexBegin, int iNoteIndexEnd );
|
||||
void ClearAll();
|
||||
void CopyRange( const NoteData* pFrom, int iFromIndexBegin, int iFromIndexEnd, int iToIndexBegin = -1 );
|
||||
@@ -139,6 +140,12 @@ public:
|
||||
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();
|
||||
|
||||
// statistics
|
||||
|
||||
/* Return the highest beat/row that might contain notes. (Use GetLastBeat if you need
|
||||
@@ -157,6 +164,7 @@ 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
|
||||
|
||||
@@ -169,17 +169,7 @@ void NoteDataUtil::GetSMNoteDataString( const NoteData &in_, CString &out )
|
||||
case TAP_HOLD_HEAD: c = '2'; break;
|
||||
case TAP_HOLD_TAIL: c = '3'; break;
|
||||
case TAP_MINE: c = 'M'; break;
|
||||
default:
|
||||
if( tn >= TAP_ATTACK_BEGIN && tn <= TAP_ATTACK_END )
|
||||
{
|
||||
c = tn - TAP_ATTACK_BEGIN + 'a'; // TODO: overflow check?
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0);
|
||||
c = '0';
|
||||
}
|
||||
break;
|
||||
default: ASSERT(0); c = '0'; break;
|
||||
}
|
||||
sRet.append(1, c);
|
||||
}
|
||||
|
||||
@@ -824,7 +824,7 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float
|
||||
DrawHold( hn, bActive, fLife, fPercentFadeToFail, true, fReverseOffsetPixels );
|
||||
}
|
||||
|
||||
void NoteDisplay::DrawTap( int iCol, float fBeat, bool bOnSameRowAsHoldStart, bool bIsAddition, bool bIsMine, float fPercentFadeToFail, float fLife, float fReverseOffsetPixels )
|
||||
void NoteDisplay::DrawActor( Actor* pActor, int iCol, float fBeat, float fPercentFadeToFail, float fLife, float fReverseOffsetPixels )
|
||||
{
|
||||
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, iCol, fBeat );
|
||||
const float fYPos = ArrowGetYPos( m_PlayerNumber, iCol, fYOffset, fReverseOffsetPixels );
|
||||
@@ -837,16 +837,6 @@ void NoteDisplay::DrawTap( int iCol, float fBeat, bool bOnSameRowAsHoldStart, bo
|
||||
RageColor diffuse = RageColor(fColorScale,fColorScale,fColorScale,fAlpha);
|
||||
RageColor glow = RageColor(1,1,1,fGlow);
|
||||
|
||||
Actor* pActor = NULL;
|
||||
if( bIsMine )
|
||||
pActor = GetTapMineActor( fBeat );
|
||||
else if( bIsAddition )
|
||||
pActor = GetTapAdditionActor( fBeat );
|
||||
else if( bOnSameRowAsHoldStart && cache->m_bDrawHoldHeadForTapsOnSameRow )
|
||||
pActor = GetHoldHeadActor( fBeat, false );
|
||||
else
|
||||
pActor = GetTapNoteActor( fBeat );
|
||||
|
||||
pActor->SetRotationZ( fRotation );
|
||||
pActor->SetXY( fXPos, fYPos );
|
||||
pActor->SetZ( fZPos );
|
||||
@@ -873,6 +863,21 @@ void NoteDisplay::DrawTap( int iCol, float fBeat, bool bOnSameRowAsHoldStart, bo
|
||||
}
|
||||
}
|
||||
|
||||
void NoteDisplay::DrawTap( int iCol, float fBeat, bool bOnSameRowAsHoldStart, bool bIsAddition, bool bIsMine, float fPercentFadeToFail, float fLife, float fReverseOffsetPixels )
|
||||
{
|
||||
Actor* pActor = NULL;
|
||||
if( bIsMine )
|
||||
pActor = GetTapMineActor( fBeat );
|
||||
else if( bIsAddition )
|
||||
pActor = GetTapAdditionActor( fBeat );
|
||||
else if( bOnSameRowAsHoldStart && cache->m_bDrawHoldHeadForTapsOnSameRow )
|
||||
pActor = GetHoldHeadActor( fBeat, false );
|
||||
else
|
||||
pActor = GetTapNoteActor( fBeat );
|
||||
|
||||
DrawActor( pActor, iCol, fBeat, fPercentFadeToFail, fLife, fReverseOffsetPixels );
|
||||
}
|
||||
|
||||
|
||||
// if( ct == PlayerOptions::COLOR_NOTE )
|
||||
// {
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
|
||||
void Load( int iColNum, PlayerNumber pn, CString NoteSkin, float fYReverseOffsetPixels );
|
||||
|
||||
void DrawActor( Actor* pActor, int iCol, float fBeat, float fPercentFadeToFail, float fLife, float fReverseOffsetPixels );
|
||||
void DrawTap( int iCol, float fBeat, bool bOnSameRowAsHoldStart, bool bIsAddition, bool bIsMine, float fPercentFadeToFail, float fLife, float fReverseOffsetPixels );
|
||||
void DrawHold( const HoldNote& hn, bool bActive, float fLife, float fPercentFadeToFail, bool bDrawGlowOnly, float fReverseOffsetPixels );
|
||||
|
||||
|
||||
+36
-20
@@ -465,9 +465,9 @@ void NoteField::DrawPrimitives()
|
||||
{
|
||||
g_NoteFieldMode[m_PlayerNumber].BeginDrawTrack(c);
|
||||
|
||||
/////////////////////////////////
|
||||
//
|
||||
// Draw all HoldNotes in this column (so that they appear under the tap notes)
|
||||
/////////////////////////////////
|
||||
//
|
||||
int i;
|
||||
|
||||
NDMap::iterator CurDisplay = m_BeatToNoteDisplays.begin();
|
||||
@@ -507,9 +507,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
//
|
||||
// Draw all TapNotes in this column
|
||||
///////////////////////////////////
|
||||
//
|
||||
CurDisplay = m_BeatToNoteDisplays.begin();
|
||||
NextDisplay = CurDisplay; ++NextDisplay;
|
||||
|
||||
@@ -543,25 +543,41 @@ void NoteField::DrawPrimitives()
|
||||
|
||||
bool bIsAddition = (tn == TAP_ADDITION);
|
||||
bool bIsMine = (tn == TAP_MINE);
|
||||
bool bIsAttack = (tn==TAP_ATTACK);
|
||||
|
||||
if( bIsAttack )
|
||||
{
|
||||
const AttackNote* pA = GetAttackNoteAt( c, i );
|
||||
Sprite sprite;
|
||||
sprite.Load( THEME->GetPathToG("NoteField attack "+pA->sModifiers) );
|
||||
SearchForBeat( CurDisplay, NextDisplay, NoteRowToBeat(i) );
|
||||
NoteDisplayCols *nd = CurDisplay->second;
|
||||
nd->display[c].DrawActor( &sprite, c, NoteRowToBeat(i), bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, 1, m_fYReverseOffsetPixels );
|
||||
}
|
||||
else
|
||||
{
|
||||
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 );
|
||||
}
|
||||
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 )
|
||||
{
|
||||
bIsInSelectionRange = m_fBeginMarker<=an.fBeat && an.fBeat<=m_fEndMarker;
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
g_NoteFieldMode[m_PlayerNumber].EndDrawTrack(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ static const TapNote TAP_MINE = '6';
|
||||
// MD 11/12/03 - for future modifiers
|
||||
// TAP_ADD_HOLD is to TAP_HOLD what TAP_ADDITION is to TAP_TAP.
|
||||
// There is no equivalent for TAP_MINE.
|
||||
static const TapNote TAP_ADD_HOLD = '7';
|
||||
static const TapNote TAP_ADD_HOLD = '7'; // is this supposed to be TAP_ADD_HOLD_HEAD? -Chris
|
||||
|
||||
|
||||
// BM-specific
|
||||
// Removed taps, e.g. in Little - play keysounds here as if
|
||||
@@ -69,10 +70,6 @@ static const TapNote TAP_REMOVED_HOLD_TAIL = '\'';
|
||||
|
||||
// MD 11/12/03 end
|
||||
|
||||
// attack note start. Use lowercase letters a-z.
|
||||
// Don't use uppercase letters - 'M' it taken for mine.
|
||||
static const TapNote TAP_ATTACK_BEGIN = 'a';
|
||||
static const TapNote TAP_ATTACK_END = 'z';
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -135,6 +132,15 @@ 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 ); };
|
||||
|
||||
@@ -19,11 +19,6 @@ CString NotesWriterDWI::NotesToDWIString( const TapNote cNoteCols[6] )
|
||||
case TAP_EMPTY:
|
||||
case TAP_MINE:
|
||||
continue;
|
||||
default:
|
||||
if( cNoteCols[col] >= TAP_ATTACK_BEGIN && cNoteCols[col] <= TAP_ATTACK_END )
|
||||
continue;
|
||||
else
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
if( cNoteCols[col] == TAP_HOLD_HEAD )
|
||||
|
||||
@@ -663,41 +663,51 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
||||
if( iCol >= m_NoteFieldEdit.GetNumTracks() ) // this button is not in the range of columns for this StyleDef
|
||||
break;
|
||||
|
||||
int i;
|
||||
|
||||
// check for to see if the user intended to remove a HoldNote
|
||||
bool bRemovedAHoldNote = false;
|
||||
for( int i=0; i<m_NoteFieldEdit.GetNumHoldNotes(); i++ ) // for each HoldNote
|
||||
for( i=0; i<m_NoteFieldEdit.GetNumHoldNotes(); i++ ) // for each HoldNote
|
||||
{
|
||||
const HoldNote &hn = m_NoteFieldEdit.GetHoldNote(i);
|
||||
if( iCol == hn.iTrack && // the notes correspond
|
||||
fSongBeat >= hn.fStartBeat && fSongBeat <= hn.fEndBeat ) // the cursor lies within this HoldNote
|
||||
{
|
||||
m_NoteFieldEdit.RemoveHoldNote( i );
|
||||
bRemovedAHoldNote = true;
|
||||
break; // stop iterating over all HoldNotes
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( !bRemovedAHoldNote )
|
||||
// check for to see if the user intended to remove an AttackNote
|
||||
for( i=0; i<m_NoteFieldEdit.GetNumAttackNotes(); i++ )
|
||||
{
|
||||
// Delete the tap note here if one already exists
|
||||
if( m_NoteFieldEdit.GetTapNote(iCol, iSongIndex) != TAP_EMPTY )
|
||||
const AttackNote& an = m_NoteFieldEdit.GetAttackNote(i);
|
||||
if( an.fBeat == fSongBeat && an.iTrack == iCol )
|
||||
{
|
||||
m_NoteFieldEdit.SetTapNote(iCol, iSongIndex, TAP_EMPTY );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hold LShift to lay mine, hold RShift to lay an attack
|
||||
if( INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD, SDLK_LSHIFT)) )
|
||||
m_NoteFieldEdit.SetTapNote(iCol, iSongIndex, TAP_MINE );
|
||||
else if( INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD, SDLK_RSHIFT)) )
|
||||
{
|
||||
g_iLastInsertAttackTrack = iCol;
|
||||
SCREENMAN->MiniMenu( &g_InsertAttack, SM_BackFromInsertAttack );
|
||||
}
|
||||
else
|
||||
m_NoteFieldEdit.SetTapNote(iCol, iSongIndex, TAP_TAP );
|
||||
m_NoteFieldEdit.RemoveAttackNote( i );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_NoteFieldEdit.GetTapNote(iCol, iSongIndex) != TAP_EMPTY )
|
||||
{
|
||||
m_NoteFieldEdit.SetTapNote( iCol, iSongIndex, TAP_EMPTY );
|
||||
return;
|
||||
}
|
||||
|
||||
// Hold LShift to lay mine, hold RShift to lay an attack
|
||||
if( INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD, SDLK_LSHIFT)) )
|
||||
{
|
||||
m_NoteFieldEdit.SetTapNote(iCol, iSongIndex, TAP_MINE );
|
||||
}
|
||||
else if( INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD, SDLK_RSHIFT)) )
|
||||
{
|
||||
g_iLastInsertAttackTrack = iCol;
|
||||
SCREENMAN->MiniMenu( &g_InsertAttack, SM_BackFromInsertAttack );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_NoteFieldEdit.SetTapNote(iCol, iSongIndex, TAP_TAP );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDLK_UP:
|
||||
@@ -1276,9 +1286,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
PlayerOptions poChosen = GAMESTATE->m_PlayerOptions[PLAYER_1];
|
||||
CString sMods = poChosen.GetString();
|
||||
int row = BeatToNoteRow( GAMESTATE->m_fSongBeat );
|
||||
m_NoteFieldEdit.SetTapNote( g_iLastInsertAttackTrack, row, TAP_TAP );
|
||||
m_NoteFieldEdit.SetTapNoteAttack( g_iLastInsertAttackTrack, row, sMods, g_fLastInsertAttackDurationSeconds );
|
||||
m_NoteFieldEdit.AddAttackNote( AttackNote(g_iLastInsertAttackTrack,GAMESTATE->m_fSongBeat,sMods,g_fLastInsertAttackDurationSeconds) );
|
||||
GAMESTATE->RestoreSelectedOptions(); // restore the edit and playback options
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user