diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 7a67e95447..9d8f9919f2 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -596,7 +596,7 @@ ColorNotSelectedDefault=0.1,0.5,0.1,1 // grayed green HelpText=&UP; &DOWN; to change line &LEFT; &RIGHT; to select between options then press START [ScreenMapControllers] -HelpText=Use arrow keys to navigate, ENTER to assign, SPACE to clear, ESCAPE when done. +HelpText=Use arrow keys to navigate, ENTER to assign, SPACE to clear, ESCAPE when done.::Some USB adaptors require that you chage "Ignore Joy Axes" in the Input Options screen. [GhostArrow] ShowSeconds=0.12 @@ -1002,9 +1002,11 @@ ModifiersZoom=0.5 ModifiersHorizAlign=2 [Inventory] -NumItemTypes=2 +NumItemTypes=3 ItemDurationSeconds=10 Item1Combo=50 -Item1Effect=boost +Item1Effect=dizzy Item2Combo=100 -Item2Effect=expand +Item2Effect=sudden +Item3Combo=150 +Item3Effect=expand diff --git a/stepmania/src/Actor.cpp b/stepmania/src/Actor.cpp index 4bb242aefd..07109af92b 100644 --- a/stepmania/src/Actor.cpp +++ b/stepmania/src/Actor.cpp @@ -22,8 +22,6 @@ Actor::Actor() { m_bFirstUpdate = true; - m_iNumTweenStates = 0; - m_baseRotation = RageVector3( 0, 0, 0 ); m_baseScale = RageVector3( 1, 1, 1 ); m_size = RageVector2( 1, 1 ); @@ -166,7 +164,7 @@ void Actor::EndDraw() void Actor::UpdateTweening( float fDeltaTime ) { // update tweening - if( m_iNumTweenStates == 0 ) + if( m_TweenStates.empty() ) return; // we are performing a tween @@ -186,12 +184,8 @@ void Actor::UpdateTweening( float fDeltaTime ) m_current = TS; // delete the head tween - for( int i=0; i= 0 ); - // HACK to keep from out of bounds access.. - if( m_iNumTweenStates == MAX_TWEEN_STATES ) - { - for( int i=0; i= 2 ) // if there was already a TS on the stack + ASSERT( m_TweenStates.size() == m_TweenInfo.size() ) + + TweenState &TS = m_TweenStates.back(); // latest + TweenInfo &TI = m_TweenInfo.back(); // latest + + if( m_TweenStates.size() >= 2 ) // if there was already a TS on the stack { // initialize the new TS from the last TS in the list - TS = m_TweenStates[m_iNumTweenStates-2]; + TS = m_TweenStates[m_TweenStates.size()-2]; } else { @@ -300,7 +290,8 @@ void Actor::BeginTweening( float time, TweenType tt ) void Actor::StopTweening() { - m_iNumTweenStates = 0; + m_TweenStates.clear(); + m_TweenInfo.clear(); } @@ -329,8 +320,10 @@ void Actor::SetTweenGlow( RageColor c ) { LatestTween().glow = c; }; Actor::TweenState Actor::GetDestTweenState() { - if(!m_iNumTweenStates) return m_current; - return LatestTween(); + if( m_TweenStates.empty() ) // not tweening + return m_current; + else + return LatestTween(); } void Actor::SetTweenState( const Actor::TweenState &ts ) @@ -571,7 +564,7 @@ float Actor::TweenTime() const { float tot = 0; - for(int i = 0; i < m_iNumTweenStates; ++i) + for( unsigned i=0; i0 && m_iNumTweenStates m_TweenStates; + vector m_TweenInfo; + TweenState& LatestTween() { ASSERT(m_TweenStates.size()>0); return m_TweenStates.back(); }; // // Temporary variables that are filled just before drawing diff --git a/stepmania/src/Combo.cpp b/stepmania/src/Combo.cpp index 2b2a6bdb39..4faf782eba 100644 --- a/stepmania/src/Combo.cpp +++ b/stepmania/src/Combo.cpp @@ -77,7 +77,7 @@ void Combo::Reset() m_sprCombo.SetDiffuse( RageColor(1,1,1,0) ); // invisible } -void Combo::SetScore( TapNoteScore score, int iNumNotesInThisRow ) +void Combo::SetScore( TapNoteScore score, int iNumNotesInThisRow, Inventory* pInventory ) { #ifndef DEBUG if( PREFSMAN->m_bAutoPlay && !GAMESTATE->m_bDemonstration ) // cheaters never prosper @@ -158,16 +158,18 @@ void Combo::SetScore( TapNoteScore score, int iNumNotesInThisRow ) case TNS_GOOD: case TNS_BOO: case TNS_MISS: - // end combo - if( m_iCurCombo > 50 ) - SCREENMAN->SendMessageToTopScreen( SM_ComboStopped, 0 ); + { + // end combo + bool bItemAcquired = pInventory->OnComboBroken( m_PlayerNumber, m_iCurCombo ); - GAMESTATE->m_Inventory[m_PlayerNumber].OnComboBroken( m_iCurCombo ); + if( !bItemAcquired && m_iCurCombo>50 ) // don't play "combo stopped" if we got an item + SCREENMAN->SendMessageToTopScreen( SM_ComboStopped, 0 ); - m_iCurCombo = 0; + m_iCurCombo = 0; - m_textComboNumber.SetDiffuse( RageColor(1,1,1,0) ); // invisible - m_sprCombo.SetDiffuse( RageColor(1,1,1,0) ); // invisible + m_textComboNumber.SetDiffuse( RageColor(1,1,1,0) ); // invisible + m_sprCombo.SetDiffuse( RageColor(1,1,1,0) ); // invisible + } break; default: ASSERT(0); diff --git a/stepmania/src/Combo.h b/stepmania/src/Combo.h index 0ae328591f..0d71f6f7d2 100644 --- a/stepmania/src/Combo.h +++ b/stepmania/src/Combo.h @@ -15,7 +15,7 @@ #include "Sprite.h" #include "BitmapText.h" #include "GameConstantsAndTypes.h" // for TapNoteScore - +class Inventory; class Combo : public ActorFrame @@ -25,7 +25,7 @@ public: void Init( PlayerNumber pn ) { m_PlayerNumber = pn; } - void SetScore( TapNoteScore score, int iNumNotesInThisRow ); + void SetScore( TapNoteScore score, int iNumNotesInThisRow, Inventory* pInventory ); int GetCurrentCombo() const { return m_iCurCombo; } int GetMaxCombo() const { return m_iMaxCombo; } diff --git a/stepmania/src/GameConstantsAndTypes.h b/stepmania/src/GameConstantsAndTypes.h index 4c5e5cc619..1999472237 100644 --- a/stepmania/src/GameConstantsAndTypes.h +++ b/stepmania/src/GameConstantsAndTypes.h @@ -218,4 +218,11 @@ const int MAX_RANKING_NAME_LENGTH = 4; const CString GROUP_ALL_MUSIC = ""; +// +// Battle stuff +// +const int ITEM_NONE = -1; +const int NUM_ITEM_SLOTS = 3; + + #endif diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 1d4b21b3dc..a597780459 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -115,7 +115,8 @@ void GameState::ResetMusicStatistics() m_bPastHereWeGo = false; for( int p=0; pGetMetric ("Inventory",ssprintf("Item%dEffect",i+1)) -bool ItemDef::operator<( const ItemDef& other ) -{ - return comboLevel < other.comboLevel; -} - -void ItemDef::Sort( vector& items ) -{ - sort( items.begin(), items.end() ); -} - - Inventory::Inventory() { - Reset(); -} - -void Inventory::Reset() -{ - for( int i=0; iGetPathTo("Sounds","gameplay battle aquire item") ); + m_soundUseItem.Load( THEME->GetPathTo("Sounds","gameplay battle use item") ); } void Inventory::RefreshPossibleItems() @@ -57,8 +43,10 @@ void Inventory::RefreshPossibleItems() } } -void Inventory::OnComboBroken( int iCombo ) +bool Inventory::OnComboBroken( PlayerNumber pn, int iCombo ) { + int* iItems = GAMESTATE->m_iItems[pn]; + // search for the item acquired for( int item=0; item<(int)m_ItemDefs.size(); item++ ) if( m_ItemDefs[item].comboLevel > iCombo ) @@ -67,7 +55,7 @@ void Inventory::OnComboBroken( int iCombo ) item--; // back up because we went one too far if( item == -1 ) // no item acquired - return; + return false; else { // give them an item @@ -75,12 +63,12 @@ void Inventory::OnComboBroken( int iCombo ) // search for the first open slot int iOpenSlot = -1; - if( m_iItems[NUM_ITEM_SLOTS/2] == ITEM_NONE ) + if( iItems[NUM_ITEM_SLOTS/2] == ITEM_NONE ) iOpenSlot = NUM_ITEM_SLOTS/2; else { for( int s=0; sm_iItems[pn]; + + if( iItems[iSlot] == ITEM_NONE ) return; - const ItemDef& def = m_ItemDefs[iSlot]; + int iItemIndex = iItems[iSlot]; + + const ItemDef& def = m_ItemDefs[iItemIndex]; PlayerNumber pnToAttack; switch( pn ) @@ -112,6 +108,8 @@ void Inventory::UseItem( PlayerNumber pn, int iSlot ) GAMESTATE->m_PlayerOptions[pnToAttack].FromString( def.effect ); // remove the item - m_iItems[iSlot] = ITEM_NONE; + iItems[iSlot] = ITEM_NONE; + + m_soundUseItem.Play(); } diff --git a/stepmania/src/Inventory.h b/stepmania/src/Inventory.h index a6e3424973..15e003566d 100644 --- a/stepmania/src/Inventory.h +++ b/stepmania/src/Inventory.h @@ -12,32 +12,33 @@ */ #include "GameConstantsAndTypes.h" +#include "RageSound.h" -const int ITEM_NONE = -1; -const int NUM_ITEM_SLOTS = 3; const int MAX_ITEM_TYPES = 20; -struct ItemDef -{ - int comboLevel; - CString effect; - bool operator<( const ItemDef& other ); - void Sort( vector& items ); -}; - -class Inventory +class Inventory { public: Inventory(); void Reset(); void RefreshPossibleItems(); - void OnComboBroken( int iCombo ); + bool OnComboBroken( PlayerNumber pn, int iCombo ); void UseItem( PlayerNumber pn, int iSlot ); + struct ItemDef + { + int comboLevel; + CString effect; + + bool operator<( const ItemDef& other ) { return comboLevel < other.comboLevel; } + void Sort( vector& items ) { sort( items.begin(), items.end() ); } + }; vector m_ItemDefs; - int m_iItems[NUM_ITEM_SLOTS]; + + RageSound m_soundAcquireItem; + RageSound m_soundUseItem; }; #endif diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index 392282320e..5316fb4f19 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -27,6 +27,8 @@ #include "RageDisplay.h" #include "ThemeManager.h" #include "Combo.h" +#include "ScoreDisplay.h" +#include "LifeMeter.h" #define GRAY_ARROWS_Y THEME->GetMetricF("Player","GrayArrowsY") #define JUDGMENT_Y THEME->GetMetricF("Player","JudgmentY") @@ -45,7 +47,8 @@ Player::Player() m_pLifeMeter = NULL; m_pScore = NULL; - m_ScoreKeeper = NULL; + m_pScoreKeeper = NULL; + m_pInventory = NULL; m_iOffsetSample = 0; @@ -65,16 +68,17 @@ int Player::GetPlayersMaxCombo() Player::~Player() { - delete m_ScoreKeeper; + delete m_pScoreKeeper; } -void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore ) +void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore, Inventory* pInventory ) { //LOG->Trace( "Player::Load()", ); m_PlayerNumber = pn; m_pLifeMeter = pLM; m_pScore = pScore; + m_pInventory = pInventory; const StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef(); @@ -94,8 +98,8 @@ void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDi m_Combo.Init( pn ); m_Judgment.Reset(); - if(m_ScoreKeeper) delete m_ScoreKeeper; - m_ScoreKeeper = new ScoreKeeperMAX2(GAMESTATE->m_pCurNotes[m_PlayerNumber], *this, pn); + if(m_pScoreKeeper) delete m_pScoreKeeper; + m_pScoreKeeper = new ScoreKeeperMAX2(GAMESTATE->m_pCurNotes[m_PlayerNumber], *this, pn); if( m_pScore ) m_pScore->Init( pn ); @@ -489,7 +493,7 @@ void Player::OnRowDestroyed( int iIndexThatWasSteppedOn ) if( iNumNotesInThisRow > 0 ) { HandleNoteScore( score, iNumNotesInThisRow ); // update score - m_Combo.SetScore( score, iNumNotesInThisRow ); + m_Combo.SetScore( score, iNumNotesInThisRow, m_pInventory ); GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber] = max( GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber], m_Combo.GetCurrentCombo() ); } @@ -531,7 +535,7 @@ int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) if( iNumMissesThisRow > 0 ) { HandleNoteScore( TNS_MISS, iNumMissesThisRow ); - m_Combo.SetScore( TNS_MISS, iNumMissesThisRow ); + m_Combo.SetScore( TNS_MISS, iNumMissesThisRow, m_pInventory ); } } @@ -568,8 +572,8 @@ void Player::HandleNoteScore( TapNoteScore score, int iNumTapsInRow ) return; #endif //DEBUG - if(m_ScoreKeeper) - m_ScoreKeeper->HandleNoteScore(score, iNumTapsInRow); + if(m_pScoreKeeper) + m_pScoreKeeper->HandleNoteScore(score, iNumTapsInRow); if (m_pScore) m_pScore->SetScore(GAMESTATE->m_CurStageStats.fScore[m_PlayerNumber]); @@ -589,8 +593,8 @@ void Player::HandleHoldNoteScore( HoldNoteScore score, TapNoteScore TapNoteScore return; #endif //DEBUG - if(m_ScoreKeeper) { - m_ScoreKeeper->HandleHoldNoteScore(score, TapNoteScore); + if(m_pScoreKeeper) { + m_pScoreKeeper->HandleHoldNoteScore(score, TapNoteScore); } if (m_pScore) diff --git a/stepmania/src/Player.h b/stepmania/src/Player.h index d0fb935e84..874162cfe4 100644 --- a/stepmania/src/Player.h +++ b/stepmania/src/Player.h @@ -22,8 +22,6 @@ #include "HoldGhostArrow.h" #include "ActorFrame.h" #include "RandomSample.h" -#include "ScoreDisplay.h" -#include "LifeMeterBar.h" #include "Judgment.h" #include "HoldJudgment.h" #include "Combo.h" @@ -31,7 +29,10 @@ #include "GrayArrowRow.h" #include "GhostArrowRow.h" #include "NoteDataWithScoring.h" -#include "ScoreKeeper.h" +class ScoreDisplay; +class LifeMeter; +class ScoreKeeper; +class Inventory; #define SAMPLE_COUNT 16 @@ -44,7 +45,7 @@ public: virtual void DrawPrimitives(); ~Player(); - void Load( PlayerNumber player_no, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore ); + void Load( PlayerNumber player_no, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore, Inventory* pInventory ); void CrossedRow( int iNoteRow ); void Step( int col ); int GetPlayersMaxCombo(); @@ -79,7 +80,8 @@ protected: LifeMeter* m_pLifeMeter; ScoreDisplay* m_pScore; - ScoreKeeper* m_ScoreKeeper; + ScoreKeeper* m_pScoreKeeper; + Inventory* m_pInventory; }; #endif diff --git a/stepmania/src/ScoreDisplayBattle.cpp b/stepmania/src/ScoreDisplayBattle.cpp index 50c2bdf75d..845b57dc87 100644 --- a/stepmania/src/ScoreDisplayBattle.cpp +++ b/stepmania/src/ScoreDisplayBattle.cpp @@ -45,15 +45,54 @@ void ScoreDisplayBattle::Update( float fDelta ) { ScoreDisplay::Update( fDelta ); - for( int i=0; im_Inventory[m_PlayerNumber].m_iItems[i]; - if( item == ITEM_NONE ) - m_sprItems[i].SetDiffuse( RageColor(1,1,1,0) ); - else + int iNewItem = GAMESTATE->m_iItems[m_PlayerNumber][s]; + int iOldItem = m_iLastSeenItems[s]; + + m_iLastSeenItems[s] = iNewItem; + + if( iNewItem != iOldItem ) // there was a change of items { - m_sprItems[i].SetDiffuse( RageColor(1,1,1,1) ); - m_sprItems[i].SetState( item ); + if( iNewItem == ITEM_NONE ) + { + m_sprItems[s].StopTweening(); + m_sprItems[s].SetDiffuse( RageColor(1,1,1,0) ); + } + else + { + m_sprItems[s].SetDiffuse( RageColor(1,1,1,1) ); + m_sprItems[s].SetState( iNewItem ); + + // blink + m_sprItems[s].StopTweening(); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) ); + m_sprItems[s].BeginTweening( 0.1f ); // sleep + m_sprItems[s].BeginTweening( 0.001f ); // snap + m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) ); + } } } } diff --git a/stepmania/src/ScoreDisplayBattle.h b/stepmania/src/ScoreDisplayBattle.h index d3524c6bf5..5b64eeb3fb 100644 --- a/stepmania/src/ScoreDisplayBattle.h +++ b/stepmania/src/ScoreDisplayBattle.h @@ -27,6 +27,8 @@ public: protected: Sprite m_sprFrames[NUM_ITEM_SLOTS]; Sprite m_sprItems[NUM_ITEM_SLOTS]; + + int m_iLastSeenItems[NUM_ITEM_SLOTS]; }; #endif diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 7ad9af0c1d..c8b7f2d13d 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -252,7 +252,7 @@ ScreenEdit::ScreenEdit() NOTESKIN->SwitchNoteSkin( PLAYER_1, "default" ); // change noteskin back to default before loading player - m_Player.Load( PLAYER_1, ¬eData, NULL, NULL ); + m_Player.Load( PLAYER_1, ¬eData, NULL, NULL, NULL ); m_Player.SetXY( PLAYER_X, PLAYER_Y ); m_Fade.SetClosed(); @@ -1312,7 +1312,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers ) m_EditMode = MODE_PLAYING; - m_Player.Load( PLAYER_1, (NoteData*)&m_NoteFieldEdit, NULL, NULL ); + m_Player.Load( PLAYER_1, (NoteData*)&m_NoteFieldEdit, NULL, NULL, NULL ); m_rectRecordBack.StopTweening(); m_rectRecordBack.BeginTweening( 0.5f ); diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index a11ab524db..b82129036e 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -330,8 +330,6 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration ) ASSERT(0); } - GAMESTATE->m_Inventory[p].RefreshPossibleItems(); - m_pScoreDisplay[p]->Init( (PlayerNumber)p ); m_pScoreDisplay[p]->SetXY( SCORE_X(p), SCORE_Y(p,bExtra) ); m_pScoreDisplay[p]->SetZoom( SCORE_ZOOM ); @@ -475,6 +473,8 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration ) StartPlayingSong( 0, 0 ); } + m_Inventory.RefreshPossibleItems(); + m_iRowLastCrossed = -1; @@ -589,7 +589,7 @@ void ScreenGameplay::LoadNextSong() NoteData pNewNoteData; pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, &pOriginalNoteData, &pNewNoteData ); - m_Player[p].Load( (PlayerNumber)p, &pNewNoteData, m_pLifeMeter[p], m_pScoreDisplay[p] ); + m_Player[p].Load( (PlayerNumber)p, &pNewNoteData, m_pLifeMeter[p], m_pScoreDisplay[p], &m_Inventory ); } /* Set up song-specific graphics. */ @@ -1027,7 +1027,7 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ } if( iItemSlot != -1 ) - GAMESTATE->m_Inventory[MenuI.player].UseItem( MenuI.player, iItemSlot ); + m_Inventory.UseItem( MenuI.player, iItemSlot ); } } diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index c242a127d8..cb68adc075 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -29,6 +29,8 @@ #include "DifficultyIcon.h" #include "BPMDisplay.h" #include "FocusingSprite.h" +#include "Inventory.h" + // messages sent by Combo const ScreenMessage SM_BeginToasty = ScreenMessage(SM_User+104); @@ -126,6 +128,8 @@ protected: Player m_Player[NUM_PLAYERS]; + Inventory m_Inventory; + DifficultyIcon m_DifficultyIcon[NUM_PLAYERS]; Sprite m_sprOniGameOver[NUM_PLAYERS];