Files
itgmania212121/stepmania/src/ScreenGameplay.cpp
T

1610 lines
50 KiB
C++
Raw Normal View History

2003-02-16 04:01:45 +00:00
#include "global.h"
2002-05-20 08:59:37 +00:00
/*
-----------------------------------------------------------------------------
Class: ScreenGameplay
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ScreenGameplay.h"
#include "SongManager.h"
#include "ScreenManager.h"
#include "GameConstantsAndTypes.h"
2002-07-23 01:41:40 +00:00
#include "PrefsManager.h"
2002-05-20 08:59:37 +00:00
#include "GameManager.h"
#include "SongManager.h"
#include "RageLog.h"
#include "AnnouncerManager.h"
2002-07-23 01:41:40 +00:00
#include "LifeMeterBar.h"
#include "LifeMeterBattery.h"
#include "GameState.h"
#include "ScoreDisplayNormal.h"
#include "ScoreDisplayOni.h"
2003-02-25 00:33:42 +00:00
#include "ScoreDisplayBattle.h"
2003-04-07 05:14:27 +00:00
#include "ScoreDisplayRave.h"
2002-07-27 19:29:51 +00:00
#include "ScreenPrompt.h"
#include "GrooveRadar.h"
2002-09-06 23:36:04 +00:00
#include "NotesLoaderSM.h"
#include "ThemeManager.h"
#include "RageTimer.h"
#include "ScoreKeeperMAX2.h"
2003-04-02 21:57:25 +00:00
#include "NoteFieldPositioning.h"
#include "LyricsLoader.h"
2002-05-20 08:59:37 +00:00
//
2002-07-23 01:41:40 +00:00
// Defines
2002-05-20 08:59:37 +00:00
//
#define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen")
2003-03-04 06:24:02 +00:00
#define MAXCOMBO_X THEME->GetMetricF("ScreenGameplay","MaxComboX")
#define MAXCOMBO_Y THEME->GetMetricF("ScreenGameplay","MaxComboY")
#define MAXCOMBO_ZOOM THEME->GetMetricF("ScreenGameplay","MaxComboZoom")
#define BPM_X THEME->GetMetricF("ScreenGameplay","BPMX")
#define BPM_Y THEME->GetMetricF("ScreenGameplay","BPMY")
#define BPM_ZOOM THEME->GetMetricF("ScreenGameplay","BPMZoom")
#define STAGENAME_X THEME->GetMetricF("ScreenGameplay","StagenameX")
#define STAGENAME_Y THEME->GetMetricF("ScreenGameplay","StagenameY")
#define STAGENAME_ZOOM THEME->GetMetricF("ScreenGameplay","StagenameZoom")
#define LIFE_FRAME_X THEME->GetMetricF("ScreenGameplay","LifeFrameX")
#define LIFE_FRAME_Y( e ) THEME->GetMetricF("ScreenGameplay",ssprintf("LifeFrame%sY",e?"Extra":""))
#define SCORE_FRAME_X THEME->GetMetricF("ScreenGameplay","ScoreFrameX")
#define SCORE_FRAME_Y( e ) THEME->GetMetricF("ScreenGameplay",ssprintf("ScoreFrame%sY",e?"Extra":""))
#define MIDDLE_FRAME_X THEME->GetMetricF("ScreenGameplay","MiddleFrameX")
#define MIDDLE_FRAME_Y THEME->GetMetricF("ScreenGameplay","MiddleFrameY")
2002-08-29 20:18:41 +00:00
#define LIFE_X( p ) THEME->GetMetricF("ScreenGameplay",ssprintf("LifeP%dX",p+1))
#define LIFE_Y( p, e ) THEME->GetMetricF("ScreenGameplay",ssprintf("LifeP%d%sY",p+1,e?"Extra":""))
#define STAGE_X THEME->GetMetricF("ScreenGameplay","StageX")
2002-08-29 20:18:41 +00:00
#define STAGE_Y( e ) THEME->GetMetricF("ScreenGameplay",ssprintf("Stage%sY",e?"Extra":""))
#define SONG_NUMBER_X( p ) THEME->GetMetricF("ScreenGameplay",ssprintf("SongNumberP%dX",p+1))
#define SONG_NUMBER_Y( p, e ) THEME->GetMetricF("ScreenGameplay",ssprintf("SongNumberP%d%sY",p+1,e?"Extra":""))
#define SCORE_X( p ) THEME->GetMetricF("ScreenGameplay",ssprintf("ScoreP%dX",p+1))
#define SCORE_Y( p, e ) THEME->GetMetricF("ScreenGameplay",ssprintf("ScoreP%d%sY",p+1,e?"Extra":""))
#define SCORE_ZOOM THEME->GetMetricF("ScreenGameplay","ScoreZoom")
2002-08-29 20:18:41 +00:00
#define PLAYER_OPTIONS_X( p ) THEME->GetMetricF("ScreenGameplay",ssprintf("PlayerOptionsP%dX",p+1))
#define PLAYER_OPTIONS_Y( p, e ) THEME->GetMetricF("ScreenGameplay",ssprintf("PlayerOptionsP%d%sY",p+1,e?"Extra":""))
#define SONG_OPTIONS_X THEME->GetMetricF("ScreenGameplay","SongOptionsX")
2002-08-29 20:18:41 +00:00
#define SONG_OPTIONS_Y( e ) THEME->GetMetricF("ScreenGameplay",ssprintf("SongOptions%sY",e?"Extra":""))
#define DIFFICULTY_X( p ) THEME->GetMetricF("ScreenGameplay",ssprintf("DifficultyP%dX",p+1))
#define DIFFICULTY_Y( p, e, r ) THEME->GetMetricF("ScreenGameplay",ssprintf("DifficultyP%d%s%sY",p+1,e?"Extra":"",r?"Reverse":""))
2003-03-19 22:48:43 +00:00
#define LYRICS_X THEME->GetMetricF("ScreenGameplay",ssprintf("LyricsX"))
#define LYRICS_Y( e, r ) THEME->GetMetricF("ScreenGameplay",ssprintf("Lyrics%s%sY",e?"Extra":"",r?"Reverse":""))
#define ACTIVE_ITEMS_X( p ) THEME->GetMetricF("ScreenGameplay",ssprintf("ActiveItemsP%dX",p+1))
#define ACTIVE_ITEMS_Y( p, e, r ) THEME->GetMetricF("ScreenGameplay",ssprintf("ActiveItemsP%d%s%sY",p+1,e?"Extra":"",r?"Reverse":""))
#define DEBUG_X THEME->GetMetricF("ScreenGameplay","DebugX")
#define DEBUG_Y THEME->GetMetricF("ScreenGameplay","DebugY")
#define AUTOPLAY_X THEME->GetMetricF("ScreenGameplay","AutoPlayX")
#define AUTOPLAY_Y THEME->GetMetricF("ScreenGameplay","AutoPlayY")
#define SURVIVE_TIME_X THEME->GetMetricF("ScreenGameplay","SurviveTimeX")
#define SURVIVE_TIME_Y THEME->GetMetricF("ScreenGameplay","SurviveTimeY")
CachedThemeMetricF SECONDS_BETWEEN_COMMENTS ("ScreenGameplay","SecondsBetweenComments");
CachedThemeMetricF G_TICK_EARLY_SECONDS ("ScreenGameplay","TickEarlySeconds");
2003-03-09 00:55:49 +00:00
const ScreenMessage SM_PlayReady = ScreenMessage(SM_User+0);
const ScreenMessage SM_PlayGo = ScreenMessage(SM_User+1);
2002-05-20 08:59:37 +00:00
// received while STATE_DANCING
2003-03-09 00:55:49 +00:00
const ScreenMessage SM_NotesEnded = ScreenMessage(SM_User+10);
const ScreenMessage SM_BeginLoadingNextSong = ScreenMessage(SM_User+11);
2002-05-20 08:59:37 +00:00
// received while STATE_OUTRO
2003-03-09 00:55:49 +00:00
const ScreenMessage SM_SaveChangedBeforeGoingBack = ScreenMessage(SM_User+20);
const ScreenMessage SM_GoToScreenAfterBack = ScreenMessage(SM_User+21);
const ScreenMessage SM_GoToStateAfterCleared= ScreenMessage(SM_User+22);
2002-05-20 08:59:37 +00:00
2003-03-09 00:55:49 +00:00
const ScreenMessage SM_BeginFailed = ScreenMessage(SM_User+30);
const ScreenMessage SM_GoToScreenAfterFail = ScreenMessage(SM_User+31);
2002-05-20 08:59:37 +00:00
// received while STATE_INTRO
2003-03-09 00:55:49 +00:00
const ScreenMessage SM_StartHereWeGo = ScreenMessage(SM_User+40);
const ScreenMessage SM_StopHereWeGo = ScreenMessage(SM_User+41);
2002-05-20 08:59:37 +00:00
2003-01-19 04:44:22 +00:00
ScreenGameplay::ScreenGameplay( bool bDemonstration )
2002-05-20 08:59:37 +00:00
{
LOG->Trace( "ScreenGameplay::ScreenGameplay()" );
2002-05-20 08:59:37 +00:00
2003-03-19 19:58:22 +00:00
m_bDemonstration = bDemonstration;
2003-03-09 00:55:49 +00:00
SECONDS_BETWEEN_COMMENTS.Refresh();
G_TICK_EARLY_SECONDS.Refresh();
2003-02-04 21:36:30 +00:00
if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL )
2003-01-19 21:05:03 +00:00
return; // ScreenDemonstration will move us to the next scren. We just need to survive for one update without crashing.
/* Save selected options before we change them. */
GAMESTATE->StoreSelectedOptions();
2002-08-28 22:42:40 +00:00
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_pLifeMeter[p] = NULL;
m_pScoreDisplay[p] = NULL;
m_pScoreKeeper[p] = NULL;
}
2002-08-28 22:42:40 +00:00
}
2002-08-02 09:31:06 +00:00
GAMESTATE->m_CurStageStats = StageStats(); // clear values
2003-03-26 23:08:05 +00:00
//
// fill in m_apSongsQueue, m_apNotesQueue, m_asModifiersQueue
//
if( GAMESTATE->IsCourseMode() )
{
2003-03-26 23:08:05 +00:00
Course* pCourse = GAMESTATE->m_pCurCourse;
pCourse->GetStageInfo( m_apSongsQueue, m_apNotesQueue[0], m_asModifiersQueue[0], GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
for( int p=1; p<NUM_PLAYERS; p++ )
{
m_apNotesQueue[p] = m_apNotesQueue[0];
m_asModifiersQueue[p] = m_asModifiersQueue[0];
}
}
2003-03-26 23:08:05 +00:00
else
2002-06-14 22:25:22 +00:00
{
2003-03-26 23:08:05 +00:00
m_apSongsQueue.push_back( GAMESTATE->m_pCurSong );
for( int p=0; p<NUM_PLAYERS; p++ )
2002-07-28 20:28:37 +00:00
{
2003-03-26 23:08:05 +00:00
m_apNotesQueue[p].push_back( GAMESTATE->m_pCurNotes[p] );
m_asModifiersQueue[p].push_back( "" );
}
2003-03-26 23:08:05 +00:00
}
2002-07-23 01:41:40 +00:00
2003-03-26 23:08:05 +00:00
//
// Init ScoreKeepers
//
int p;
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(p) )
continue; // skip
m_pScoreKeeper[p] = new ScoreKeeperMAX2( m_apNotesQueue[p], (PlayerNumber)p );
2002-06-14 22:25:22 +00:00
}
2003-03-26 23:08:05 +00:00
m_bChangedOffsetOrBPM = GAMESTATE->m_SongOptions.m_bAutoSync;
2002-07-28 20:28:37 +00:00
2002-05-20 08:59:37 +00:00
m_DancingState = STATE_INTRO;
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-05-20 08:59:37 +00:00
// If this is beginner mode, show the helper
/* !! Working on this.. having probs loading the BG sequences -- Miryokuteki */
//this->AddChild( &m_bhDancer );
//m_bhDancer.Load( THEME->GetPathTo("Graphics", "select difficulty ex picture easy") );
//m_bhDancer.SetXY( -100,-100 ); //<-- causing entire screen to offset!
//m_bhDancer.SetDiffuse( RageColor(1,1,1,1) );
//m_bhDancer.SetEffectGlowShift( 0.5f );
//m_bhDancer.BeginDraw();
/* */
2002-05-20 08:59:37 +00:00
m_Background.SetDiffuse( RageColor(0.4f,0.4f,0.4f,1) );
this->AddChild( &m_Background );
2002-05-27 08:23:27 +00:00
2003-02-14 22:39:23 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
2002-05-20 08:59:37 +00:00
{
2002-07-23 01:41:40 +00:00
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
2002-05-20 08:59:37 +00:00
continue;
2002-08-01 21:55:40 +00:00
float fPlayerX = (float) GAMESTATE->GetCurrentStyleDef()->m_iCenterX[p];
// If solo-single is enabled..
/* XXX: Maybe this should be enabled for all ONE_PLAYER_ONE_CREDIT modes.
* I don't feel like testing that right now, though. */
if( PREFSMAN->m_bSoloSingle &&
GAMESTATE->m_CurStyle == STYLE_DANCE_SINGLE &&
GAMESTATE->GetNumSidesJoined() == 1 )
fPlayerX = SCREEN_WIDTH/2;
2002-08-01 21:55:40 +00:00
m_Player[p].SetX( fPlayerX );
this->AddChild( &m_Player[p] );
2002-08-01 21:55:40 +00:00
2003-03-27 00:51:57 +00:00
m_TimingAssist.Load((PlayerNumber)p, &m_Player[p]);
m_ActiveItemList[p].Init( (PlayerNumber)p );
/* Position it in LoadNextSong. */
this->AddChild( &m_ActiveItemList[p] );
2003-03-09 00:55:49 +00:00
m_sprOniGameOver[p].Load( THEME->GetPathTo("Graphics","ScreenGameplay oni gameover") );
2002-08-01 21:55:40 +00:00
m_sprOniGameOver[p].SetX( fPlayerX );
m_sprOniGameOver[p].SetY( SCREEN_TOP - m_sprOniGameOver[p].GetZoomedHeight()/2 );
m_sprOniGameOver[p].SetDiffuse( RageColor(1,1,1,0) ); // 0 alpha so we don't waste time drawing while not visible
this->AddChild( &m_sprOniGameOver[p] );
2002-05-20 08:59:37 +00:00
}
2003-03-27 00:51:57 +00:00
this->AddChild(&m_TimingAssist);
2002-05-20 08:59:37 +00:00
2002-08-01 21:55:40 +00:00
m_OniFade.SetOpened();
this->AddChild( &m_OniFade );
2002-08-01 21:55:40 +00:00
const bool bExtra = GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2();
2002-06-14 22:25:22 +00:00
2002-10-18 19:01:32 +00:00
// LifeFrame goes below LifeMeter
CString sLifeFrameName;
if( bExtra )
2003-03-09 00:55:49 +00:00
sLifeFrameName = "ScreenGameplay extra life frame";
2002-10-18 19:01:32 +00:00
else if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY )
2003-03-09 00:55:49 +00:00
sLifeFrameName = "ScreenGameplay oni life frame";
2002-10-18 19:01:32 +00:00
else
2003-03-09 00:55:49 +00:00
sLifeFrameName = "ScreenGameplay life frame";
2002-10-18 19:01:32 +00:00
m_sprLifeFrame.Load( THEME->GetPathTo("Graphics",sLifeFrameName) );
m_sprLifeFrame.SetXY( LIFE_FRAME_X, LIFE_FRAME_Y(bExtra) );
this->AddChild( &m_sprLifeFrame );
2002-05-20 08:59:37 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
{
2002-07-28 20:28:37 +00:00
switch( GAMESTATE->m_SongOptions.m_LifeType )
2002-07-23 01:41:40 +00:00
{
2002-07-28 20:28:37 +00:00
case SongOptions::LIFE_BAR:
2002-07-23 01:41:40 +00:00
m_pLifeMeter[p] = new LifeMeterBar;
break;
2002-07-28 20:28:37 +00:00
case SongOptions::LIFE_BATTERY:
2002-07-23 01:41:40 +00:00
m_pLifeMeter[p] = new LifeMeterBattery;
break;
default:
ASSERT(0);
}
2002-05-20 08:59:37 +00:00
2002-07-28 20:28:37 +00:00
m_pLifeMeter[p]->Load( (PlayerNumber)p );
m_pLifeMeter[p]->SetXY( LIFE_X(p), LIFE_Y(p,bExtra) );
this->AddChild( m_pLifeMeter[p] );
2002-05-20 08:59:37 +00:00
}
for( p=0; p<NUM_PLAYERS; p++ )
2002-08-01 03:15:27 +00:00
{
m_textCourseSongNumber[p].LoadFromNumbers( THEME->GetPathTo("Numbers","ScreenGameplay song num") );
2003-03-02 01:43:33 +00:00
m_textCourseSongNumber[p].EnableShadow( false );
m_textCourseSongNumber[p].SetXY( SONG_NUMBER_X(p), SONG_NUMBER_Y(p,bExtra) );
2002-08-01 03:15:27 +00:00
m_textCourseSongNumber[p].SetText( "" );
m_textCourseSongNumber[p].SetDiffuse( RageColor(0,0.5f,1,1) ); // light blue
2002-08-01 03:15:27 +00:00
}
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
2003-02-25 00:33:42 +00:00
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
m_sprStage.Load( THEME->GetPathTo("Graphics","ScreenGameplay stage "+GAMESTATE->GetStageText()) );
m_sprStage.SetXY( STAGE_X, STAGE_Y(bExtra) );
this->AddChild( &m_sprStage );
2002-08-01 03:15:27 +00:00
break;
case PLAY_MODE_NONSTOP:
2002-08-01 03:15:27 +00:00
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
for( p=0; p<NUM_PLAYERS; p++ )
2002-08-01 13:42:56 +00:00
if( GAMESTATE->IsPlayerEnabled(p) )
this->AddChild( &m_textCourseSongNumber[p] );
2002-08-01 03:15:27 +00:00
break;
default:
ASSERT(0); // invalid GameMode
}
2002-06-14 22:25:22 +00:00
2002-08-28 22:42:40 +00:00
//
// Add all Actors in score frame
2002-08-28 22:42:40 +00:00
//
CString sScoreFrameName;
if( bExtra )
2003-03-09 00:55:49 +00:00
sScoreFrameName = "ScreenGameplay extra score frame";
else if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY )
2003-03-09 00:55:49 +00:00
sScoreFrameName = "ScreenGameplay oni score frame";
else
2003-03-09 00:55:49 +00:00
sScoreFrameName = "ScreenGameplay score frame";
m_sprScoreFrame.Load( THEME->GetPathTo("Graphics",sScoreFrameName) );
m_sprScoreFrame.SetXY( SCORE_FRAME_X, SCORE_FRAME_Y(bExtra) );
this->AddChild( &m_sprScoreFrame );
2002-07-23 01:41:40 +00:00
2003-03-30 18:12:57 +00:00
m_textSongTitle.LoadFromFont( THEME->GetPathTo("Fonts","ScreenGameplay song title") );
m_textSongTitle.EnableShadow( false );
m_textSongTitle.SetXY( STAGENAME_X, STAGENAME_Y );
m_textSongTitle.SetZoom( STAGENAME_ZOOM );
this->AddChild( &m_textSongTitle );
2003-03-30 18:12:57 +00:00
m_MaxCombo.LoadFromNumbers( THEME->GetPathTo("Numbers","ScreenGameplay max combo") );
m_MaxCombo.SetXY( MAXCOMBO_X, MAXCOMBO_Y );
m_MaxCombo.SetZoom( MAXCOMBO_ZOOM );
2003-03-16 20:55:45 +00:00
m_MaxCombo.SetText( ssprintf("%d", GAMESTATE->m_CurStageStats.iCurCombo[GAMESTATE->m_MasterPlayerNumber]) ); /* TODO: Make this work for both players */
this->AddChild( &m_MaxCombo );
2002-05-20 08:59:37 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
{
2002-07-23 01:41:40 +00:00
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
2002-05-20 08:59:37 +00:00
continue;
2002-08-28 22:42:40 +00:00
switch( GAMESTATE->m_PlayMode )
{
2002-08-28 22:42:40 +00:00
case PLAY_MODE_ARCADE:
case PLAY_MODE_NONSTOP:
2002-08-28 22:42:40 +00:00
m_pScoreDisplay[p] = new ScoreDisplayNormal;
break;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
m_pScoreDisplay[p] = new ScoreDisplayOni;
break;
2003-02-25 00:33:42 +00:00
case PLAY_MODE_BATTLE:
m_pScoreDisplay[p] = new ScoreDisplayBattle;
break;
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
m_pScoreDisplay[p] = new ScoreDisplayRave;
break;
2002-08-28 22:42:40 +00:00
default:
ASSERT(0);
}
m_pScoreDisplay[p]->Init( (PlayerNumber)p );
m_pScoreDisplay[p]->SetXY( SCORE_X(p), SCORE_Y(p,bExtra) );
m_pScoreDisplay[p]->SetZoom( SCORE_ZOOM );
this->AddChild( m_pScoreDisplay[p] );
2003-03-30 18:12:57 +00:00
m_textPlayerOptions[p].LoadFromFont( THEME->GetPathTo("Fonts","Common normal") );
2003-03-02 01:43:33 +00:00
m_textPlayerOptions[p].EnableShadow( false );
m_textPlayerOptions[p].SetXY( PLAYER_OPTIONS_X(p), PLAYER_OPTIONS_Y(p,bExtra) );
2002-05-28 20:01:22 +00:00
m_textPlayerOptions[p].SetZoom( 0.5f );
m_textPlayerOptions[p].SetDiffuse( RageColor(1,1,1,1) );
this->AddChild( &m_textPlayerOptions[p] );
2002-05-20 08:59:37 +00:00
}
2003-03-30 18:12:57 +00:00
m_textSongOptions.LoadFromFont( THEME->GetPathTo("Fonts","Common normal") );
2003-03-02 01:43:33 +00:00
m_textSongOptions.EnableShadow( false );
2002-08-29 20:18:41 +00:00
m_textSongOptions.SetXY( SONG_OPTIONS_X, SONG_OPTIONS_Y(bExtra) );
m_textSongOptions.SetZoom( 0.5f );
m_textSongOptions.SetDiffuse( RageColor(1,1,1,1) );
m_textSongOptions.SetText( GAMESTATE->m_SongOptions.GetString() );
this->AddChild( &m_textSongOptions );
2002-06-14 22:25:22 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
{
2002-07-23 01:41:40 +00:00
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
2002-06-14 22:25:22 +00:00
continue;
2002-07-23 01:41:40 +00:00
2003-03-09 00:55:49 +00:00
m_DifficultyIcon[p].Load( THEME->GetPathTo("graphics","ScreenGameplay difficulty icons 2x5") );
/* Position it in LoadNextSong. */
2002-10-06 16:56:58 +00:00
this->AddChild( &m_DifficultyIcon[p] );
2002-06-14 22:25:22 +00:00
}
if(PREFSMAN->m_bShowLyrics)
this->AddChild(&m_LyricDisplay);
2003-03-30 18:12:57 +00:00
m_textAutoPlay.LoadFromFont( THEME->GetPathTo("Fonts","ScreenGameplay autoplay") );
m_textAutoPlay.SetXY( AUTOPLAY_X, AUTOPLAY_Y );
if( !bDemonstration ) // only load if we're not in demonstration of jukebox
this->AddChild( &m_textAutoPlay );
UpdateAutoPlayText();
2002-06-24 22:04:31 +00:00
2002-05-20 08:59:37 +00:00
2003-03-09 00:55:49 +00:00
m_BPMDisplay.SetXY( BPM_X, BPM_Y );
m_BPMDisplay.SetZoom( BPM_ZOOM );
this->AddChild( &m_BPMDisplay );
for( p=0; p<NUM_PLAYERS; p++ )
{
m_Inventory[p].Load( (PlayerNumber)p );
this->AddChild( &m_Inventory[p] );
2003-04-07 05:14:27 +00:00
m_RaveHelper[p].Load( (PlayerNumber)p );
this->AddChild( &m_RaveHelper[p] );
}
2002-05-20 08:59:37 +00:00
2003-03-09 00:55:49 +00:00
if( !bDemonstration ) // only load if we're going to use it
{
m_Ready.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay ready") );
this->AddChild( &m_Ready );
2002-05-20 08:59:37 +00:00
2003-03-09 00:55:49 +00:00
m_Go.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay go") );
this->AddChild( &m_Go );
2002-05-20 08:59:37 +00:00
2003-03-09 00:55:49 +00:00
m_Cleared.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay cleared") );
this->AddChild( &m_Cleared );
2003-03-09 00:55:49 +00:00
m_Failed.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay failed") );
this->AddChild( &m_Failed );
2002-07-27 19:29:51 +00:00
2003-03-09 00:55:49 +00:00
if( GAMESTATE->IsFinalStage() ) // only load if we're going to use it
m_Extra.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay extra1") );
if( GAMESTATE->IsExtraStage() ) // only load if we're going to use it
m_Extra.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay extra2") );
this->AddChild( &m_Extra );
2002-08-01 13:42:56 +00:00
2003-03-09 00:55:49 +00:00
m_Toasty.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay toasty") );
this->AddChild( &m_Toasty );
2002-08-01 13:42:56 +00:00
2003-03-09 00:55:49 +00:00
m_In.Load( THEME->GetPathTo("BGAnimations","ScreenGameplay in") );
this->AddChild( &m_In );
2003-03-30 18:12:57 +00:00
m_textDebug.LoadFromFont( THEME->GetPathTo("Fonts","Common normal") );
m_textDebug.SetXY( DEBUG_X, DEBUG_Y );
m_textDebug.SetDiffuse( RageColor(1,1,1,1) );
this->AddChild( &m_textDebug );
2003-03-13 01:26:50 +00:00
m_Back.Load( THEME->GetPathTo("BGAnimations","Common back") );
this->AddChild( &m_Back );
2003-03-09 00:55:49 +00:00
2003-03-30 20:18:46 +00:00
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) // only load if we're going to use it
2003-03-09 00:55:49 +00:00
{
m_textSurviveTime.LoadFromFont( THEME->GetPathTo("Fonts","ScreenGameplay survive time") );
2003-03-09 00:55:49 +00:00
m_textSurviveTime.EnableShadow( false );
m_textSurviveTime.SetXY( SURVIVE_TIME_X, SURVIVE_TIME_Y );
m_textSurviveTime.SetText( "" );
m_textSurviveTime.SetDiffuse( RageColor(1,1,1,0) );
this->AddChild( &m_textSurviveTime );
}
}
2003-02-04 21:36:30 +00:00
2002-05-20 08:59:37 +00:00
2003-04-02 21:57:25 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
{
GAMESTATE->m_Position[p]->LoadFromStyleDef(GAMESTATE->GetCurrentStyleDef(), (PlayerNumber)p);
}
/* LoadNextSong first, since that positions some elements which need to be
* positioned before we TweenOnScreen. */
LoadNextSong();
2002-08-28 22:42:40 +00:00
TweenOnScreen();
2002-05-20 08:59:37 +00:00
2003-01-19 04:44:22 +00:00
2003-03-09 00:55:49 +00:00
if( !bDemonstration ) // only load if we're going to use it
2003-01-19 04:44:22 +00:00
{
2003-03-09 00:55:49 +00:00
m_soundOniDie.Load( THEME->GetPathTo("Sounds","ScreenGameplay oni die") );
m_announcerReady.Load( ANNOUNCER->GetPathTo("gameplay ready"), 1 );
2003-01-19 04:44:22 +00:00
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
m_announcerHereWeGo.Load( ANNOUNCER->GetPathTo("gameplay here we go extra"), 1 );
2003-01-19 04:44:22 +00:00
else if( GAMESTATE->IsFinalStage() )
m_announcerHereWeGo.Load( ANNOUNCER->GetPathTo("gameplay here we go final"), 1 );
2003-01-19 04:44:22 +00:00
else
m_announcerHereWeGo.Load( ANNOUNCER->GetPathTo("gameplay here we go normal"), 1 );
m_announcerDanger.Load( ANNOUNCER->GetPathTo("gameplay comment danger") );
m_announcerGood.Load( ANNOUNCER->GetPathTo("gameplay comment good") );
m_announcerHot.Load( ANNOUNCER->GetPathTo("gameplay comment hot") );
m_announcerOni.Load( ANNOUNCER->GetPathTo("gameplay comment oni") );
m_announcer100Combo.Load( ANNOUNCER->GetPathTo("gameplay 100 combo") );
m_announcer200Combo.Load( ANNOUNCER->GetPathTo("gameplay 200 combo") );
m_announcer300Combo.Load( ANNOUNCER->GetPathTo("gameplay 300 combo") );
m_announcer400Combo.Load( ANNOUNCER->GetPathTo("gameplay 400 combo") );
m_announcer500Combo.Load( ANNOUNCER->GetPathTo("gameplay 500 combo") );
m_announcer600Combo.Load( ANNOUNCER->GetPathTo("gameplay 600 combo") );
m_announcer700Combo.Load( ANNOUNCER->GetPathTo("gameplay 700 combo") );
m_announcer800Combo.Load( ANNOUNCER->GetPathTo("gameplay 800 combo") );
m_announcer900Combo.Load( ANNOUNCER->GetPathTo("gameplay 900 combo") );
m_announcer1000Combo.Load( ANNOUNCER->GetPathTo("gameplay 1000 combo") );
m_announcerComboStopped.Load( ANNOUNCER->GetPathTo("gameplay combo stopped") );
2003-03-09 00:55:49 +00:00
m_soundAssistTick.Load( THEME->GetPathTo("Sounds","ScreenGameplay assist tick") );
}
2003-01-19 04:44:22 +00:00
m_iRowLastCrossed = -1;
// Get the transitions rolling on the first update.
// We can't do this in the constructor because ScreenGameplay is constructed
// in the middle of ScreenStage.
2002-05-20 08:59:37 +00:00
}
ScreenGameplay::~ScreenGameplay()
{
LOG->Trace( "ScreenGameplay::~ScreenGameplay()" );
2002-07-23 01:41:40 +00:00
for( int p=0; p<NUM_PLAYERS; p++ )
{
2002-08-28 22:42:40 +00:00
SAFE_DELETE( m_pLifeMeter[p] );
SAFE_DELETE( m_pScoreDisplay[p] );
SAFE_DELETE( m_pScoreKeeper[p] );
2002-07-23 01:41:40 +00:00
}
2002-12-29 22:57:38 +00:00
m_soundMusic.StopPlaying();
2002-05-20 08:59:37 +00:00
}
2002-07-28 20:28:37 +00:00
bool ScreenGameplay::IsLastSong()
2002-06-24 22:04:31 +00:00
{
2003-03-26 23:08:05 +00:00
if( GAMESTATE->m_pCurCourse && GAMESTATE->m_pCurCourse->m_bRepeat )
return false;
return GAMESTATE->GetCourseSongIndex()+1 == (int)m_apSongsQueue.size(); // GetCourseSongIndex() is 0-based but size() is not
2002-07-28 20:28:37 +00:00
}
2002-06-24 22:04:31 +00:00
void ScreenGameplay::LoadNextSong()
2002-07-28 20:28:37 +00:00
{
GAMESTATE->ResetMusicStatistics();
int p;
for( p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(p) )
GAMESTATE->m_CurStageStats.iSongsPlayed[p]++;
2002-06-14 22:25:22 +00:00
2003-03-26 23:08:05 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
m_textCourseSongNumber[p].SetText( ssprintf("%d", GAMESTATE->m_CurStageStats.iSongsPlayed[p]) );
2003-03-26 23:08:05 +00:00
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
iPlaySongIndex %= m_apSongsQueue.size();
GAMESTATE->m_pCurSong = m_apSongsQueue[iPlaySongIndex];
2003-03-26 23:08:05 +00:00
// Restore the player's originally selected options.
GAMESTATE->RestoreSelectedOptions();
2002-06-14 22:25:22 +00:00
m_textSongOptions.SetText( GAMESTATE->m_SongOptions.GetString() );
2002-07-28 20:28:37 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
2002-06-14 22:25:22 +00:00
{
2002-07-28 20:28:37 +00:00
if( !GAMESTATE->IsPlayerEnabled(p) )
2002-06-14 22:25:22 +00:00
continue;
2003-03-26 23:08:05 +00:00
GAMESTATE->m_pCurNotes[p] = m_apNotesQueue[p][iPlaySongIndex];
m_pScoreKeeper[p]->OnNextSong( GAMESTATE->GetCourseSongIndex(), GAMESTATE->m_pCurNotes[p] );
// Put courses options into effect.
GAMESTATE->m_PlayerOptions[p].FromString( m_asModifiersQueue[p][iPlaySongIndex] );
GAMESTATE->m_SongOptions.FromString( m_asModifiersQueue[p][iPlaySongIndex] );
m_textPlayerOptions[p].SetText( GAMESTATE->m_PlayerOptions[p].GetString() );
2002-08-01 21:55:40 +00:00
// reset oni game over graphic
m_sprOniGameOver[p].SetY( SCREEN_TOP - m_sprOniGameOver[p].GetZoomedHeight()/2 );
m_sprOniGameOver[p].SetDiffuse( RageColor(1,1,1,0) ); // 0 alpha so we don't waste time drawing while not visible
2002-08-01 21:55:40 +00:00
if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BATTERY && GAMESTATE->m_CurStageStats.bFailed[p] ) // already failed
2002-08-01 21:55:40 +00:00
ShowOniGameOver((PlayerNumber)p);
2002-10-06 16:56:58 +00:00
m_DifficultyIcon[p].SetFromNotes( PlayerNumber(p), GAMESTATE->m_pCurNotes[p] );
2002-06-14 22:25:22 +00:00
2002-10-12 00:39:00 +00:00
NoteData pOriginalNoteData;
GAMESTATE->m_pCurNotes[p]->GetNoteData( &pOriginalNoteData );
2002-06-14 22:25:22 +00:00
2002-08-22 23:03:39 +00:00
const StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
2002-10-12 00:39:00 +00:00
NoteData pNewNoteData;
pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, &pOriginalNoteData, &pNewNoteData );
2002-06-14 22:25:22 +00:00
m_Player[p].Load( (PlayerNumber)p, &pNewNoteData, m_pLifeMeter[p], m_pScoreDisplay[p], &m_Inventory[p], m_pScoreKeeper[p] );
2003-03-27 00:51:57 +00:00
m_TimingAssist.Reset();
2002-06-14 22:25:22 +00:00
}
2003-02-04 21:36:30 +00:00
/* Set up song-specific graphics. */
2002-08-22 09:31:32 +00:00
m_Background.LoadFromSong( GAMESTATE->m_pCurSong );
m_Background.SetDiffuse( RageColor(0.5f,0.5f,0.5f,1) );
m_Background.BeginTweening( 2 );
m_Background.SetTweenDiffuse( RageColor(1,1,1,1) );
2002-07-23 01:41:40 +00:00
2003-03-30 18:12:57 +00:00
m_textSongTitle.SetText( GAMESTATE->m_pCurSong->m_sMainTitle );
2003-02-04 21:36:30 +00:00
/* XXX: set it to the current BPM, not the range */
float fMinBPM, fMaxBPM;
GAMESTATE->m_pCurSong->GetMinMaxBPM( fMinBPM, fMaxBPM );
m_BPMDisplay.SetBPMRange( fMinBPM, fMaxBPM );
const bool bExtra = GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2();
const bool bReverse[NUM_PLAYERS] = {
GAMESTATE->m_PlayerOptions[0].m_fReverseScroll == 1,
GAMESTATE->m_PlayerOptions[1].m_fReverseScroll == 1
};
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
continue;
m_ActiveItemList[p].SetXY( ACTIVE_ITEMS_X(p), ACTIVE_ITEMS_Y(p,bExtra,bReverse[p]) );
m_DifficultyIcon[p].SetXY( DIFFICULTY_X(p), DIFFICULTY_Y(p,bExtra,bReverse[p]) );
}
2003-03-19 22:48:43 +00:00
/* XXX: We want to put the lyrics out of the way, but it's likely that one
* player is in reverse and the other isn't. What to do? */
m_LyricDisplay.SetXY( LYRICS_X, LYRICS_Y(bExtra,bReverse[GAMESTATE->m_MasterPlayerNumber]) );
2002-12-27 23:16:16 +00:00
m_soundMusic.Load( GAMESTATE->m_pCurSong->GetMusicPath() );
2003-03-19 19:58:22 +00:00
// Load lyrics
// XXX: don't load this here
LyricsLoader LL;
if( GAMESTATE->m_pCurSong->HasLyrics() )
LL.LoadFromLRCFile(GAMESTATE->m_pCurSong->GetLyricsPath(), *GAMESTATE->m_pCurSong);
}
2003-01-25 08:32:57 +00:00
float ScreenGameplay::StartPlayingSong(float MinTimeToNotes, float MinTimeToMusic)
{
2003-01-25 08:32:57 +00:00
ASSERT(MinTimeToNotes >= 0);
ASSERT(MinTimeToMusic >= 0);
/* XXX: We want the first beat *in use*, so we don't delay needlessly. */
const float fFirstBeat = GAMESTATE->m_pCurSong->m_fFirstBeat;
const float fFirstSecond = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat( fFirstBeat );
2003-01-25 08:32:57 +00:00
float fStartSecond = fFirstSecond - MinTimeToNotes;
2002-12-29 23:31:29 +00:00
2003-01-25 08:32:57 +00:00
fStartSecond = min(fStartSecond, -MinTimeToMusic);
m_soundMusic.SetPositionSeconds( fStartSecond );
2002-07-23 01:41:40 +00:00
m_soundMusic.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
2002-12-29 23:31:29 +00:00
/* Keep the music playing after it's finished; we'll stop it. */
m_soundMusic.SetStopMode(RageSound::M_CONTINUE);
m_soundMusic.StartPlaying();
/* Return the amount of time until the first beat. */
2003-01-25 08:10:35 +00:00
return fFirstSecond - fStartSecond;
2002-06-14 22:25:22 +00:00
}
2002-07-27 19:29:51 +00:00
bool ScreenGameplay::OneIsHot()
{
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
2002-08-20 21:00:56 +00:00
if( m_pLifeMeter[p]->IsHot() )
2002-07-27 19:29:51 +00:00
return true;
return false;
}
bool ScreenGameplay::AllAreInDanger()
{
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
if( !m_pLifeMeter[p]->IsInDanger() )
return false;
return true;
}
bool ScreenGameplay::AllAreFailing()
{
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
if( !m_pLifeMeter[p]->IsFailing() )
return false;
return true;
}
bool ScreenGameplay::AllFailedEarlier()
{
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(p) )
if( !m_pLifeMeter[p]->FailedEarlier() )
return false;
return true;
}
2002-10-12 00:32:47 +00:00
// play assist ticks
bool ScreenGameplay::IsTimeToPlayTicks() const
2002-10-12 00:32:47 +00:00
{
// Sound cards have a latency between when a sample is Play()ed and when the sound
// will start coming out the speaker. Compensate for this by boosting
// fPositionSeconds ahead
float fPositionSeconds = GAMESTATE->m_fMusicSeconds;
2003-03-09 00:55:49 +00:00
fPositionSeconds += (SOUNDMAN->GetPlayLatency()+(float)G_TICK_EARLY_SECONDS) * m_soundMusic.GetPlaybackRate();
float fSongBeat = GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds );
2002-10-12 00:32:47 +00:00
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
iRowNow = max( 0, iRowNow );
static int iRowLastCrossed = 0;
bool bAnyoneHasANote = false; // set this to true if any player has a note at one of the indicies we crossed
for( int r=iRowLastCrossed+1; r<=iRowNow; r++ ) // for each index we crossed since the last update
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
bAnyoneHasANote |= m_Player[p].IsThereATapAtRow( r );
2002-10-12 00:32:47 +00:00
break; // this will only play the tick for the first player that is joined
}
}
iRowLastCrossed = iRowNow;
return bAnyoneHasANote;
}
2002-06-14 22:25:22 +00:00
2002-05-20 08:59:37 +00:00
void ScreenGameplay::Update( float fDeltaTime )
{
if( GAMESTATE->m_pCurSong == NULL )
{
/* ScreenDemonstration will move us to the next screen. We just need to
* survive for one update without crashing. We need to call Screen::Update
* to make sure we receive the next-screen message. */
Screen::Update( fDeltaTime );
return;
}
if( m_bFirstUpdate )
{
SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("gameplay intro") ); // crowd cheer
//
// Get the transitions rolling
//
if( m_bDemonstration )
{
StartPlayingSong( 0, 0 ); // *kick* (no transitions)
}
else
{
float fMinTimeToMusic = m_In.GetLengthSeconds(); // start of m_Ready
float fMinTimeToNotes = fMinTimeToMusic + m_Ready.GetLengthSeconds() + m_Go.GetLengthSeconds()+2; // end of Go
/*
* Tell the music to start, but don't actually make any noise for
* at least 2.5 (or 1.5) seconds. (This is so we scroll on screen smoothly.)
*
* This is only a minimum: the music might be started later, to meet
* the minimum-time-to-notes value. If you're writing song data,
* and you want to make sure we get ideal timing here, make sure there's
* a bit of space at the beginning of the music with no steps.
*/
/*float delay =*/ StartPlayingSong( fMinTimeToNotes, fMinTimeToMusic );
m_In.StartTransitioning( SM_PlayReady );
}
}
2003-02-10 22:08:10 +00:00
/* Very important: Update GAMESTATE's song beat information
* -before- calling update on all the classes that depend on it.
* If you don't do this first, the classes are all acting on old
* information and will lag. -Chris */
2002-06-24 22:04:31 +00:00
/* If ScreenJukebox is changing screens, it'll stop m_soundMusic to tell
* us not to update the time here. (In that case, we've already created
* a new ScreenJukebox and reset music statistics, and if we do this then
* we'll un-reset them.) */
if(m_soundMusic.IsPlaying())
GAMESTATE->UpdateSongPosition(m_soundMusic.GetPositionSeconds());
2002-07-23 01:41:40 +00:00
2003-02-10 22:08:10 +00:00
Screen::Update( fDeltaTime );
if( GAMESTATE->m_pCurSong == NULL )
return;
2003-02-10 22:08:10 +00:00
2003-02-11 02:20:38 +00:00
if( GAMESTATE->m_MasterPlayerNumber != PLAYER_INVALID )
2003-03-16 20:55:45 +00:00
m_MaxCombo.SetText( ssprintf("%d", GAMESTATE->m_CurStageStats.iCurCombo[GAMESTATE->m_MasterPlayerNumber]) ); /* MAKE THIS WORK FOR BOTH PLAYERS! */
2003-02-10 22:08:10 +00:00
//LOG->Trace( "m_fOffsetInBeats = %f, m_fBeatsPerSecond = %f, m_Music.GetPositionSeconds = %f", m_fOffsetInBeats, m_fBeatsPerSecond, m_Music.GetPositionSeconds() );
2002-05-20 08:59:37 +00:00
2003-02-06 17:47:00 +00:00
int pn;
2002-05-20 08:59:37 +00:00
switch( m_DancingState )
{
case STATE_DANCING:
//
2003-03-30 20:54:37 +00:00
// Update living players' alive time
//
2003-02-06 17:47:00 +00:00
for( pn=0; pn<NUM_PLAYERS; pn++ )
2003-03-30 20:54:37 +00:00
if( GAMESTATE->IsPlayerEnabled(pn) && !GAMESTATE->m_CurStageStats.bFailed[pn])
GAMESTATE->m_CurStageStats.fAliveSeconds [pn] += fDeltaTime;
2002-07-27 19:29:51 +00:00
//
2002-05-20 08:59:37 +00:00
// Check for end of song
2002-07-27 19:29:51 +00:00
//
float fSecondsToStop = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat ) + 1;
if( GAMESTATE->m_fMusicSeconds > fSecondsToStop && !m_OniFade.IsClosing() )
2002-08-01 03:15:27 +00:00
{
GAMESTATE->m_fSongBeat = 0;
2003-03-25 21:17:29 +00:00
this->PostScreenMessage( SM_NotesEnded, 0 );
2002-08-01 03:15:27 +00:00
}
2002-07-27 19:29:51 +00:00
//
// check for fail
//
switch( GAMESTATE->m_SongOptions.m_FailType )
2002-07-27 19:29:51 +00:00
{
case SongOptions::FAIL_ARCADE:
2002-08-01 21:55:40 +00:00
switch( GAMESTATE->m_SongOptions.m_LifeType )
{
case SongOptions::LIFE_BAR:
2003-03-25 21:17:29 +00:00
if( AllAreFailing() ) SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 );
2002-08-01 21:55:40 +00:00
if( AllAreInDanger() ) m_Background.TurnDangerOn();
else m_Background.TurnDangerOff();
// check for individual fail
for ( pn=0; pn<NUM_PLAYERS; pn++ )
{
if ( m_pLifeMeter[pn]->IsFailing() && !GAMESTATE->m_CurStageStats.bFailed[pn] )
GAMESTATE->m_CurStageStats.bFailed[pn] = true; // fail
}
2002-08-01 21:55:40 +00:00
break;
case SongOptions::LIFE_BATTERY:
2003-03-25 21:17:29 +00:00
if( AllFailedEarlier() )SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 );
2002-08-01 21:55:40 +00:00
if( AllAreInDanger() ) m_Background.TurnDangerOn();
else m_Background.TurnDangerOff();
2002-07-27 19:29:51 +00:00
2002-08-01 21:55:40 +00:00
// check for individual fail
for( pn=0; pn<NUM_PLAYERS; pn++ )
{
2002-11-02 21:51:18 +00:00
if( !GAMESTATE->IsPlayerEnabled(pn) )
continue;
if( !m_pLifeMeter[pn]->IsFailing())
continue; /* isn't failing */
if( GAMESTATE->m_CurStageStats.bFailed[pn] )
2002-11-02 21:51:18 +00:00
continue; /* failed and is already dead */
if( !AllFailedEarlier() ) // if not the last one to fail
{
// kill them!
m_soundOniDie.PlayRandom();
ShowOniGameOver((PlayerNumber)pn);
m_Player[pn].Init(); // remove all notes and scoring
m_Player[pn].FadeToFail(); // tell the NoteField to fade to white
}
2003-02-17 00:30:55 +00:00
GAMESTATE->m_CurStageStats.bFailed[pn] = true;
2002-11-02 21:51:18 +00:00
}
2002-08-01 21:55:40 +00:00
break;
}
2002-07-27 19:29:51 +00:00
break;
case SongOptions::FAIL_END_OF_SONG:
case SongOptions::FAIL_OFF:
2002-07-27 19:29:51 +00:00
break; // don't check for fail
default:
ASSERT(0);
}
//
2003-03-09 00:55:49 +00:00
// Check to see if it's time to play a ScreenGameplay comment
2002-07-27 19:29:51 +00:00
//
m_fTimeLeftBeforeDancingComment -= fDeltaTime;
if( m_fTimeLeftBeforeDancingComment <= 0 )
2002-05-20 08:59:37 +00:00
{
switch( GAMESTATE->m_PlayMode )
2002-08-02 09:31:06 +00:00
{
case PLAY_MODE_ARCADE:
2003-02-25 00:33:42 +00:00
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
if( OneIsHot() ) m_announcerHot.PlayRandom();
else if( AllAreInDanger() ) m_announcerDanger.PlayRandom();
else m_announcerGood.PlayRandom();
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
m_announcerOni.PlayRandom();
break;
default:
ASSERT(0);
2002-08-02 09:31:06 +00:00
}
2002-08-20 21:00:56 +00:00
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; // reset for the next comment
2002-05-20 08:59:37 +00:00
}
}
2002-06-24 22:04:31 +00:00
//
// Send crossed row messages to Player
//
2003-02-10 22:08:10 +00:00
// Why was this originally "BeatToNoteRowNotRounded"? It should be rounded. -Chris
int iRowNow = BeatToNoteRow( GAMESTATE->m_fSongBeat );
2003-02-25 19:59:29 +00:00
if( iRowNow >= 0 )
2002-06-24 22:04:31 +00:00
{
2002-08-15 16:45:49 +00:00
for( int r=m_iRowLastCrossed+1; r<=iRowNow; r++ ) // for each index we crossed since the last update
2002-06-24 22:04:31 +00:00
{
2003-02-06 17:47:00 +00:00
for( pn=0; pn<NUM_PLAYERS; pn++ )
2002-08-15 16:45:49 +00:00
{
2003-02-06 17:47:00 +00:00
if( GAMESTATE->IsPlayerEnabled(pn) )
m_Player[pn].CrossedRow( r );
2002-08-15 16:45:49 +00:00
}
2002-06-24 22:04:31 +00:00
}
2002-08-15 16:45:49 +00:00
m_iRowLastCrossed = iRowNow;
}
2002-06-24 22:04:31 +00:00
2003-03-27 06:02:03 +00:00
if( GAMESTATE->m_SongOptions.m_bAssistTick && IsTimeToPlayTicks())
m_soundAssistTick.Play();
2002-05-20 08:59:37 +00:00
}
void ScreenGameplay::DrawPrimitives()
{
Screen::DrawPrimitives();
}
void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
{
//LOG->Trace( "ScreenGameplay::Input()" );
2003-01-19 21:57:13 +00:00
if( MenuI.IsValid() &&
MenuI.button == MENU_BUTTON_BACK &&
m_DancingState != STATE_OUTRO &&
2003-03-09 00:55:49 +00:00
!m_Back.IsTransitioning() )
2003-01-19 21:57:13 +00:00
{
if( PREFSMAN->m_bDelayedEscape && type==IET_FIRST_PRESS)
{
m_textDebug.SetText( "Continue holding BACK to quit" );
m_textDebug.StopTweening();
m_textDebug.SetDiffuse( RageColor(1,1,1,0) );
m_textDebug.BeginTweening( 1/8.f );
m_textDebug.SetTweenDiffuse( RageColor(1,1,1,1) );
return;
}
if( PREFSMAN->m_bDelayedEscape && type==IET_RELEASE )
{
m_textDebug.StopTweening();
m_textDebug.BeginTweening( 1/8.f );
m_textDebug.SetTweenDiffuse( RageColor(1,1,1,0) );
return;
}
if( (!PREFSMAN->m_bDelayedEscape && type==IET_FIRST_PRESS) ||
(DeviceI.device==DEVICE_KEYBOARD && type==IET_SLOW_REPEAT) ||
(DeviceI.device!=DEVICE_KEYBOARD && type==IET_FAST_REPEAT) )
{
m_DancingState = STATE_OUTRO;
2003-03-09 00:55:49 +00:00
SOUNDMAN->PlayOnce( THEME->GetPathTo("Sounds","Common back") );
2003-01-19 21:57:13 +00:00
/* Hmm. There are a bunch of subtly different ways we can
* tween out:
* 1. Keep rendering the song, and keep it moving. This might
* cause problems if the cancel and the end of the song overlap.
* 2. Stop the song completely, so all song motion under the tween
* ceases.
* 3. Stop the song, but keep effects (eg. Drunk) running.
* 4. Don't display the song at all.
*
* We're doing #3. I'm not sure which is best.
*/
m_soundMusic.StopPlaying();
this->ClearMessageQueue();
2003-03-09 00:55:49 +00:00
m_Back.StartTransitioning( SM_SaveChangedBeforeGoingBack );
2003-01-19 21:57:13 +00:00
return;
}
}
/* Nothing else cares about releases. */
if(type == IET_RELEASE) return;
2002-05-20 08:59:37 +00:00
2002-06-24 22:04:31 +00:00
// Handle special keys to adjust the offset
2002-07-03 21:27:26 +00:00
if( DeviceI.device == DEVICE_KEYBOARD )
2002-06-24 22:04:31 +00:00
{
switch( DeviceI.button )
{
case SDLK_F6:
2002-10-01 01:55:39 +00:00
m_bChangedOffsetOrBPM = true;
GAMESTATE->m_SongOptions.m_bAutoSync = !GAMESTATE->m_SongOptions.m_bAutoSync; // toggle
UpdateAutoPlayText();
2002-10-01 01:55:39 +00:00
break;
case SDLK_F7:
GAMESTATE->m_SongOptions.m_bAssistTick ^= 1;
m_textDebug.SetText( ssprintf("Assist Tick is %s", GAMESTATE->m_SongOptions.m_bAssistTick?"ON":"OFF") );
m_textDebug.SetDiffuse( RageColor(1,1,1,1) );
m_textDebug.StopTweening();
m_textDebug.BeginTweening( 3 ); // sleep
m_textDebug.BeginTweening( 0.5f ); // fade out
m_textDebug.SetTweenDiffuse( RageColor(1,1,1,0) );
break;
case SDLK_F8:
2002-07-27 19:29:51 +00:00
PREFSMAN->m_bAutoPlay = !PREFSMAN->m_bAutoPlay;
UpdateAutoPlayText();
2002-07-27 19:29:51 +00:00
break;
case SDLK_F9:
case SDLK_F10:
2002-07-27 19:29:51 +00:00
{
m_bChangedOffsetOrBPM = true;
float fOffsetDelta;
switch( DeviceI.button )
{
case SDLK_F9: fOffsetDelta = -0.025f; break;
case SDLK_F10: fOffsetDelta = +0.025f; break;
2002-09-07 10:43:16 +00:00
default: ASSERT(0); return;
2002-07-27 19:29:51 +00:00
}
if( type == IET_FAST_REPEAT )
fOffsetDelta *= 10;
2002-08-02 09:31:06 +00:00
BPMSegment& seg = GAMESTATE->m_pCurSong->GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat );
2002-07-27 19:29:51 +00:00
seg.m_fBPM += fOffsetDelta;
m_textDebug.SetText( ssprintf("Cur BPM = %f", seg.m_fBPM) );
m_textDebug.SetDiffuse( RageColor(1,1,1,1) );
2002-07-27 19:29:51 +00:00
m_textDebug.StopTweening();
m_textDebug.BeginTweening( 3 ); // sleep
m_textDebug.BeginTweening( 0.5f ); // fade out
m_textDebug.SetTweenDiffuse( RageColor(1,1,1,0) );
2002-07-27 19:29:51 +00:00
}
break;
case SDLK_F11:
case SDLK_F12:
2002-07-03 21:27:26 +00:00
{
2002-07-27 19:29:51 +00:00
m_bChangedOffsetOrBPM = true;
2002-07-03 21:27:26 +00:00
float fOffsetDelta;
switch( DeviceI.button )
{
case SDLK_F11: fOffsetDelta = -0.02f; break;
case SDLK_F12: fOffsetDelta = +0.02f; break;
2002-09-07 10:43:16 +00:00
default: ASSERT(0); return;
2002-07-03 21:27:26 +00:00
}
if( type == IET_FAST_REPEAT )
fOffsetDelta *= 10;
2002-07-03 21:27:26 +00:00
2002-07-23 01:41:40 +00:00
GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds += fOffsetDelta;
2002-07-03 21:27:26 +00:00
m_textDebug.SetText( ssprintf("Offset = %f", GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds) );
m_textDebug.SetDiffuse( RageColor(1,1,1,1) );
2002-07-03 21:27:26 +00:00
m_textDebug.StopTweening();
m_textDebug.BeginTweening( 3 ); // sleep
m_textDebug.BeginTweening( 0.5f ); // fade out
m_textDebug.SetTweenDiffuse( RageColor(1,1,1,0) );
2002-07-03 21:27:26 +00:00
}
2002-06-24 22:04:31 +00:00
break;
}
}
2002-07-27 19:29:51 +00:00
//
2003-02-25 00:33:42 +00:00
// handle a step or battle item activate
2002-07-27 19:29:51 +00:00
//
2003-01-25 11:05:12 +00:00
if( type==IET_FIRST_PRESS &&
!PREFSMAN->m_bAutoPlay &&
StyleI.IsValid() &&
GAMESTATE->IsPlayerEnabled( StyleI.player ) )
{
2003-01-25 11:05:12 +00:00
m_Player[StyleI.player].Step( StyleI.col );
}
2003-02-25 00:33:42 +00:00
else if( type==IET_FIRST_PRESS &&
!PREFSMAN->m_bAutoPlay &&
MenuI.IsValid() &&
GAMESTATE->IsPlayerEnabled( MenuI.player ) )
{
int iItemSlot;
switch( MenuI.button )
{
case MENU_BUTTON_LEFT: iItemSlot = 0; break;
case MENU_BUTTON_START: iItemSlot = 1; break;
case MENU_BUTTON_RIGHT: iItemSlot = 2; break;
default: iItemSlot = -1; break;
}
if( iItemSlot != -1 )
2003-04-07 05:14:27 +00:00
m_Inventory[MenuI.player].UseItem( iItemSlot );
2003-02-25 00:33:42 +00:00
}
2002-05-20 08:59:37 +00:00
}
void ScreenGameplay::UpdateAutoPlayText()
{
2003-03-09 00:55:49 +00:00
CString sText;
2003-03-09 00:55:49 +00:00
if( PREFSMAN->m_bAutoPlay )
sText += "AutoPlay ";
if( GAMESTATE->m_SongOptions.m_bAutoSync )
sText += "AutoSync ";
2003-03-09 00:55:49 +00:00
if( sText.length() > 0 )
sText.resize( sText.length()-5 );
m_textAutoPlay.SetText( sText );
}
2002-08-02 09:31:06 +00:00
void SaveChanges()
2002-07-27 19:29:51 +00:00
{
2002-10-17 23:31:17 +00:00
/* XXX: Hmm. Better would be to make sure m_pCurCourse is only set when we're
* playing out of a course, and use that here, so these things wouldn't need to
* special case play modes. Need to make sure m_pCurCourse gets erased
* correctly, though. -glenn */
/* That's a very clever idea! I should look into this. -Chris */
2002-07-28 20:28:37 +00:00
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
2003-02-25 00:33:42 +00:00
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
2002-09-11 04:49:07 +00:00
GAMESTATE->m_pCurSong->Save();
2002-07-28 20:28:37 +00:00
break;
case PLAY_MODE_NONSTOP:
2002-07-28 20:28:37 +00:00
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
// FIXME!!!
2003-03-26 23:08:05 +00:00
//for( int i=0; i<m_apSongsQueue.size(); i++ )
// m_apSongsQueue[i]->Save();
2002-07-28 20:28:37 +00:00
}
break;
default:
ASSERT(0);
}
2002-07-27 19:29:51 +00:00
}
2002-08-02 09:31:06 +00:00
void DontSaveChanges()
2002-07-27 19:29:51 +00:00
{
2002-09-06 23:36:04 +00:00
SMLoader ld;
2002-07-28 20:28:37 +00:00
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
2003-02-25 00:33:42 +00:00
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
2002-09-06 23:36:04 +00:00
ld.LoadFromSMFile(GAMESTATE->m_pCurSong->GetCacheFilePath(),
*GAMESTATE->m_pCurSong);
2002-07-28 20:28:37 +00:00
break;
case PLAY_MODE_NONSTOP:
2002-07-28 20:28:37 +00:00
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
// FIXME
2003-03-26 23:08:05 +00:00
// for( unsigned i=0; i<m_apSongsQueue.size(); i++ )
// {
2003-03-26 23:08:05 +00:00
// Song* pSong = m_apSongsQueue[i];
2003-02-25 00:33:42 +00:00
// ld.LoadFromSMFile( pSong->GetCacheFilePath(), *pSong );
// }
2002-07-28 20:28:37 +00:00
}
break;
default:
ASSERT(0);
}
2002-07-27 19:29:51 +00:00
}
void ShowSavePrompt( ScreenMessage SM_SendWhenDone )
{
2002-07-28 20:28:37 +00:00
CString sMessage;
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
2003-02-25 00:33:42 +00:00
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
2002-07-28 20:28:37 +00:00
sMessage = ssprintf(
"You have changed the offset or BPM of\n"
"%s.\n"
"Would you like to save these changes back\n"
"to the song file?\n"
2002-08-20 06:26:34 +00:00
"Choosing NO will discard your changes.",
2003-02-11 23:52:18 +00:00
GAMESTATE->m_pCurSong->GetFullDisplayTitle().GetString() );
2002-07-28 20:28:37 +00:00
break;
case PLAY_MODE_NONSTOP:
2002-07-28 20:28:37 +00:00
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
sMessage = ssprintf(
"You have changed the offset or BPM of\n"
"one or more songs in this course.\n"
"Would you like to save these changes back\n"
"to the song file(s)?\n"
2002-08-20 06:26:34 +00:00
"Choosing NO will discard your changes." );
2002-07-28 20:28:37 +00:00
break;
default:
ASSERT(0);
}
SCREENMAN->Prompt( SM_SendWhenDone, sMessage, true, true, SaveChanges, DontSaveChanges );
2002-07-27 19:29:51 +00:00
}
2002-05-20 08:59:37 +00:00
void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
{
switch( SM )
{
2003-03-09 00:55:49 +00:00
case SM_PlayReady:
2003-01-25 11:05:12 +00:00
m_Background.FadeIn();
2003-03-09 00:55:49 +00:00
m_announcerReady.PlayRandom();
m_Ready.StartTransitioning( SM_PlayGo );
2002-05-20 08:59:37 +00:00
break;
2003-03-09 00:55:49 +00:00
case SM_PlayGo:
m_announcerHereWeGo.PlayRandom();
2003-03-09 00:55:49 +00:00
m_Go.StartTransitioning( SM_None );
2003-01-26 04:58:07 +00:00
GAMESTATE->m_bPastHereWeGo = true;
m_DancingState = STATE_DANCING; // STATE CHANGE! Now the user is allowed to press Back
break;
2002-05-20 08:59:37 +00:00
// received while STATE_DANCING
2002-07-11 19:02:26 +00:00
case SM_NotesEnded:
2002-07-23 01:41:40 +00:00
{
// save any statistics
2002-11-16 20:21:00 +00:00
int p;
for( p=0; p<NUM_PLAYERS; p++ )
2002-07-28 20:28:37 +00:00
{
if( GAMESTATE->IsPlayerEnabled(p) )
{
for( int r=0; r<NUM_RADAR_CATEGORIES; r++ )
{
RadarCategory rc = (RadarCategory)r;
GAMESTATE->m_CurStageStats.fRadarPossible[p][r] = NoteDataUtil::GetRadarValue( m_Player[p], rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
GAMESTATE->m_CurStageStats.fRadarActual[p][r] = m_Player[p].GetActualRadarValue( rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
2002-07-28 20:28:37 +00:00
}
}
}
GAMESTATE->RemoveAllActiveAttacks();
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(p) )
continue;
if( !GAMESTATE->m_CurStageStats.bFailed[p] )
GAMESTATE->m_CurStageStats.iSongsPassed[p]++;
}
2002-07-27 19:29:51 +00:00
2002-07-28 20:28:37 +00:00
if( !IsLastSong() )
2002-07-27 19:29:51 +00:00
{
for( p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(p) && !GAMESTATE->m_CurStageStats.bFailed[p] )
m_pLifeMeter[p]->OnSongEnded(); // give a little life back between stages
2002-08-01 03:15:27 +00:00
m_OniFade.CloseWipingRight( SM_BeginLoadingNextSong );
2002-07-27 19:29:51 +00:00
}
2002-07-28 20:28:37 +00:00
else // IsLastSong
2002-07-27 19:29:51 +00:00
{
2003-03-09 00:55:49 +00:00
if( m_DancingState == STATE_OUTRO ) // ScreenGameplay already ended
2002-07-28 20:28:37 +00:00
return; // ignore
m_DancingState = STATE_OUTRO;
if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_END_OF_SONG && AllFailedEarlier() )
2002-07-28 20:28:37 +00:00
{
2003-03-25 21:17:29 +00:00
this->PostScreenMessage( SM_BeginFailed, 0 );
2002-07-28 20:28:37 +00:00
}
2003-03-09 00:55:49 +00:00
else // ! failed
{
2003-03-09 00:55:49 +00:00
// do they deserve an extra stage?
if( GAMESTATE->HasEarnedExtraStage() )
{
m_Extra.StartTransitioning( SM_GoToStateAfterCleared );
SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("gameplay extra") );
2003-03-25 21:17:29 +00:00
// this->PostScreenMessage( SM_ShowTryExtraStage, 1 );
2003-03-09 00:55:49 +00:00
}
else
{
m_Cleared.StartTransitioning( SM_GoToStateAfterCleared );
SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("gameplay cleared") );
2003-03-25 21:17:29 +00:00
// this->PostScreenMessage( SM_ShowCleared, 1 );
2003-03-09 00:55:49 +00:00
}
2002-07-28 20:28:37 +00:00
}
2002-07-27 19:29:51 +00:00
}
2002-05-20 08:59:37 +00:00
}
break;
2002-08-01 03:15:27 +00:00
case SM_BeginLoadingNextSong:
LoadNextSong();
2003-02-09 21:10:56 +00:00
GAMESTATE->m_bPastHereWeGo = true;
2003-02-05 20:50:12 +00:00
/* We're fading in, so don't hit any notes for a few seconds; they'll be
* obscured by the fade. */
StartPlayingSong( 3, 0 );
2002-08-01 03:15:27 +00:00
m_OniFade.OpenWipingRight( SM_None );
break;
2003-03-16 19:11:51 +00:00
case SM_PlayToasty:
if( PREFSMAN->m_bEasterEggs )
2003-03-16 19:11:51 +00:00
if( !m_Toasty.IsTransitioning() && !m_Toasty.IsFinished() ) // don't play if we've already played it once
m_Toasty.StartTransitioning();
break;
2002-07-11 19:02:26 +00:00
case SM_100Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer100Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_200Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer200Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_300Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer300Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_400Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer400Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_500Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer500Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_600Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer600Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_700Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer700Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_800Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer800Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_900Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer900Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_1000Combo:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcer1000Combo.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
case SM_ComboStopped:
if( m_fTimeLeftBeforeDancingComment < 12 )
{
m_announcerComboStopped.PlayRandom();
m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2002-07-11 19:02:26 +00:00
}
break;
2003-03-09 00:55:49 +00:00
2002-07-11 19:02:26 +00:00
2003-03-09 00:55:49 +00:00
/* // received while STATE_OUTRO
2002-05-20 08:59:37 +00:00
case SM_ShowCleared:
m_sprCleared.BeginTweening(1.0f);
m_sprCleared.SetTweenDiffuse( RageColor(1,1,1,1) );
m_sprCleared.BeginTweening(1.5f); // sleep
2002-08-27 16:53:25 +00:00
m_sprCleared.BeginTweening(0.7f);
m_sprCleared.SetTweenDiffuse( RageColor(1,1,1,0) );
2003-03-25 21:17:29 +00:00
SCREENMAN->PostMessageToTopScreen( SM_GoToStateAfterCleared, 4 );
break;
2003-03-09 00:55:49 +00:00
*/
/* case SM_ShowTryExtraStage:
{
m_soundTryExtraStage.PlayRandom();
// make the background invisible so we don't waste mem bandwidth drawing it
m_Background.BeginTweening( 1 );
m_Background.SetTweenDiffuse( RageColor(1,1,1,0) );
RageColor colorStage = GAMESTATE->GetStageColor();
colorStage.a *= 0.7f;
m_sprTryExtraStage.SetZoom( 4 );
2003-03-02 01:43:33 +00:00
m_sprTryExtraStage.BeginBlurredTweening( 0.8f, TWEEN_DECELERATE );
m_sprTryExtraStage.SetTweenZoom( 0.4f ); // zoom out
m_sprTryExtraStage.SetTweenDiffuse( colorStage ); // and fade in
m_sprTryExtraStage.BeginTweening( 0.2f );
m_sprTryExtraStage.SetTweenZoom( 0.8f ); // bounce
m_sprTryExtraStage.SetTweenDiffuse( colorStage ); // and fade in
m_sprTryExtraStage.BeginTweening( 0.2f );
m_sprTryExtraStage.SetTweenZoom( 1.0f ); // come to rest
m_sprTryExtraStage.SetTweenDiffuse( colorStage ); // and fade in
colorStage.a = 0;
m_sprTryExtraStage.BeginTweening( 2 ); // sleep
m_sprTryExtraStage.BeginTweening( 1 ); // fade out
m_sprTryExtraStage.SetTweenDiffuse( colorStage );
2003-03-25 21:17:29 +00:00
SCREENMAN->PostMessageToTopScreen( SM_GoToStateAfterCleared, 5 );
}
2002-07-27 19:29:51 +00:00
break;
2003-03-09 00:55:49 +00:00
*/
2002-08-01 05:11:11 +00:00
case SM_SaveChangedBeforeGoingBack:
if( m_bChangedOffsetOrBPM )
{
m_bChangedOffsetOrBPM = false;
ShowSavePrompt( SM_GoToScreenAfterBack );
}
2002-08-01 13:42:56 +00:00
else
HandleScreenMessage( SM_GoToScreenAfterBack );
2002-08-01 05:11:11 +00:00
break;
2003-03-09 00:55:49 +00:00
2002-07-27 19:29:51 +00:00
case SM_GoToScreenAfterBack:
/* Reset options. (Should this be done in ScreenSelect*?) */
GAMESTATE->RestoreSelectedOptions();
2002-07-27 19:29:51 +00:00
switch( GAMESTATE->m_PlayMode )
{
2002-07-29 03:06:55 +00:00
case PLAY_MODE_ARCADE:
2003-02-25 00:33:42 +00:00
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
// SCREENMAN->SetNewScreen( "ScreenSelectMusic" );
SCREENMAN->SetNewScreen( SONGSEL_SCREEN );
2002-07-29 03:06:55 +00:00
break;
case PLAY_MODE_NONSTOP:
2002-07-29 03:06:55 +00:00
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
SCREENMAN->SetNewScreen( "ScreenSelectCourse" );
2002-07-29 03:06:55 +00:00
break;
2003-03-09 00:55:49 +00:00
default:
ASSERT(0);
2002-07-27 19:29:51 +00:00
}
2002-05-20 08:59:37 +00:00
break;
2003-03-09 00:55:49 +00:00
2002-07-27 19:29:51 +00:00
case SM_GoToStateAfterCleared:
/* Reset options. (Should this be done in ScreenSelect*?) */
GAMESTATE->RestoreSelectedOptions();
2002-07-27 19:29:51 +00:00
if( m_bChangedOffsetOrBPM )
{
m_bChangedOffsetOrBPM = false;
ShowSavePrompt( SM_GoToStateAfterCleared );
break;
}
2003-03-25 21:17:29 +00:00
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
2003-03-25 21:17:29 +00:00
SCREENMAN->SetNewScreen( "ScreenEvaluationStage" );
break;
2003-03-25 21:17:29 +00:00
case PLAY_MODE_NONSTOP:
2003-03-28 05:47:42 +00:00
SCREENMAN->SetNewScreen( "ScreenEvaluationNonstop" );
break;
2003-03-25 21:17:29 +00:00
case PLAY_MODE_ONI:
2003-03-28 05:47:42 +00:00
SCREENMAN->SetNewScreen( "ScreenEvaluationOni" );
break;
2003-03-25 21:17:29 +00:00
case PLAY_MODE_ENDLESS:
2003-03-28 05:47:42 +00:00
SCREENMAN->SetNewScreen( "ScreenEvaluationEndless" );
2003-03-25 21:17:29 +00:00
break;
default:
ASSERT(0);
}
2002-05-20 08:59:37 +00:00
break;
case SM_BeginFailed:
m_DancingState = STATE_OUTRO;
2002-12-29 22:57:38 +00:00
m_soundMusic.StopPlaying();
2003-03-09 00:55:49 +00:00
m_Failed.StartTransitioning( SM_GoToScreenAfterFail );
2002-05-20 08:59:37 +00:00
2003-03-09 00:55:49 +00:00
// make the background invisible so we don't waste power drawing it
2002-05-20 08:59:37 +00:00
m_Background.BeginTweening( 1 );
m_Background.SetTweenDiffuse( RageColor(1,1,1,0) );
2002-05-20 08:59:37 +00:00
2002-08-01 13:42:56 +00:00
// show the survive time if extra stage
2003-03-25 21:17:29 +00:00
// TODO: Move this animation to a metric?
2002-08-01 13:42:56 +00:00
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
{
float fMaxSurviveSeconds = 0;
2002-08-01 13:42:56 +00:00
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(p) )
fMaxSurviveSeconds = max( fMaxSurviveSeconds, GAMESTATE->m_CurStageStats.fAliveSeconds[p] );
ASSERT( fMaxSurviveSeconds > 0 );
m_textSurviveTime.SetText( "TIME: " + SecondsToTime(fMaxSurviveSeconds) );
2002-08-01 13:42:56 +00:00
m_textSurviveTime.BeginTweening( 0.3f ); // sleep
m_textSurviveTime.BeginTweening( 0.3f ); // fade in
m_textSurviveTime.SetTweenDiffuse( RageColor(1,1,1,1) );
m_textSurviveTime.BeginTweening( 3.5f ); // sleep
m_textSurviveTime.BeginTweening( 0.5f ); // fade out
m_textSurviveTime.SetTweenDiffuse( RageColor(1,1,1,0) );
2002-08-01 13:42:56 +00:00
}
SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("gameplay failed") );
2002-05-20 08:59:37 +00:00
break;
2002-05-27 08:23:27 +00:00
case SM_GoToScreenAfterFail:
/* Reset options. (Should this be done in ScreenSelect*?) */
GAMESTATE->RestoreSelectedOptions();
2002-07-27 19:29:51 +00:00
if( m_bChangedOffsetOrBPM )
{
m_bChangedOffsetOrBPM = false;
ShowSavePrompt( SM_GoToScreenAfterFail );
break;
}
2003-03-25 21:17:29 +00:00
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
case PLAY_MODE_BATTLE:
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE:
2003-03-25 21:17:29 +00:00
if( PREFSMAN->m_bEventMode )
HandleScreenMessage( SM_GoToScreenAfterBack );
else if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
SCREENMAN->SetNewScreen( "ScreenEvaluationSummary" );
else
SCREENMAN->SetNewScreen( "ScreenGameOver" );
break;
case PLAY_MODE_NONSTOP:
2003-03-28 05:47:42 +00:00
SCREENMAN->SetNewScreen( "ScreenEvaluationNonstop" );
break;
2003-03-25 21:17:29 +00:00
case PLAY_MODE_ONI:
2003-03-28 05:47:42 +00:00
SCREENMAN->SetNewScreen( "ScreenEvaluationOni" );
break;
2003-03-25 21:17:29 +00:00
case PLAY_MODE_ENDLESS:
2003-03-28 05:47:42 +00:00
SCREENMAN->SetNewScreen( "ScreenEvaluationEndless" );
2003-03-25 21:17:29 +00:00
break;
default:
ASSERT(0);
}
2002-05-20 08:59:37 +00:00
}
2002-06-14 22:25:22 +00:00
}
2002-05-20 08:59:37 +00:00
2002-06-14 22:25:22 +00:00
void ScreenGameplay::TweenOnScreen()
{
unsigned i, p;
2002-06-14 22:25:22 +00:00
/* XXX: m_sprLifeFrame.GetChildren(apActorsInLifeFrame) */
2003-01-03 05:56:28 +00:00
vector<Actor*> apActorsInLifeFrame;
apActorsInLifeFrame.push_back( &m_sprLifeFrame );
2002-08-28 22:42:40 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
2002-10-31 04:23:39 +00:00
apActorsInLifeFrame.push_back( m_pLifeMeter[p] );
apActorsInLifeFrame.push_back( &m_sprStage );
2002-08-28 22:42:40 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
2002-10-31 04:23:39 +00:00
apActorsInLifeFrame.push_back( &m_textCourseSongNumber[p] );
for( i=0; i<apActorsInLifeFrame.size(); i++ )
2002-08-28 22:42:40 +00:00
{
float fOriginalY = apActorsInLifeFrame[i]->GetY();
apActorsInLifeFrame[i]->SetY( fOriginalY-100 );
apActorsInLifeFrame[i]->BeginTweening( 0.5f ); // sleep
apActorsInLifeFrame[i]->BeginTweening( 1 );
apActorsInLifeFrame[i]->SetTweenY( fOriginalY );
2002-08-28 22:42:40 +00:00
}
2003-01-03 05:56:28 +00:00
vector<Actor*> apActorsInScoreFrame;
2002-10-31 04:23:39 +00:00
apActorsInScoreFrame.push_back( &m_sprScoreFrame );
2002-08-28 22:42:40 +00:00
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(p) )
continue;
2002-10-31 04:23:39 +00:00
apActorsInScoreFrame.push_back( m_pScoreDisplay[p] );
apActorsInScoreFrame.push_back( &m_textPlayerOptions[p] );
2002-08-28 22:42:40 +00:00
}
2002-10-31 04:23:39 +00:00
apActorsInScoreFrame.push_back( &m_textSongOptions );
for( i=0; i<apActorsInScoreFrame.size(); i++ )
2002-08-28 22:42:40 +00:00
{
float fOriginalY = apActorsInScoreFrame[i]->GetY();
apActorsInScoreFrame[i]->SetY( fOriginalY+100 );
apActorsInScoreFrame[i]->BeginTweening( 0.5f ); // sleep
apActorsInScoreFrame[i]->BeginTweening( 1 );
apActorsInScoreFrame[i]->SetTweenY( fOriginalY );
2002-08-28 22:42:40 +00:00
}
for( p=0; p<NUM_PLAYERS; p++ )
{
2002-10-06 16:56:58 +00:00
float fOriginalX = m_DifficultyIcon[p].GetX();
m_DifficultyIcon[p].SetX( (p==PLAYER_1) ? fOriginalX-200 : fOriginalX+200 );
m_DifficultyIcon[p].BeginTweening( 0.5f ); // sleep
2002-10-06 16:56:58 +00:00
m_DifficultyIcon[p].BeginTweening( 1 );
m_DifficultyIcon[p].SetTweenX( fOriginalX );
2002-08-28 22:42:40 +00:00
}
2002-05-20 08:59:37 +00:00
}
2002-06-14 22:25:22 +00:00
void ScreenGameplay::TweenOffScreen()
{
}
void ScreenGameplay::ShowOniGameOver( PlayerNumber pn )
2002-08-01 21:55:40 +00:00
{
m_sprOniGameOver[pn].SetDiffuse( RageColor(1,1,1,1) );
m_sprOniGameOver[pn].BeginTweening( 0.5f, Actor::TWEEN_BOUNCE_END );
m_sprOniGameOver[pn].SetTweenY( CENTER_Y );
2003-03-02 01:43:33 +00:00
m_sprOniGameOver[pn].SetEffectBob( 4, RageVector3(0,6,0) );
2002-08-01 21:55:40 +00:00
}