diff --git a/src/DifficultyList.cpp b/src/DifficultyList.cpp index 83fba9e3f2..0a341feb87 100644 --- a/src/DifficultyList.cpp +++ b/src/DifficultyList.cpp @@ -1,412 +1,412 @@ -#include "global.h" -#include "DifficultyList.h" -#include "GameState.h" -#include "Song.h" -#include "Steps.h" -#include "Style.h" -#include "StepsDisplay.h" -#include "StepsUtil.h" -#include "CommonMetrics.h" -#include "Foreach.h" -#include "SongUtil.h" -#include "XmlFile.h" - -/** @brief Specifies the max number of charts available for a song. - * - * This includes autogenned charts. */ -#define MAX_METERS (NUM_Difficulty * NUM_StepsType) + MAX_EDITS_PER_SONG - -REGISTER_ACTOR_CLASS( StepsDisplayList ); - -StepsDisplayList::StepsDisplayList() -{ - m_bShown = true; - - FOREACH_ENUM( PlayerNumber, pn ) - { - SubscribeToMessage( (MessageID)(Message_CurrentStepsP1Changed+pn) ); - SubscribeToMessage( (MessageID)(Message_CurrentTrailP1Changed+pn) ); - } -} - -StepsDisplayList::~StepsDisplayList() -{ -} - -void StepsDisplayList::LoadFromNode( const XNode* pNode ) -{ - ActorFrame::LoadFromNode( pNode ); - - ASSERT_M( !m_sName.empty(), "StepsDisplayList must have a Name" ); - - ITEMS_SPACING_Y.Load( m_sName, "ItemsSpacingY" ); - NUM_SHOWN_ITEMS.Load( m_sName, "NumShownItems" ); - CAPITALIZE_DIFFICULTY_NAMES.Load( m_sName, "CapitalizeDifficultyNames" ); - MOVE_COMMAND.Load( m_sName, "MoveCommand" ); - - m_Lines.resize( MAX_METERS ); - m_CurSong = NULL; - - FOREACH_ENUM( PlayerNumber, pn ) - { - const XNode *pChild = pNode->GetChild( ssprintf("CursorP%i",pn+1) ); - if( pChild == NULL ) - RageException::Throw( "%s: StepsDisplayList: missing the node \"CursorP%d\"", ActorUtil::GetWhere(pNode).c_str(), pn+1 ); - m_Cursors[pn].LoadActorFromNode( pChild, this ); - - /* Hack: we need to tween cursors both up to down (cursor motion) and visible to - * invisible (fading). Cursor motion needs to stoptweening, so multiple motions - * don't queue and look unresponsive. However, that stoptweening interrupts fading, - * resulting in the cursor remaining invisible or partially invisible. So, do them - * in separate tweening stacks. This means the Cursor command can't change diffuse - * colors; I think we do need a diffuse color stack ... */ - pChild = pNode->GetChild( ssprintf("CursorP%iFrame",pn+1) ); - if( pChild == NULL ) - RageException::Throw( "%s: StepsDisplayList: missing the node \"CursorP%dFrame\"", ActorUtil::GetWhere(pNode).c_str(), pn+1 ); - m_CursorFrames[pn].LoadFromNode( pChild ); - m_CursorFrames[pn].AddChild( m_Cursors[pn] ); - this->AddChild( &m_CursorFrames[pn] ); - } - - for( unsigned m = 0; m < m_Lines.size(); ++m ) - { - // todo: Use Row1, Row2 for names? also m_sName+"Row" -aj - m_Lines[m].m_Meter.SetName( "Row" ); - m_Lines[m].m_Meter.Load( "StepsDisplayListRow", NULL ); - this->AddChild( &m_Lines[m].m_Meter ); - } - - UpdatePositions(); - PositionItems(); -} - -int StepsDisplayList::GetCurrentRowIndex( PlayerNumber pn ) const -{ - Difficulty ClosestDifficulty = GAMESTATE->GetClosestShownDifficulty(pn); - - for( unsigned i=0; im_pCurSteps[pn] == NULL ) - { - if( row.m_dc == ClosestDifficulty ) - return i; - } - else - { - if( GAMESTATE->m_pCurSteps[pn].Get() == row.m_Steps ) - return i; - } - } - - return 0; -} - -// Update m_fY and m_bHidden[]. -void StepsDisplayList::UpdatePositions() -{ - int iCurrentRow[NUM_PLAYERS]; - FOREACH_HumanPlayer( p ) - iCurrentRow[p] = GetCurrentRowIndex( p ); - - const int total = NUM_SHOWN_ITEMS; - const int halfsize = total / 2; - - int first_start, first_end, second_start, second_end; - - // Choices for each player. If only one player is active, it's the same for both. - int P1Choice = GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: 0; - int P2Choice = GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: 0; - - vector &Rows = m_Rows; - - const bool BothPlayersActivated = GAMESTATE->IsHumanPlayer(PLAYER_1) && GAMESTATE->IsHumanPlayer(PLAYER_2); - if( !BothPlayersActivated ) - { - // Simply center the cursor. - first_start = max( P1Choice - halfsize, 0 ); - first_end = first_start + total; - second_start = second_end = first_end; - } - else - { - // First half: - const int earliest = min( P1Choice, P2Choice ); - first_start = max( earliest - halfsize/2, 0 ); - first_end = first_start + halfsize; - - // Second half: - const int latest = max( P1Choice, P2Choice ); - - second_start = max( latest - halfsize/2, 0 ); - - // Don't overlap. - second_start = max( second_start, first_end ); - - second_end = second_start + halfsize; - } - - first_end = min( first_end, (int) Rows.size() ); - second_end = min( second_end, (int) Rows.size() ); - - /* If less than total (and Rows.size()) are displayed, fill in the empty - * space intelligently. */ - while(1) - { - const int sum = (first_end - first_start) + (second_end - second_start); - if( sum >= (int) Rows.size() || sum >= total) - break; // nothing more to display, or no room - - /* First priority: expand the top of the second half until it meets - * the first half. */ - if( second_start > first_end ) - second_start--; - // Otherwise, expand either end. - else if( first_start > 0 ) - first_start--; - else if( second_end < (int) Rows.size() ) - second_end++; - else - FAIL_M("Do we have room to grow, or don't we?"); - } - - int pos = 0; - for( int i=0; i<(int) Rows.size(); i++ ) // foreach row - { - float ItemPosition; - if( i < first_start ) - ItemPosition = -0.5f; - else if( i < first_end ) - ItemPosition = (float) pos++; - else if( i < second_start ) - ItemPosition = halfsize - 0.5f; - else if( i < second_end ) - ItemPosition = (float) pos++; - else - ItemPosition = (float) total - 0.5f; - - Row &row = Rows[i]; - - float fY = ITEMS_SPACING_Y*ItemPosition; - row.m_fY = fY; - row.m_bHidden = i < first_start || - (i >= first_end && i < second_start) || - i >= second_end; - } -} - - -void StepsDisplayList::PositionItems() -{ - for( int i = 0; i < MAX_METERS; ++i ) - { - bool bUnused = ( i >= (int)m_Rows.size() ); - m_Lines[i].m_Meter.SetVisible( !bUnused ); - } - - for( int m = 0; m < (int)m_Rows.size(); ++m ) - { - Row &row = m_Rows[m]; - bool bHidden = row.m_bHidden; - if( !m_bShown ) - bHidden = true; - - const float fDiffuseAlpha = bHidden? 0.0f:1.0f; - if( m_Lines[m].m_Meter.GetDestY() != row.m_fY || - m_Lines[m].m_Meter.DestTweenState().diffuse[0][3] != fDiffuseAlpha ) - { - m_Lines[m].m_Meter.RunCommands( MOVE_COMMAND.GetValue() ); - m_Lines[m].m_Meter.RunCommandsOnChildren( MOVE_COMMAND.GetValue() ); - } - - m_Lines[m].m_Meter.SetY( row.m_fY ); - } - - for( int m=0; m < MAX_METERS; ++m ) - { - bool bHidden = true; - if( m_bShown && m < (int)m_Rows.size() ) - bHidden = m_Rows[m].m_bHidden; - - float fDiffuseAlpha = bHidden?0.0f:1.0f; - - m_Lines[m].m_Meter.SetDiffuseAlpha( fDiffuseAlpha ); - } - - - FOREACH_HumanPlayer( pn ) - { - int iCurrentRow = GetCurrentRowIndex( pn ); - - float fY = 0; - if( iCurrentRow < (int) m_Rows.size() ) - fY = m_Rows[iCurrentRow].m_fY; - - m_CursorFrames[pn].PlayCommand( "Change" ); - m_CursorFrames[pn].SetY( fY ); - } -} - -void StepsDisplayList::SetFromGameState() -{ - const Song *pSong = GAMESTATE->m_pCurSong; - unsigned i = 0; - - if( pSong == NULL ) - { - // FIXME: This clamps to between the min and the max difficulty, but - // it really should round to the nearest difficulty that's in - // DIFFICULTIES_TO_SHOW. - const vector& difficulties = CommonMetrics::DIFFICULTIES_TO_SHOW.GetValue(); - m_Rows.resize( difficulties.size() ); - FOREACH_CONST( Difficulty, difficulties, d ) - { - m_Rows[i].m_dc = *d; - m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GAMESTATE->m_pCurStyle->m_StepsType, 0, *d, CourseType_Invalid ); - ++i; - } - } - else - { - vector vpSteps; - SongUtil::GetPlayableSteps( pSong, vpSteps ); - // Should match the sort in ScreenSelectMusic::AfterMusicChange. - - m_Rows.resize( vpSteps.size() ); - FOREACH_CONST( Steps*, vpSteps, s ) - { - //LOG->Trace(ssprintf("setting steps for row %i",i)); - m_Rows[i].m_Steps = *s; - m_Lines[i].m_Meter.SetFromSteps( *s ); - ++i; - } - } - - while( i < MAX_METERS ) - m_Lines[i++].m_Meter.Unset(); - - UpdatePositions(); - PositionItems(); - - for( int m = 0; m < MAX_METERS; ++m ) - m_Lines[m].m_Meter.FinishTweening(); -} - -void StepsDisplayList::HideRows() -{ - for( unsigned m = 0; m < m_Rows.size(); ++m ) - { - Line &l = m_Lines[m]; - - l.m_Meter.FinishTweening(); - l.m_Meter.SetDiffuseAlpha(0); - } -} - -void StepsDisplayList::TweenOnScreen() -{ - FOREACH_HumanPlayer( pn ) - ON_COMMAND( m_Cursors[pn] ); - - for( int m = 0; m < MAX_METERS; ++m ) - ON_COMMAND( m_Lines[m].m_Meter ); - - this->SetHibernate( 0.5f ); - m_bShown = true; - for( unsigned m = 0; m < m_Rows.size(); ++m ) - { - Line &l = m_Lines[m]; - - l.m_Meter.FinishTweening(); - } - - HideRows(); - PositionItems(); - - FOREACH_HumanPlayer( pn ) - COMMAND( m_Cursors[pn], "TweenOn" ); -} - -void StepsDisplayList::TweenOffScreen() -{ - -} - -void StepsDisplayList::Show() -{ - m_bShown = true; - - SetFromGameState(); - - HideRows(); - PositionItems(); - - FOREACH_HumanPlayer( pn ) - COMMAND( m_Cursors[pn], "Show" ); -} - -void StepsDisplayList::Hide() -{ - m_bShown = false; - PositionItems(); - - FOREACH_HumanPlayer( pn ) - COMMAND( m_Cursors[pn], "Hide" ); -} - -void StepsDisplayList::HandleMessage( const Message &msg ) -{ - FOREACH_ENUM( PlayerNumber, pn ) - { - if( msg.GetName() == MessageIDToString((MessageID)(Message_CurrentStepsP1Changed+pn)) || - msg.GetName() == MessageIDToString((MessageID)(Message_CurrentTrailP1Changed+pn)) ) - SetFromGameState(); - } - - ActorFrame::HandleMessage(msg); -} - - -// lua start -#include "LuaBinding.h" - -/** @brief Allow Lua to have access to the StepsDisplayList. */ -class LunaStepsDisplayList: public Luna -{ -public: - static int setfromgamestate( T* p, lua_State *L ) { p->SetFromGameState(); return 0; } - - LunaStepsDisplayList() - { - ADD_METHOD( setfromgamestate ); - } -}; - -LUA_REGISTER_DERIVED_CLASS( StepsDisplayList, ActorFrame ) -// lua end - -/* - * (c) 2003-2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "DifficultyList.h" +#include "GameState.h" +#include "Song.h" +#include "Steps.h" +#include "Style.h" +#include "StepsDisplay.h" +#include "StepsUtil.h" +#include "CommonMetrics.h" +#include "Foreach.h" +#include "SongUtil.h" +#include "XmlFile.h" + +/** @brief Specifies the max number of charts available for a song. + * + * This includes autogenned charts. */ +#define MAX_METERS (NUM_Difficulty * NUM_StepsType) + MAX_EDITS_PER_SONG + +REGISTER_ACTOR_CLASS( StepsDisplayList ); + +StepsDisplayList::StepsDisplayList() +{ + m_bShown = true; + + FOREACH_ENUM( PlayerNumber, pn ) + { + SubscribeToMessage( (MessageID)(Message_CurrentStepsP1Changed+pn) ); + SubscribeToMessage( (MessageID)(Message_CurrentTrailP1Changed+pn) ); + } +} + +StepsDisplayList::~StepsDisplayList() +{ +} + +void StepsDisplayList::LoadFromNode( const XNode* pNode ) +{ + ActorFrame::LoadFromNode( pNode ); + + ASSERT_M( !m_sName.empty(), "StepsDisplayList must have a Name" ); + + ITEMS_SPACING_Y.Load( m_sName, "ItemsSpacingY" ); + NUM_SHOWN_ITEMS.Load( m_sName, "NumShownItems" ); + CAPITALIZE_DIFFICULTY_NAMES.Load( m_sName, "CapitalizeDifficultyNames" ); + MOVE_COMMAND.Load( m_sName, "MoveCommand" ); + + m_Lines.resize( MAX_METERS ); + m_CurSong = NULL; + + FOREACH_ENUM( PlayerNumber, pn ) + { + const XNode *pChild = pNode->GetChild( ssprintf("CursorP%i",pn+1) ); + if( pChild == NULL ) + RageException::Throw( "%s: StepsDisplayList: missing the node \"CursorP%d\"", ActorUtil::GetWhere(pNode).c_str(), pn+1 ); + m_Cursors[pn].LoadActorFromNode( pChild, this ); + + /* Hack: we need to tween cursors both up to down (cursor motion) and visible to + * invisible (fading). Cursor motion needs to stoptweening, so multiple motions + * don't queue and look unresponsive. However, that stoptweening interrupts fading, + * resulting in the cursor remaining invisible or partially invisible. So, do them + * in separate tweening stacks. This means the Cursor command can't change diffuse + * colors; I think we do need a diffuse color stack ... */ + pChild = pNode->GetChild( ssprintf("CursorP%iFrame",pn+1) ); + if( pChild == NULL ) + RageException::Throw( "%s: StepsDisplayList: missing the node \"CursorP%dFrame\"", ActorUtil::GetWhere(pNode).c_str(), pn+1 ); + m_CursorFrames[pn].LoadFromNode( pChild ); + m_CursorFrames[pn].AddChild( m_Cursors[pn] ); + this->AddChild( &m_CursorFrames[pn] ); + } + + for( unsigned m = 0; m < m_Lines.size(); ++m ) + { + // todo: Use Row1, Row2 for names? also m_sName+"Row" -aj + m_Lines[m].m_Meter.SetName( "Row" ); + m_Lines[m].m_Meter.Load( "StepsDisplayListRow", NULL ); + this->AddChild( &m_Lines[m].m_Meter ); + } + + UpdatePositions(); + PositionItems(); +} + +int StepsDisplayList::GetCurrentRowIndex( PlayerNumber pn ) const +{ + Difficulty ClosestDifficulty = GAMESTATE->GetClosestShownDifficulty(pn); + + for( unsigned i=0; im_pCurSteps[pn] == NULL ) + { + if( row.m_dc == ClosestDifficulty ) + return i; + } + else + { + if( GAMESTATE->m_pCurSteps[pn].Get() == row.m_Steps ) + return i; + } + } + + return 0; +} + +// Update m_fY and m_bHidden[]. +void StepsDisplayList::UpdatePositions() +{ + int iCurrentRow[NUM_PLAYERS]; + FOREACH_HumanPlayer( p ) + iCurrentRow[p] = GetCurrentRowIndex( p ); + + const int total = NUM_SHOWN_ITEMS; + const int halfsize = total / 2; + + int first_start, first_end, second_start, second_end; + + // Choices for each player. If only one player is active, it's the same for both. + int P1Choice = GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: 0; + int P2Choice = GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: 0; + + vector &Rows = m_Rows; + + const bool BothPlayersActivated = GAMESTATE->IsHumanPlayer(PLAYER_1) && GAMESTATE->IsHumanPlayer(PLAYER_2); + if( !BothPlayersActivated ) + { + // Simply center the cursor. + first_start = max( P1Choice - halfsize, 0 ); + first_end = first_start + total; + second_start = second_end = first_end; + } + else + { + // First half: + const int earliest = min( P1Choice, P2Choice ); + first_start = max( earliest - halfsize/2, 0 ); + first_end = first_start + halfsize; + + // Second half: + const int latest = max( P1Choice, P2Choice ); + + second_start = max( latest - halfsize/2, 0 ); + + // Don't overlap. + second_start = max( second_start, first_end ); + + second_end = second_start + halfsize; + } + + first_end = min( first_end, (int) Rows.size() ); + second_end = min( second_end, (int) Rows.size() ); + + /* If less than total (and Rows.size()) are displayed, fill in the empty + * space intelligently. */ + while(1) + { + const int sum = (first_end - first_start) + (second_end - second_start); + if( sum >= (int) Rows.size() || sum >= total) + break; // nothing more to display, or no room + + /* First priority: expand the top of the second half until it meets + * the first half. */ + if( second_start > first_end ) + second_start--; + // Otherwise, expand either end. + else if( first_start > 0 ) + first_start--; + else if( second_end < (int) Rows.size() ) + second_end++; + else + FAIL_M("Do we have room to grow, or don't we?"); + } + + int pos = 0; + for( int i=0; i<(int) Rows.size(); i++ ) // foreach row + { + float ItemPosition; + if( i < first_start ) + ItemPosition = -0.5f; + else if( i < first_end ) + ItemPosition = (float) pos++; + else if( i < second_start ) + ItemPosition = halfsize - 0.5f; + else if( i < second_end ) + ItemPosition = (float) pos++; + else + ItemPosition = (float) total - 0.5f; + + Row &row = Rows[i]; + + float fY = ITEMS_SPACING_Y*ItemPosition; + row.m_fY = fY; + row.m_bHidden = i < first_start || + (i >= first_end && i < second_start) || + i >= second_end; + } +} + + +void StepsDisplayList::PositionItems() +{ + for( int i = 0; i < MAX_METERS; ++i ) + { + bool bUnused = ( i >= (int)m_Rows.size() ); + m_Lines[i].m_Meter.SetVisible( !bUnused ); + } + + for( int m = 0; m < (int)m_Rows.size(); ++m ) + { + Row &row = m_Rows[m]; + bool bHidden = row.m_bHidden; + if( !m_bShown ) + bHidden = true; + + const float fDiffuseAlpha = bHidden? 0.0f:1.0f; + if( m_Lines[m].m_Meter.GetDestY() != row.m_fY || + m_Lines[m].m_Meter.DestTweenState().diffuse[0][3] != fDiffuseAlpha ) + { + m_Lines[m].m_Meter.RunCommands( MOVE_COMMAND.GetValue() ); + m_Lines[m].m_Meter.RunCommandsOnChildren( MOVE_COMMAND.GetValue() ); + } + + m_Lines[m].m_Meter.SetY( row.m_fY ); + } + + for( int m=0; m < MAX_METERS; ++m ) + { + bool bHidden = true; + if( m_bShown && m < (int)m_Rows.size() ) + bHidden = m_Rows[m].m_bHidden; + + float fDiffuseAlpha = bHidden?0.0f:1.0f; + + m_Lines[m].m_Meter.SetDiffuseAlpha( fDiffuseAlpha ); + } + + + FOREACH_HumanPlayer( pn ) + { + int iCurrentRow = GetCurrentRowIndex( pn ); + + float fY = 0; + if( iCurrentRow < (int) m_Rows.size() ) + fY = m_Rows[iCurrentRow].m_fY; + + m_CursorFrames[pn].PlayCommand( "Change" ); + m_CursorFrames[pn].SetY( fY ); + } +} + +void StepsDisplayList::SetFromGameState() +{ + const Song *pSong = GAMESTATE->m_pCurSong; + unsigned i = 0; + + if( pSong == NULL ) + { + // FIXME: This clamps to between the min and the max difficulty, but + // it really should round to the nearest difficulty that's in + // DIFFICULTIES_TO_SHOW. + const vector& difficulties = CommonMetrics::DIFFICULTIES_TO_SHOW.GetValue(); + m_Rows.resize( difficulties.size() ); + for (Difficulty const &d : difficulties) + { + m_Rows[i].m_dc = d; + m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GAMESTATE->m_pCurStyle->m_StepsType, 0, d, CourseType_Invalid ); + ++i; + } + } + else + { + vector vpSteps; + SongUtil::GetPlayableSteps( pSong, vpSteps ); + // Should match the sort in ScreenSelectMusic::AfterMusicChange. + + m_Rows.resize( vpSteps.size() ); + for (Steps const * s: vpSteps) + { + //LOG->Trace(ssprintf("setting steps for row %i",i)); + m_Rows[i].m_Steps = s; + m_Lines[i].m_Meter.SetFromSteps( s ); + ++i; + } + } + + while( i < MAX_METERS ) + m_Lines[i++].m_Meter.Unset(); + + UpdatePositions(); + PositionItems(); + + for( int m = 0; m < MAX_METERS; ++m ) + m_Lines[m].m_Meter.FinishTweening(); +} + +void StepsDisplayList::HideRows() +{ + for( unsigned m = 0; m < m_Rows.size(); ++m ) + { + Line &l = m_Lines[m]; + + l.m_Meter.FinishTweening(); + l.m_Meter.SetDiffuseAlpha(0); + } +} + +void StepsDisplayList::TweenOnScreen() +{ + FOREACH_HumanPlayer( pn ) + ON_COMMAND( m_Cursors[pn] ); + + for( int m = 0; m < MAX_METERS; ++m ) + ON_COMMAND( m_Lines[m].m_Meter ); + + this->SetHibernate( 0.5f ); + m_bShown = true; + for( unsigned m = 0; m < m_Rows.size(); ++m ) + { + Line &l = m_Lines[m]; + + l.m_Meter.FinishTweening(); + } + + HideRows(); + PositionItems(); + + FOREACH_HumanPlayer( pn ) + COMMAND( m_Cursors[pn], "TweenOn" ); +} + +void StepsDisplayList::TweenOffScreen() +{ + +} + +void StepsDisplayList::Show() +{ + m_bShown = true; + + SetFromGameState(); + + HideRows(); + PositionItems(); + + FOREACH_HumanPlayer( pn ) + COMMAND( m_Cursors[pn], "Show" ); +} + +void StepsDisplayList::Hide() +{ + m_bShown = false; + PositionItems(); + + FOREACH_HumanPlayer( pn ) + COMMAND( m_Cursors[pn], "Hide" ); +} + +void StepsDisplayList::HandleMessage( const Message &msg ) +{ + FOREACH_ENUM( PlayerNumber, pn ) + { + if( msg.GetName() == MessageIDToString((MessageID)(Message_CurrentStepsP1Changed+pn)) || + msg.GetName() == MessageIDToString((MessageID)(Message_CurrentTrailP1Changed+pn)) ) + SetFromGameState(); + } + + ActorFrame::HandleMessage(msg); +} + + +// lua start +#include "LuaBinding.h" + +/** @brief Allow Lua to have access to the StepsDisplayList. */ +class LunaStepsDisplayList: public Luna +{ +public: + static int setfromgamestate( T* p, lua_State *L ) { p->SetFromGameState(); return 0; } + + LunaStepsDisplayList() + { + ADD_METHOD( setfromgamestate ); + } +}; + +LUA_REGISTER_DERIVED_CLASS( StepsDisplayList, ActorFrame ) +// lua end + +/* + * (c) 2003-2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */