2003-02-16 04:01:45 +00:00
#include "global.h"
2002-05-20 08:59:37 +00:00
#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"
2002-07-23 01:41:40 +00:00
#include "LifeMeterBar.h"
#include "LifeMeterBattery.h"
2005-04-21 04:27:13 +00:00
#include "LifeMeterTime.h"
2002-07-23 01:41:40 +00:00
#include "GameState.h"
#include "ScoreDisplayNormal.h"
2003-10-05 05:24:50 +00:00
#include "ScoreDisplayPercentage.h"
2005-04-21 11:16:01 +00:00
#include "ScoreDisplayLifeTime.h"
2002-07-23 01:41:40 +00:00
#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"
2002-08-27 03:59:22 +00:00
#include "GrooveRadar.h"
2002-09-06 23:36:04 +00:00
#include "NotesLoaderSM.h"
2002-11-11 04:53:31 +00:00
#include "ThemeManager.h"
2003-01-25 07:40:47 +00:00
#include "RageTimer.h"
2003-03-16 18:57:34 +00:00
#include "ScoreKeeperMAX2.h"
2003-06-30 18:08:27 +00:00
#include "ScoreKeeperRave.h"
2003-04-02 21:57:25 +00:00
#include "NoteFieldPositioning.h"
2003-03-19 12:43:49 +00:00
#include "LyricsLoader.h"
2003-04-13 21:17:14 +00:00
#include "ActorUtil.h"
2003-04-22 04:54:04 +00:00
#include "NoteSkinManager.h"
#include "RageTextureManager.h"
2004-07-08 00:10:34 +00:00
#include "GameSoundManager.h"
2003-06-30 18:08:27 +00:00
#include "CombinedLifeMeterTug.h"
2003-07-08 19:56:56 +00:00
#include "Inventory.h"
2003-07-17 20:10:07 +00:00
#include "Course.h"
2003-08-07 06:36:34 +00:00
#include "NoteDataUtil.h"
2005-02-21 06:22:46 +00:00
#include "UnlockManager.h"
2003-11-16 04:45:12 +00:00
#include "LightsManager.h"
2003-12-17 10:21:31 +00:00
#include "ProfileManager.h"
2005-02-16 03:25:45 +00:00
#include "StatsManager.h"
2004-01-11 23:33:56 +00:00
#include "PlayerAI.h" // for NUM_SKILL_LEVELS
2004-03-16 22:10:45 +00:00
#include "NetworkSyncManager.h"
2004-05-23 00:53:20 +00:00
#include "Foreach.h"
2004-08-19 01:18:11 +00:00
#include "DancingCharacters.h"
2004-09-21 06:07:12 +00:00
#include "ScreenDimensions.h"
2004-11-06 20:36:04 +00:00
#include "ThemeMetric.h"
2004-12-20 21:27:24 +00:00
#include "PlayerState.h"
2005-01-15 02:01:26 +00:00
#include "Style.h"
2005-01-30 02:43:32 +00:00
#include "LuaManager.h"
2005-02-06 08:48:55 +00:00
#include "MemoryCardManager.h"
2005-03-20 09:52:48 +00:00
#include "CommonMetrics.h"
2005-05-08 04:10:16 +00:00
#include "InputMapper.h"
#include "Game.h"
2003-03-19 12:43:49 +00:00
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
//
2004-05-31 08:58:43 +00:00
#define SHOW_LIFE_METER_FOR_DISABLED_PLAYERS THEME->GetMetricB(m_sName,"ShowLifeMeterForDisabledPlayers")
#define EVAL_ON_FAIL THEME->GetMetricB(m_sName,"ShowEvaluationOnFail")
#define SHOW_SCORE_IN_RAVE THEME->GetMetricB(m_sName,"ShowScoreInRave")
#define SONG_POSITION_METER_WIDTH THEME->GetMetricF(m_sName,"SongPositionMeterWidth")
2004-11-07 05:49:06 +00:00
#define PLAYER_X( p, styleType ) THEME->GetMetricF(m_sName,ssprintf("PlayerP%d%sX",p+1,StyleTypeToString(styleType).c_str()))
2005-04-09 11:32:10 +00:00
#define STOP_COURSE_EARLY THEME->GetMetricB(m_sName,"StopCourseEarly") // evaluate this every time it's used
2003-04-22 14:32:48 +00:00
2005-02-26 06:22:40 +00:00
static ThemeMetric < float > INITIAL_BACKGROUND_BRIGHTNESS ( "ScreenGameplay" , "InitialBackgroundBrightness" );
2004-11-06 20:36:04 +00:00
static ThemeMetric < float > SECONDS_BETWEEN_COMMENTS ( "ScreenGameplay" , "SecondsBetweenComments" );
2003-04-13 21:17:14 +00:00
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_PlayGo )
2002-05-20 08:59:37 +00:00
// received while STATE_DANCING
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_LoadNextSong )
AutoScreenMessage ( SM_StartLoadingNextSong )
2005-03-23 08:48:38 +00:00
2002-05-20 08:59:37 +00:00
// received while STATE_OUTRO
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_GoToScreenAfterBack )
2002-05-20 08:59:37 +00:00
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_BeginFailed )
2005-04-10 06:21:59 +00:00
AutoScreenMessage ( SM_LeaveGameplay )
2002-05-20 08:59:37 +00:00
2003-01-25 07:40:47 +00:00
// received while STATE_INTRO
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_StartHereWeGo )
AutoScreenMessage ( SM_StopHereWeGo )
2002-05-20 08:59:37 +00:00
2005-05-19 01:26:41 +00:00
static Preference < float > g_fNetStartOffset ( "NetworkStartOffset" , - 3.0 );
2003-10-25 07:58:10 +00:00
2004-11-26 17:28:47 +00:00
REGISTER_SCREEN_CLASS ( ScreenGameplay );
2005-04-01 12:35:49 +00:00
ScreenGameplay :: ScreenGameplay ( CString sName ) : ScreenWithMenuElements ( sName )
2002-05-20 08:59:37 +00:00
{
2005-02-26 06:22:40 +00:00
PLAYER_TYPE . Load ( sName , "PlayerType" );
2005-03-12 00:04:27 +00:00
GIVE_UP_TEXT . Load ( sName , "GiveUpText" );
GIVE_UP_ABORTED_TEXT . Load ( sName , "GiveUpAbortedText" );
2005-03-23 02:11:33 +00:00
MUSIC_FADE_OUT_SECONDS . Load ( sName , "MusicFadeOutSeconds" );
2005-03-10 02:45:40 +00:00
START_GIVES_UP . Load ( sName , "StartGivesUp" );
BACK_GIVES_UP . Load ( sName , "BackGivesUp" );
2005-04-27 06:34:53 +00:00
GIVING_UP_GOES_TO_PREV_SCREEN . Load ( sName , "GivingUpGoesToPrevScreen" );
2005-04-10 06:21:59 +00:00
GIVING_UP_GOES_TO_NEXT_SCREEN . Load ( sName , "GivingUpGoesToNextScreen" );
2005-05-09 15:14:19 +00:00
FAIL_AFTER_30_MISSES . Load ( sName , "FailAfter30Misses" );
2005-04-24 11:03:02 +00:00
USE_FORCED_MODIFIERS_IN_BEGINNER . Load ( sName , "UseForcedModifiersInBeginner" );
FORCED_MODIFIERS_IN_BEGINNER . Load ( sName , "ForcedModifiersInBeginner" );
2004-02-18 02:31:43 +00:00
}
2002-05-20 08:59:37 +00:00
2004-02-18 02:31:43 +00:00
void ScreenGameplay :: Init ()
{
2005-04-01 12:35:49 +00:00
ScreenWithMenuElements :: Init ();
2005-01-03 22:44:19 +00:00
2005-02-06 08:48:55 +00:00
/* Pause MEMCARDMAN. If a memory card is remove, we don't want to interrupt the
* player by making a noise until the game finishes. */
2005-02-06 10:10:38 +00:00
if ( ! GAMESTATE -> m_bDemonstrationOrJukebox )
MEMCARDMAN -> PauseMountingThread ();
2005-02-06 08:48:55 +00:00
2005-01-03 23:20:11 +00:00
if ( GAMESTATE -> m_bDemonstrationOrJukebox )
2004-03-23 06:11:10 +00:00
LIGHTSMAN -> SetLightsMode ( LIGHTSMODE_DEMONSTRATION );
2003-11-16 04:45:12 +00:00
else
2004-03-30 04:44:09 +00:00
LIGHTSMAN -> SetLightsMode ( LIGHTSMODE_GAMEPLAY );
2003-11-16 04:45:12 +00:00
2004-10-25 03:47:22 +00:00
m_pSoundMusic = NULL ;
2005-03-11 02:52:40 +00:00
m_bPaused = false ;
2004-10-25 03:47:22 +00:00
2004-05-21 00:58:48 +00:00
/* We do this ourself. */
SOUND -> HandleSongTimer ( false );
2003-12-18 08:53:38 +00:00
2003-11-13 00:39:36 +00:00
//need to initialize these before checking for demonstration mode
//otherwise destructor will try to delete possibly invalid pointers
2004-05-16 12:34:02 +00:00
FOREACH_PlayerNumber ( p )
2003-11-13 00:39:36 +00:00
{
m_pLifeMeter [ p ] = NULL ;
2003-11-26 06:40:03 +00:00
m_pPrimaryScoreDisplay [ p ] = NULL ;
m_pSecondaryScoreDisplay [ p ] = NULL ;
2003-11-13 00:39:36 +00:00
m_pPrimaryScoreKeeper [ p ] = NULL ;
m_pSecondaryScoreKeeper [ p ] = NULL ;
m_pInventory [ p ] = NULL ;
}
m_pCombinedLifeMeter = NULL ;
2003-03-09 00:55:49 +00:00
2003-02-04 21:36:30 +00:00
if ( GAMESTATE -> m_pCurSong == NULL && GAMESTATE -> m_pCurCourse == NULL )
2005-01-03 21:05:40 +00:00
return ; // ScreenDemonstration will move us to the next screen. We just need to survive for one update without crashing.
2003-01-19 21:05:03 +00:00
2003-02-24 03:26:33 +00:00
/* Save selected options before we change them. */
GAMESTATE -> StoreSelectedOptions ();
2004-03-30 03:55:54 +00:00
/* Save settings to the profile now. Don't do this on extra stages, since the
* user doesn't have full control; saving would force profiles to DIFFICULTY_HARD
* and save over their default modifiers every time someone got an extra stage.
* Do this before course modifiers are set up. */
if ( ! GAMESTATE -> IsExtraStage () && ! GAMESTATE -> IsExtraStage2 () )
{
FOREACH_HumanPlayer ( pn )
GAMESTATE -> SaveCurrentSettingsToProfile ( pn );
}
2005-02-23 04:46:05 +00:00
/* Called once per stage (single song or single course). */
GAMESTATE -> BeginStage ();
2003-04-14 22:12:54 +00:00
2003-04-07 21:24:14 +00:00
2002-08-28 22:42:40 +00:00
2003-01-10 02:22:07 +00:00
2003-04-07 21:24:14 +00:00
// fill in difficulty of CPU players with that of the first human player
2004-05-16 23:15:17 +00:00
FOREACH_PotentialCpuPlayer ( p )
2005-02-25 18:17:26 +00:00
GAMESTATE -> m_pCurSteps [ p ]. Set ( GAMESTATE -> m_pCurSteps [ GAMESTATE -> GetFirstHumanPlayer () ] );
2003-04-07 21:24:14 +00:00
2005-01-03 23:29:40 +00:00
/* Increment the course play count. */
if ( GAMESTATE -> IsCourseMode () && ! GAMESTATE -> m_bDemonstrationOrJukebox )
FOREACH_EnabledPlayer ( p )
PROFILEMAN -> IncrementCoursePlayCount ( GAMESTATE -> m_pCurCourse , GAMESTATE -> m_pCurTrail [ p ], p );
2003-03-26 23:08:05 +00:00
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . playMode = GAMESTATE -> m_PlayMode ;
STATSMAN -> m_CurStageStats . pStyle = GAMESTATE -> m_pCurStyle ;
2003-09-06 01:20:56 +00:00
2005-03-18 07:53:16 +00:00
/* Record combo rollover. */
FOREACH_EnabledPlayer ( pn )
STATSMAN -> m_CurStageStats . m_player [ pn ]. UpdateComboList ( 0 , true );
2003-09-06 01:20:56 +00:00
2003-09-06 01:35:29 +00:00
if ( GAMESTATE -> IsExtraStage () )
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . StageType = StageStats :: STAGE_EXTRA ;
2003-09-06 01:35:29 +00:00
else if ( GAMESTATE -> IsExtraStage2 () )
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . StageType = StageStats :: STAGE_EXTRA2 ;
2003-09-06 01:35:29 +00:00
else
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . StageType = StageStats :: STAGE_NORMAL ;
2003-09-06 01:35:29 +00:00
2003-03-26 23:08:05 +00:00
//
// Init ScoreKeepers
//
2004-05-16 12:34:02 +00:00
2004-05-16 12:42:16 +00:00
FOREACH_EnabledPlayer ( p )
2003-03-16 18:57:34 +00:00
{
2005-05-16 09:36:32 +00:00
switch ( PREFSMAN -> m_ScoringType )
2003-08-11 09:58:18 +00:00
{
2003-08-11 23:12:01 +00:00
case PrefsManager :: SCORING_MAX2 :
2003-09-08 21:50:05 +00:00
case PrefsManager :: SCORING_5TH :
2004-12-22 07:31:27 +00:00
m_pPrimaryScoreKeeper [ p ] = new ScoreKeeperMAX2 (
GAMESTATE -> m_pPlayerState [ p ],
2005-02-16 03:25:45 +00:00
& STATSMAN -> m_CurStageStats . m_player [ p ] );
2003-08-11 09:58:18 +00:00
break ;
2003-08-11 23:12:01 +00:00
default : ASSERT ( 0 );
2003-08-11 09:58:18 +00:00
}
2003-06-30 18:08:27 +00:00
switch ( GAMESTATE -> m_PlayMode )
{
case PLAY_MODE_RAVE :
2004-12-22 07:31:27 +00:00
m_pSecondaryScoreKeeper [ p ] = new ScoreKeeperRave (
GAMESTATE -> m_pPlayerState [ p ],
2005-02-16 03:25:45 +00:00
& STATSMAN -> m_CurStageStats . m_player [ p ] );
2003-06-30 18:08:27 +00:00
break ;
}
2003-03-16 18:57:34 +00:00
}
2002-05-20 08:59:37 +00:00
m_DancingState = STATE_INTRO ;
2003-08-07 07:34:42 +00:00
// Set this in LoadNextSong()
//m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS;
2005-05-07 09:58:23 +00:00
2003-04-13 00:44:50 +00:00
m_bZeroDeltaOnNextUpdate = false ;
2005-05-07 09:58:23 +00:00
2003-03-08 08:03:22 +00:00
2005-03-11 02:52:40 +00:00
m_SongBackground . SetName ( "SongBackground" );
2005-03-11 02:12:21 +00:00
m_SongBackground . SetDrawOrder ( DRAW_ORDER_BEFORE_EVERYTHING );
2005-03-11 02:52:40 +00:00
ON_COMMAND ( m_SongBackground );
2005-03-11 02:12:21 +00:00
this -> AddChild ( & m_SongBackground );
2004-01-07 00:13:32 +00:00
2005-03-11 02:52:40 +00:00
m_SongForeground . SetName ( "SongForeground" );
m_SongForeground . SetDrawOrder ( DRAW_ORDER_OVERLAY + 1 ); // on top of the overlay, but under transitions
ON_COMMAND ( m_SongBackground );
this -> AddChild ( & m_SongForeground );
2004-01-07 00:13:32 +00:00
2005-03-11 02:06:39 +00:00
if ( PREFSMAN -> m_bShowBeginnerHelper )
{
m_BeginnerHelper . SetDrawOrder ( DRAW_ORDER_BEFORE_EVERYTHING );
m_BeginnerHelper . SetXY ( SCREEN_CENTER_X , SCREEN_CENTER_Y );
this -> AddChild ( & m_BeginnerHelper );
}
2003-10-08 23:32:08 +00:00
2003-10-09 06:43:51 +00:00
m_sprStaticBackground . SetName ( "StaticBG" );
2004-05-31 08:58:43 +00:00
m_sprStaticBackground . Load ( THEME -> GetPathG ( m_sName , "Static Background" ) );
2003-10-09 06:43:51 +00:00
SET_XY ( m_sprStaticBackground );
2004-05-02 03:01:27 +00:00
m_sprStaticBackground . SetDrawOrder ( DRAW_ORDER_BEFORE_EVERYTHING ); // behind everything else
2003-10-08 23:32:08 +00:00
this -> AddChild ( & m_sprStaticBackground );
2002-05-20 08:59:37 +00:00
2005-01-03 23:20:11 +00:00
if ( ! GAMESTATE -> m_bDemonstrationOrJukebox ) // only load if we're going to use it
2003-04-13 23:22:27 +00:00
{
2004-05-31 08:58:43 +00:00
m_Toasty . Load ( THEME -> GetPathB ( m_sName , "toasty" ) );
2003-04-13 23:22:27 +00:00
this -> AddChild ( & m_Toasty );
}
2004-05-16 12:34:02 +00:00
FOREACH_EnabledPlayer ( p )
2002-05-27 08:23:27 +00:00
{
2004-11-07 05:49:06 +00:00
float fPlayerX = PLAYER_X ( p , GAMESTATE -> GetCurrentStyle () -> m_StyleType );
2003-03-02 06:16:03 +00:00
2003-09-08 01:38:19 +00:00
/* Perhaps this should be handled better by defining a new
* StyleType for ONE_PLAYER_ONE_CREDIT_AND_ONE_COMPUTER,
* but for now just ignore SoloSingles when it's Battle or Rave
* Mode. This doesn't begin to address two-player solo (6 arrows) */
2003-03-02 06:16:03 +00:00
if ( PREFSMAN -> m_bSoloSingle &&
2003-09-08 01:38:19 +00:00
GAMESTATE -> m_PlayMode != PLAY_MODE_BATTLE &&
GAMESTATE -> m_PlayMode != PLAY_MODE_RAVE &&
2004-11-07 05:49:06 +00:00
GAMESTATE -> GetCurrentStyle () -> m_StyleType == ONE_PLAYER_ONE_SIDE )
fPlayerX = SCREEN_CENTER_X ;
2003-03-02 06:16:03 +00:00
2005-05-21 06:17:56 +00:00
m_Player [ p ]. SetName ( ssprintf ( "PlayerP%i" , p + 1 ) );
2005-05-21 01:56:08 +00:00
m_Player [ p ]. SetXY ( fPlayerX , SCREEN_CENTER_Y );
2002-09-02 21:59:58 +00:00
this -> AddChild ( & m_Player [ p ] );
2002-08-01 21:55:40 +00:00
2005-05-09 04:07:07 +00:00
m_sprOniGameOver [ p ]. SetName ( ssprintf ( "OniGameOverP%i" , p + 1 ) );
2004-05-31 08:58:43 +00:00
m_sprOniGameOver [ p ]. Load ( THEME -> GetPathG ( m_sName , "oni gameover" ) );
2005-05-09 04:07:07 +00:00
SET_XY_AND_ON_COMMAND ( m_sprOniGameOver [ p ] );
2002-09-02 21:59:58 +00:00
this -> AddChild ( & m_sprOniGameOver [ p ] );
2002-05-27 08:23:27 +00:00
}
2002-05-20 08:59:37 +00:00
2005-03-19 00:03:53 +00:00
m_NextSong . Load ( THEME -> GetPathB ( m_sName , "next course song" ) );
m_NextSong . SetDrawOrder ( DRAW_ORDER_TRANSITIONS - 1 );
this -> AddChild ( & m_NextSong );
2002-08-01 21:55:40 +00:00
2004-05-02 03:01:27 +00:00
m_SongFinished . SetDrawOrder ( DRAW_ORDER_TRANSITIONS - 1 );
2004-03-06 10:07:17 +00:00
this -> AddChild ( & m_SongFinished );
2002-06-14 22:25:22 +00:00
2005-02-06 03:32:53 +00:00
bool bBattery = GAMESTATE -> m_SongOptions . m_LifeType == SongOptions :: LIFE_BATTERY ;
2003-11-19 12:33:52 +00:00
//
// Add LifeFrame
//
2005-02-06 03:32:53 +00:00
m_sprLifeFrame . Load ( THEME -> GetPathG ( m_sName , bBattery ? "oni life frame" : "life frame" ) );
2005-05-06 10:48:32 +00:00
m_sprLifeFrame -> SetName ( "LifeFrame" );
2003-04-13 21:17:14 +00:00
SET_XY ( m_sprLifeFrame );
2005-05-06 10:48:32 +00:00
this -> AddChild ( m_sprLifeFrame );
2002-10-18 19:01:32 +00:00
2003-07-08 19:56:56 +00:00
//
2003-11-19 12:33:52 +00:00
// Add score frame
//
2005-02-06 03:32:53 +00:00
m_sprScoreFrame . Load ( THEME -> GetPathG ( m_sName , bBattery ? "oni score frame" : "score frame" ) );
2004-05-31 08:58:43 +00:00
m_sprScoreFrame . SetName ( "ScoreFrame" );
2003-11-19 12:33:52 +00:00
SET_XY ( m_sprScoreFrame );
this -> AddChild ( & m_sprScoreFrame );
//
// Add combined life meter
2003-07-08 19:56:56 +00:00
//
switch ( GAMESTATE -> m_PlayMode )
{
2003-08-19 04:27:50 +00:00
case PLAY_MODE_BATTLE :
2003-07-08 19:56:56 +00:00
case PLAY_MODE_RAVE :
2003-08-19 04:27:50 +00:00
m_pCombinedLifeMeter = new CombinedLifeMeterTug ;
2004-05-31 08:58:43 +00:00
m_pCombinedLifeMeter -> SetName ( "CombinedLife" );
2003-07-08 19:56:56 +00:00
SET_XY ( * m_pCombinedLifeMeter );
this -> AddChild ( m_pCombinedLifeMeter );
break ;
}
2004-04-06 02:05:34 +00:00
//
// Before the lifemeter loads, if Networking is required
// we need to wait, so that there is no Dead On Start issues.
// if you wait too long at the second checkpoint, you will
// appear dead when you begin your game.
//
2004-07-15 16:17:41 +00:00
NSMAN -> StartRequest ( 0 );
2004-04-06 02:05:34 +00:00
2003-07-08 19:56:56 +00:00
//
2003-11-19 12:33:52 +00:00
// Add individual life meter
2003-07-08 19:56:56 +00:00
//
2003-06-30 18:08:27 +00:00
switch ( GAMESTATE -> m_PlayMode )
2002-05-20 08:59:37 +00:00
{
2004-06-11 06:05:35 +00:00
case PLAY_MODE_REGULAR :
2003-06-30 18:08:27 +00:00
case PLAY_MODE_ONI :
case PLAY_MODE_NONSTOP :
case PLAY_MODE_ENDLESS :
2004-05-16 19:22:37 +00:00
FOREACH_PlayerNumber ( p )
2002-07-23 01:41:40 +00:00
{
2004-05-16 19:22:37 +00:00
if ( ! GAMESTATE -> IsPlayerEnabled ( p ) && ! SHOW_LIFE_METER_FOR_DISABLED_PLAYERS )
2003-07-08 19:56:56 +00:00
continue ; // skip
2003-06-30 18:08:27 +00:00
switch ( GAMESTATE -> m_SongOptions . m_LifeType )
{
case SongOptions :: LIFE_BAR :
m_pLifeMeter [ p ] = new LifeMeterBar ;
break ;
case SongOptions :: LIFE_BATTERY :
m_pLifeMeter [ p ] = new LifeMeterBattery ;
break ;
2005-04-21 04:27:13 +00:00
case SongOptions :: LIFE_TIME :
m_pLifeMeter [ p ] = new LifeMeterTime ;
break ;
2003-06-30 18:08:27 +00:00
default :
ASSERT ( 0 );
}
2004-07-23 04:45:48 +00:00
m_pLifeMeter [ p ] -> Load ( p );
2004-05-31 08:58:43 +00:00
m_pLifeMeter [ p ] -> SetName ( ssprintf ( "LifeP%d" , p + 1 ) );
2003-06-30 18:08:27 +00:00
SET_XY ( * m_pLifeMeter [ p ] );
this -> AddChild ( m_pLifeMeter [ p ] );
}
break ;
2003-11-19 12:33:52 +00:00
case PLAY_MODE_BATTLE :
case PLAY_MODE_RAVE :
break ;
2002-05-20 08:59:37 +00:00
}
2004-08-18 05:16:45 +00:00
m_ShowScoreboard = false ;
2004-08-14 22:58:57 +00:00
2004-08-13 08:24:11 +00:00
//the following is only used in SMLAN/SMOnline
2005-04-02 17:07:28 +00:00
if ( NSMAN -> useSMserver && ( ! GAMESTATE -> PlayerUsingBothSides () ) )
2004-08-13 08:24:11 +00:00
{
2004-12-01 20:42:15 +00:00
PlayerNumber pn = GAMESTATE -> GetFirstDisabledPlayer ();
if ( pn != PLAYER_INVALID )
{
FOREACH_NSScoreBoardColumn ( col )
2004-08-18 05:16:45 +00:00
{
2004-12-01 20:42:15 +00:00
m_Scoreboard [ col ]. LoadFromFont ( THEME -> GetPathF ( m_sName , "scoreboard" ) );
m_Scoreboard [ col ]. SetShadowLength ( 0 );
m_Scoreboard [ col ]. SetName ( ssprintf ( "ScoreboardC%iP%i" , col + 1 , pn + 1 ) );
SET_XY ( m_Scoreboard [ col ] );
this -> AddChild ( & m_Scoreboard [ col ] );
m_Scoreboard [ col ]. SetText ( NSMAN -> m_Scoreboard [ col ] );
m_Scoreboard [ col ]. SetVertAlign ( align_top );
2004-08-18 05:16:45 +00:00
m_ShowScoreboard = true ;
}
2004-12-01 20:42:15 +00:00
}
2004-08-13 08:24:11 +00:00
}
2002-05-20 08:59:37 +00:00
2004-07-25 06:29:50 +00:00
m_MaxCombo . LoadFromFont ( THEME -> GetPathF ( m_sName , "max combo" ) );
2003-04-13 21:17:14 +00:00
m_MaxCombo . SetName ( "MaxCombo" );
SET_XY ( m_MaxCombo );
2005-02-16 03:25:45 +00:00
m_MaxCombo . SetText ( ssprintf ( "%d" , STATSMAN -> m_CurStageStats . m_player [ GAMESTATE -> m_MasterPlayerNumber ]. iMaxCombo ) ); // TODO: Make this work for both players
2002-11-07 19:42:39 +00:00
this -> AddChild ( & m_MaxCombo );
2004-05-16 12:34:02 +00:00
FOREACH_EnabledPlayer ( p )
2002-05-20 08:59:37 +00:00
{
2003-11-26 06:40:03 +00:00
//
// primary score display
//
2002-08-28 22:42:40 +00:00
switch ( GAMESTATE -> m_PlayMode )
2002-08-13 23:26:46 +00:00
{
2004-06-11 06:05:35 +00:00
case PLAY_MODE_REGULAR :
2003-03-26 19:15:38 +00:00
case PLAY_MODE_NONSTOP :
2003-11-19 12:33:52 +00:00
case PLAY_MODE_BATTLE :
2003-11-26 06:40:03 +00:00
case PLAY_MODE_RAVE :
2003-10-05 05:24:50 +00:00
if ( PREFSMAN -> m_bPercentageScoring )
2003-11-26 06:40:03 +00:00
m_pPrimaryScoreDisplay [ p ] = new ScoreDisplayPercentage ;
2003-10-05 05:24:50 +00:00
else
2003-11-26 06:40:03 +00:00
m_pPrimaryScoreDisplay [ p ] = new ScoreDisplayNormal ;
2002-08-28 22:42:40 +00:00
break ;
case PLAY_MODE_ONI :
case PLAY_MODE_ENDLESS :
2005-04-21 11:16:01 +00:00
if ( GAMESTATE -> m_SongOptions . m_LifeType == SongOptions :: LIFE_TIME )
m_pPrimaryScoreDisplay [ p ] = new ScoreDisplayLifeTime ;
else
m_pPrimaryScoreDisplay [ p ] = new ScoreDisplayOni ;
2003-04-07 05:14:27 +00:00
break ;
2002-08-28 22:42:40 +00:00
default :
ASSERT ( 0 );
}
2004-12-20 21:27:24 +00:00
m_pPrimaryScoreDisplay [ p ] -> Init ( GAMESTATE -> m_pPlayerState [ p ] );
2004-05-31 08:58:43 +00:00
m_pPrimaryScoreDisplay [ p ] -> SetName ( ssprintf ( "ScoreP%d" , p + 1 ) );
2003-11-26 06:40:03 +00:00
SET_XY ( * m_pPrimaryScoreDisplay [ p ] );
2003-12-22 05:20:13 +00:00
if ( GAMESTATE -> m_PlayMode != PLAY_MODE_RAVE || SHOW_SCORE_IN_RAVE ) /* XXX: ugly */
this -> AddChild ( m_pPrimaryScoreDisplay [ p ] );
2003-11-26 06:40:03 +00:00
//
// secondary score display
//
switch ( GAMESTATE -> m_PlayMode )
{
case PLAY_MODE_RAVE :
m_pSecondaryScoreDisplay [ p ] = new ScoreDisplayRave ;
break ;
}
if ( m_pSecondaryScoreDisplay [ p ] )
{
2004-12-20 21:27:24 +00:00
m_pSecondaryScoreDisplay [ p ] -> Init ( GAMESTATE -> m_pPlayerState [ p ] );
2004-05-31 08:58:43 +00:00
m_pSecondaryScoreDisplay [ p ] -> SetName ( ssprintf ( "SecondaryScoreP%d" , p + 1 ) );
2003-11-26 06:40:03 +00:00
SET_XY ( * m_pSecondaryScoreDisplay [ p ] );
this -> AddChild ( m_pSecondaryScoreDisplay [ p ] );
}
2003-07-08 19:56:56 +00:00
}
2003-11-29 11:16:36 +00:00
//
// Add stage / SongNumber
//
2005-05-07 09:58:23 +00:00
m_sprCourseSongNumber . SetName ( "CourseSongNumber" );
SET_XY ( m_sprCourseSongNumber );
2003-11-29 11:16:36 +00:00
2004-05-16 02:51:55 +00:00
FOREACH_EnabledPlayer ( p )
2003-11-29 11:16:36 +00:00
{
2004-07-25 06:29:50 +00:00
m_textCourseSongNumber [ p ]. LoadFromFont ( THEME -> GetPathF ( m_sName , "song num" ) );
2004-03-20 02:59:08 +00:00
m_textCourseSongNumber [ p ]. SetShadowLength ( 0 );
2004-05-31 08:58:43 +00:00
m_textCourseSongNumber [ p ]. SetName ( ssprintf ( "SongNumberP%d" , p + 1 ) );
2003-11-29 11:16:36 +00:00
SET_XY ( m_textCourseSongNumber [ p ] );
m_textCourseSongNumber [ p ]. SetText ( "" );
m_textCourseSongNumber [ p ]. SetDiffuse ( RageColor ( 0 , 0.5f , 1 , 1 ) ); // light blue
}
2004-05-16 02:51:55 +00:00
FOREACH_EnabledPlayer ( p )
2004-01-23 06:20:28 +00:00
{
2004-05-31 08:58:43 +00:00
m_textStepsDescription [ p ]. LoadFromFont ( THEME -> GetPathF ( m_sName , "StepsDescription" ) );
2004-01-23 06:20:28 +00:00
m_textStepsDescription [ p ]. SetName ( ssprintf ( "StepsDescriptionP%i" , p + 1 ) );
SET_XY ( m_textStepsDescription [ p ] );
this -> AddChild ( & m_textStepsDescription [ p ] );
}
2003-11-29 11:16:36 +00:00
switch ( GAMESTATE -> m_PlayMode )
{
2004-06-11 06:05:35 +00:00
case PLAY_MODE_REGULAR :
2003-11-29 11:16:36 +00:00
case PLAY_MODE_BATTLE :
case PLAY_MODE_RAVE :
break ;
case PLAY_MODE_NONSTOP :
case PLAY_MODE_ONI :
case PLAY_MODE_ENDLESS :
2005-05-07 09:58:23 +00:00
this -> AddChild ( & m_sprCourseSongNumber );
2003-12-18 23:19:02 +00:00
2004-05-31 08:58:43 +00:00
FOREACH_EnabledPlayer ( p )
this -> AddChild ( & m_textCourseSongNumber [ p ] );
2003-11-29 11:16:36 +00:00
break ;
default :
ASSERT ( 0 ); // invalid GameMode
}
2004-05-31 08:58:43 +00:00
m_sprStageFrame . Load ( THEME -> GetPathG ( m_sName , "stage frame" ) );
2004-02-15 00:48:24 +00:00
m_sprStageFrame -> SetName ( "StageFrame" );
2004-02-14 00:39:24 +00:00
SET_XY ( m_sprStageFrame );
2004-02-15 00:48:24 +00:00
this -> AddChild ( m_sprStageFrame );
2003-11-29 11:16:36 +00:00
//
// Player/Song options
//
2004-05-31 08:58:43 +00:00
FOREACH_EnabledPlayer ( p )
2003-07-08 19:56:56 +00:00
{
2004-05-31 08:58:43 +00:00
m_textPlayerOptions [ p ]. LoadFromFont ( THEME -> GetPathF ( m_sName , "player options" ) );
2004-03-20 02:59:08 +00:00
m_textPlayerOptions [ p ]. SetShadowLength ( 0 );
2004-05-31 08:58:43 +00:00
m_textPlayerOptions [ p ]. SetName ( ssprintf ( "PlayerOptionsP%d" , p + 1 ) );
2003-04-13 21:17:14 +00:00
SET_XY ( m_textPlayerOptions [ p ] );
2002-09-02 21:59:58 +00:00
this -> AddChild ( & m_textPlayerOptions [ p ] );
2002-05-20 08:59:37 +00:00
}
2004-05-31 08:58:43 +00:00
m_textSongOptions . LoadFromFont ( THEME -> GetPathF ( m_sName , "song options" ) );
2004-03-20 02:59:08 +00:00
m_textSongOptions . SetShadowLength ( 0 );
2004-05-31 08:58:43 +00:00
m_textSongOptions . SetName ( "SongOptions" );
2003-04-13 21:17:14 +00:00
SET_XY ( m_textSongOptions );
2002-08-13 23:26:46 +00:00
m_textSongOptions . SetText ( GAMESTATE -> m_SongOptions . GetString () );
2002-09-02 21:59:58 +00:00
this -> AddChild ( & m_textSongOptions );
2002-06-14 22:25:22 +00:00
2004-07-23 04:45:48 +00:00
FOREACH_EnabledPlayer ( pn )
2004-03-17 06:01:17 +00:00
{
2004-07-23 04:45:48 +00:00
m_ActiveAttackList [ pn ]. LoadFromFont ( THEME -> GetPathF ( m_sName , "ActiveAttackList" ) );
2004-12-20 21:27:24 +00:00
m_ActiveAttackList [ pn ]. Init ( GAMESTATE -> m_pPlayerState [ pn ] );
2004-07-23 04:45:48 +00:00
m_ActiveAttackList [ pn ]. SetName ( ssprintf ( "ActiveAttackListP%d" , pn + 1 ) );
SET_XY ( m_ActiveAttackList [ pn ] );
this -> AddChild ( & m_ActiveAttackList [ pn ] );
2004-03-17 06:01:17 +00:00
}
2002-06-14 22:25:22 +00:00
2003-11-29 11:16:36 +00:00
2004-05-31 06:04:30 +00:00
FOREACH_EnabledPlayer ( p )
2002-06-14 22:25:22 +00:00
{
2004-05-31 08:58:43 +00:00
m_DifficultyIcon [ p ]. Load ( THEME -> GetPathG ( m_sName , ssprintf ( "difficulty icons %dx%d" , NUM_PLAYERS , NUM_DIFFICULTIES )) );
2003-02-28 20:50:28 +00:00
/* Position it in LoadNextSong. */
2002-10-06 16:56:58 +00:00
this -> AddChild ( & m_DifficultyIcon [ p ] );
2004-05-31 06:04:30 +00:00
2005-02-23 20:40:46 +00:00
m_DifficultyMeter [ p ]. Load ( m_sName + ssprintf ( " DifficultyMeterP%d" , p + 1 ) );
2004-05-31 06:04:30 +00:00
/* Position it in LoadNextSong. */
this -> AddChild ( & m_DifficultyMeter [ p ] );
2002-06-14 22:25:22 +00:00
}
2004-12-01 20:42:15 +00:00
if ( PREFSMAN -> m_bShowLyrics )
this -> AddChild ( & m_LyricDisplay );
2002-08-23 20:18:29 +00:00
2003-01-11 08:55:21 +00:00
2003-11-17 03:34:13 +00:00
m_BPMDisplay . SetName ( "BPMDisplay" );
2003-11-14 18:31:28 +00:00
m_BPMDisplay . Load ();
2003-04-13 21:17:14 +00:00
SET_XY ( m_BPMDisplay );
2003-01-10 02:22:07 +00:00
this -> AddChild ( & m_BPMDisplay );
2004-12-18 08:15:19 +00:00
m_fLastBPS = 0 ;
2003-01-10 02:22:07 +00:00
2003-07-15 20:05:00 +00:00
ZERO ( m_pInventory );
2005-03-18 03:17:52 +00:00
FOREACH_PlayerNumber ( p )
2003-04-07 03:25:44 +00:00
{
2003-11-20 06:50:05 +00:00
// switch( GAMESTATE->m_PlayMode )
// {
// case PLAY_MODE_BATTLE:
// m_pInventory[p] = new Inventory;
2004-07-23 04:45:48 +00:00
// m_pInventory[p]->Load( p );
2003-11-20 06:50:05 +00:00
// this->AddChild( m_pInventory[p] );
// break;
// }
2003-04-07 03:25:44 +00:00
}
2003-03-09 00:55:49 +00:00
2005-01-03 23:20:11 +00:00
if ( ! GAMESTATE -> m_bDemonstrationOrJukebox ) // only load if we're going to use it
2003-03-09 00:55:49 +00:00
{
2004-05-31 08:58:43 +00:00
m_Ready . Load ( THEME -> GetPathB ( m_sName , "ready" ) );
2003-03-09 00:55:49 +00:00
this -> AddChild ( & m_Ready );
2004-05-31 08:58:43 +00:00
m_Go . Load ( THEME -> GetPathB ( m_sName , "go" ) );
2003-03-09 00:55:49 +00:00
this -> AddChild ( & m_Go );
2004-05-31 08:58:43 +00:00
m_Cleared . Load ( THEME -> GetPathB ( m_sName , "cleared" ) );
2004-05-02 03:01:27 +00:00
m_Cleared . SetDrawOrder ( DRAW_ORDER_TRANSITIONS - 1 ); // on top of everything else
2003-03-09 00:55:49 +00:00
this -> AddChild ( & m_Cleared );
2004-05-31 08:58:43 +00:00
m_Failed . Load ( THEME -> GetPathB ( m_sName , "failed" ) );
2004-05-02 03:01:27 +00:00
m_Failed . SetDrawOrder ( DRAW_ORDER_TRANSITIONS - 1 ); // on top of everything else
2003-03-09 00:55:49 +00:00
this -> AddChild ( & m_Failed );
2003-10-17 08:03:46 +00:00
if ( PREFSMAN -> m_bAllowExtraStage && GAMESTATE -> IsFinalStage () ) // only load if we're going to use it
2004-05-31 08:58:43 +00:00
m_Extra . Load ( THEME -> GetPathB ( m_sName , "extra1" ) );
2003-10-17 08:03:46 +00:00
if ( PREFSMAN -> m_bAllowExtraStage && GAMESTATE -> IsExtraStage () ) // only load if we're going to use it
2004-05-31 08:58:43 +00:00
m_Extra . Load ( THEME -> GetPathB ( m_sName , "extra2" ) );
2003-03-09 00:55:49 +00:00
this -> AddChild ( & m_Extra );
2003-04-14 22:12:54 +00:00
// only load if we're going to use it
switch ( GAMESTATE -> m_PlayMode )
{
2003-08-19 04:27:50 +00:00
case PLAY_MODE_BATTLE :
2003-04-21 02:41:10 +00:00
case PLAY_MODE_RAVE :
2004-05-16 08:48:54 +00:00
FOREACH_PlayerNumber ( p )
2003-04-14 22:12:54 +00:00
{
2004-05-31 08:58:43 +00:00
m_Win [ p ]. Load ( THEME -> GetPathB ( m_sName , ssprintf ( "win p%d" , p + 1 )) );
2003-04-14 22:12:54 +00:00
this -> AddChild ( & m_Win [ p ] );
}
2004-05-31 08:58:43 +00:00
m_Draw . Load ( THEME -> GetPathB ( m_sName , "draw" ) );
2003-04-21 02:41:10 +00:00
this -> AddChild ( & m_Draw );
2003-04-14 22:12:54 +00:00
break ;
}
2004-05-31 08:58:43 +00:00
m_textDebug . LoadFromFont ( THEME -> GetPathF ( "Common" , "normal" ) );
2003-04-13 21:17:14 +00:00
m_textDebug . SetName ( "Debug" );
SET_XY ( m_textDebug );
2005-03-12 07:27:48 +00:00
m_textDebug . SetDrawOrder ( DRAW_ORDER_TRANSITIONS - 1 ); // just under transitions, over the foreground
2003-03-16 23:17:48 +00:00
this -> AddChild ( & m_textDebug );
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
{
2004-05-31 08:58:43 +00:00
m_textSurviveTime . LoadFromFont ( THEME -> GetPathF ( m_sName , "survive time" ) );
2004-03-20 02:59:08 +00:00
m_textSurviveTime . SetShadowLength ( 0 );
2003-04-13 21:17:14 +00:00
m_textSurviveTime . SetName ( "SurviveTime" );
SET_XY ( m_textSurviveTime );
2004-05-02 03:01:27 +00:00
m_textSurviveTime . SetDrawOrder ( DRAW_ORDER_TRANSITIONS - 1 );
2003-03-09 00:55:49 +00:00
m_textSurviveTime . SetDiffuse ( RageColor ( 1 , 1 , 1 , 0 ) );
this -> AddChild ( & m_textSurviveTime );
}
}
2005-03-18 05:06:34 +00:00
m_SongBackground . Init ();
2003-03-09 00:55:49 +00:00
2005-01-03 23:20:11 +00:00
if ( ! GAMESTATE -> m_bDemonstrationOrJukebox ) // only load if we're going to use it
2003-01-19 04:44:22 +00:00
{
2004-05-31 08:58:43 +00:00
m_soundAssistTick . Load ( THEME -> GetPathS ( m_sName , "assist tick" ), true );
2003-05-13 13:35:32 +00:00
2003-07-08 19:56:56 +00:00
switch ( GAMESTATE -> m_PlayMode )
2003-05-13 13:35:32 +00:00
{
2003-08-19 04:27:50 +00:00
case PLAY_MODE_BATTLE :
2004-05-31 08:58:43 +00:00
m_soundBattleTrickLevel1 . Load ( THEME -> GetPathS ( m_sName , "battle trick level1" ), true );
m_soundBattleTrickLevel2 . Load ( THEME -> GetPathS ( m_sName , "battle trick level2" ), true );
m_soundBattleTrickLevel3 . Load ( THEME -> GetPathS ( m_sName , "battle trick level3" ), true );
2003-07-08 19:56:56 +00:00
break ;
2003-05-13 13:35:32 +00:00
}
2003-03-09 00:55:49 +00:00
}
2005-03-18 04:58:15 +00:00
FOREACH_EnabledPlayer ( pn )
2005-03-18 03:17:52 +00:00
m_Player [ pn ]. Init (
PLAYER_TYPE ,
GAMESTATE -> m_pPlayerState [ pn ],
& STATSMAN -> m_CurStageStats . m_player [ pn ],
m_pLifeMeter [ pn ],
m_pCombinedLifeMeter ,
m_pPrimaryScoreDisplay [ pn ],
m_pSecondaryScoreDisplay [ pn ],
m_pInventory [ pn ],
m_pPrimaryScoreKeeper [ pn ],
m_pSecondaryScoreKeeper [ pn ] );
2005-03-18 07:53:16 +00:00
//
// fill in m_apSongsQueue, m_vpStepsQueue, m_asModifiersQueue
//
InitSongQueues ();
FOREACH_EnabledPlayer ( pn )
ASSERT ( ! m_vpStepsQueue [ pn ]. empty () );
FOREACH_EnabledPlayer ( pn )
{
if ( m_pPrimaryScoreKeeper [ pn ] )
m_pPrimaryScoreKeeper [ pn ] -> Load ( m_apSongsQueue , m_vpStepsQueue [ pn ], m_asModifiersQueue [ pn ] );
if ( m_pSecondaryScoreKeeper [ pn ] )
m_pSecondaryScoreKeeper [ pn ] -> Load ( m_apSongsQueue , m_vpStepsQueue [ pn ], m_asModifiersQueue [ pn ] );
}
2005-03-18 02:57:03 +00:00
/* LoadNextSong first, since that positions some elements which need to be
* positioned before we TweenOnScreen. */
LoadNextSong ();
TweenOnScreen ();
this -> SortByDrawOrder ();
2003-09-06 03:25:45 +00:00
m_GiveUpTimer . SetZero ();
2003-03-12 01:26:44 +00:00
// 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
}
2005-01-03 23:29:40 +00:00
//
// fill in m_apSongsQueue, m_vpStepsQueue, m_asModifiersQueue
//
void ScreenGameplay :: InitSongQueues ()
{
LOG -> Trace ( "InitSongQueues" );
if ( GAMESTATE -> IsCourseMode () )
{
Course * pCourse = GAMESTATE -> m_pCurCourse ;
ASSERT ( pCourse );
m_apSongsQueue . clear ();
PlayerNumber pnMaster = GAMESTATE -> m_MasterPlayerNumber ;
Trail * pTrail = GAMESTATE -> m_pCurTrail [ pnMaster ];
2005-01-31 04:41:25 +00:00
ASSERT ( pTrail );
2005-01-03 23:29:40 +00:00
FOREACH_CONST ( TrailEntry , pTrail -> m_vEntries , e )
2005-01-31 04:41:25 +00:00
{
ASSERT ( e -> pSong );
2005-01-03 23:29:40 +00:00
m_apSongsQueue . push_back ( e -> pSong );
2005-01-31 04:41:25 +00:00
}
2005-01-03 23:29:40 +00:00
2005-04-20 06:13:06 +00:00
FOREACH_EnabledPlayer ( p )
2005-01-03 23:29:40 +00:00
{
Trail * pTrail = GAMESTATE -> m_pCurTrail [ p ];
ASSERT ( pTrail );
m_vpStepsQueue [ p ]. clear ();
m_asModifiersQueue [ p ]. clear ();
FOREACH_CONST ( TrailEntry , pTrail -> m_vEntries , e )
{
2005-01-31 04:41:25 +00:00
ASSERT ( e -> pSteps );
2005-01-03 23:29:40 +00:00
m_vpStepsQueue [ p ]. push_back ( e -> pSteps );
AttackArray a ;
e -> GetAttackArray ( a );
m_asModifiersQueue [ p ]. push_back ( a );
}
}
}
else
{
m_apSongsQueue . push_back ( GAMESTATE -> m_pCurSong );
2005-04-20 06:13:06 +00:00
FOREACH_PlayerNumber ( p )
2005-01-03 23:29:40 +00:00
{
2005-04-26 07:02:10 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ p ];
m_vpStepsQueue [ p ]. push_back ( pSteps );
AttackArray aa ;
if ( pSteps -> GetDifficulty () == DIFFICULTY_BEGINNER && ( bool ) USE_FORCED_MODIFIERS_IN_BEGINNER )
2005-04-26 20:46:06 +00:00
aa . push_back ( Attack ( ATTACK_LEVEL_1 , 0 , 0 , FORCED_MODIFIERS_IN_BEGINNER , false , true , false ) ); // don't show in AttackList
2005-04-26 07:02:10 +00:00
m_asModifiersQueue [ p ]. push_back ( aa );
2005-01-03 23:29:40 +00:00
}
}
2005-04-20 06:13:06 +00:00
// Fill StageStats
STATSMAN -> m_CurStageStats . vpPossibleSongs = m_apSongsQueue ;
FOREACH_PlayerNumber ( p )
STATSMAN -> m_CurStageStats . m_player [ p ]. vpPossibleSteps = m_vpStepsQueue [ p ];
2005-01-03 23:29:40 +00:00
}
2002-05-20 08:59:37 +00:00
ScreenGameplay ::~ ScreenGameplay ()
{
2004-04-25 23:17:08 +00:00
if ( this -> IsFirstUpdate () )
{
/* We never received any updates. That means we were deleted without being
* used, and never actually played. (This can happen when backing out of
* ScreenStage.) Cancel the stage. */
GAMESTATE -> CancelStage ();
}
2002-07-31 19:40:40 +00:00
LOG -> Trace ( "ScreenGameplay::~ScreenGameplay()" );
2002-07-23 01:41:40 +00:00
2005-02-06 10:10:38 +00:00
if ( ! GAMESTATE -> m_bDemonstrationOrJukebox )
MEMCARDMAN -> UnPauseMountingThread ();
2005-02-06 08:48:55 +00:00
2004-05-16 08:48:54 +00:00
FOREACH_PlayerNumber ( p )
2002-07-23 01:41:40 +00:00
{
2002-08-28 22:42:40 +00:00
SAFE_DELETE ( m_pLifeMeter [ p ] );
2003-11-26 06:40:03 +00:00
SAFE_DELETE ( m_pPrimaryScoreDisplay [ p ] );
SAFE_DELETE ( m_pSecondaryScoreDisplay [ p ] );
SAFE_DELETE ( m_pSecondaryScoreDisplay [ p ] );
2003-06-30 18:08:27 +00:00
SAFE_DELETE ( m_pPrimaryScoreKeeper [ p ] );
SAFE_DELETE ( m_pSecondaryScoreKeeper [ p ] );
2003-07-08 19:56:56 +00:00
SAFE_DELETE ( m_pInventory [ p ] );
2002-07-23 01:41:40 +00:00
}
2003-06-30 18:08:27 +00:00
SAFE_DELETE ( m_pCombinedLifeMeter );
2004-11-05 06:36:49 +00:00
if ( m_pSoundMusic )
m_pSoundMusic -> StopPlaying ();
2003-05-13 13:35:32 +00:00
2004-01-12 09:36:01 +00:00
m_soundAssistTick . StopPlaying (); /* Stop any queued assist ticks. */
2004-12-03 01:29:23 +00:00
NSMAN -> ReportSongOver ();
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 ;
2005-04-06 06:12:23 +00:00
return GAMESTATE -> GetCourseSongIndex () >= ( int ) m_apSongsQueue . size () - 1 ; // GetCourseSongIndex() is 0-based
2002-07-28 20:28:37 +00:00
}
2005-04-11 07:59:27 +00:00
void ScreenGameplay :: SetupSong ( int iSongIndex )
2003-12-23 02:18:27 +00:00
{
2005-04-11 07:59:27 +00:00
FOREACH_EnabledPlayer ( p )
2004-10-24 10:45:30 +00:00
{
2005-04-11 07:59:27 +00:00
/* This is the first beat that can be changed without it being visible. Until
* we draw for the first time, any beat can be changed. */
GAMESTATE -> m_pPlayerState [ p ] -> m_fLastDrawnBeat = - 100 ;
GAMESTATE -> m_pCurSteps [ p ]. Set ( m_vpStepsQueue [ p ][ iSongIndex ] );
2004-10-24 10:45:30 +00:00
2005-04-11 07:59:27 +00:00
/* Load new NoteData into Player. Do this before
* RebuildPlayerOptionsFromActiveAttacks or else transform mods will get
* propogated to GAMESTATE->m_PlayerOptions too early and be double-applied
* to the NoteData:
* once in Player::Load, then again in Player::ApplyActiveAttacks. This
* is very bad for transforms like AddMines.
*/
NoteData originalNoteData ;
GAMESTATE -> m_pCurSteps [ p ] -> GetNoteData ( originalNoteData );
2004-03-21 18:27:25 +00:00
2005-04-11 07:59:27 +00:00
const Style * pStyle = GAMESTATE -> GetCurrentStyle ();
NoteData ndTransformed ;
pStyle -> GetTransformedNoteDataForStyle ( p , originalNoteData , ndTransformed );
// load player
{
NoteData nd = ndTransformed ;
NoteDataUtil :: RemoveAllTapsOfType ( nd , TapNote :: autoKeysound );
m_Player [ p ]. Load ( nd );
}
// load auto keysounds
{
NoteData nd = ndTransformed ;
NoteDataUtil :: RemoveAllTapsExceptForType ( nd , TapNote :: autoKeysound );
m_AutoKeysounds . Load ( p , nd );
}
// Put course options into effect. Do this after Player::Load so
// that mods aren't double-applied.
GAMESTATE -> m_pPlayerState [ p ] -> m_ModsToApply . clear ();
for ( unsigned i = 0 ; i < m_asModifiersQueue [ p ][ iSongIndex ]. size (); ++ i )
{
Attack a = m_asModifiersQueue [ p ][ iSongIndex ][ i ];
if ( a . fStartSecond == 0 )
a . fStartSecond = - 1 ; // now
GAMESTATE -> LaunchAttack ( p , a );
2005-05-20 08:57:59 +00:00
GAMESTATE -> m_SongOptions . FromString ( a . sModifiers );
2005-04-11 07:59:27 +00:00
}
// UGLY: Force updating the BeatToNoteSkin mapping and cache NoteSkins now, or else
// we'll do it on the first update and skip.
m_Player [ p ]. ApplyWaitingTransforms ();
/* Update attack bOn flags. */
GAMESTATE -> Update ( 0 );
GAMESTATE -> RebuildPlayerOptionsFromActiveAttacks ( p );
/* Hack: Course modifiers that are set to start immediately shouldn't tween on. */
GAMESTATE -> m_pPlayerState [ p ] -> m_CurrentPlayerOptions = GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerOptions ;
2003-12-23 02:18:27 +00:00
}
}
2005-05-06 10:48:32 +00:00
void ScreenGameplay :: LoadCourseSongNumber ( int iSongNumber )
2004-02-14 00:39:24 +00:00
{
if ( ! GAMESTATE -> IsCourseMode () )
return ;
2005-05-07 09:58:23 +00:00
const CString path = THEME -> GetPathG ( m_sName , ssprintf ( "course song %i" , iSongNumber + 1 ), true );
if ( path != "" )
m_sprCourseSongNumber . Load ( path );
else
m_sprCourseSongNumber . UnloadTexture ();
SCREENMAN -> ZeroNextUpdate ();
2004-02-14 00:39:24 +00:00
}
2003-01-25 07:40:47 +00:00
void ScreenGameplay :: LoadNextSong ()
2002-07-28 20:28:37 +00:00
{
GAMESTATE -> ResetMusicStatistics ();
2004-04-18 18:42:42 +00:00
2004-06-06 21:30:47 +00:00
FOREACH_EnabledPlayer ( p )
2004-04-18 18:42:42 +00:00
{
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . m_player [ p ]. iSongsPlayed ++ ;
m_textCourseSongNumber [ p ]. SetText ( ssprintf ( "%d" , STATSMAN -> m_CurStageStats . m_player [ p ]. iSongsPlayed ) );
2004-04-18 18:42:42 +00:00
}
2003-02-24 02:45:01 +00:00
2005-02-25 04:18:28 +00:00
LoadCourseSongNumber ( GAMESTATE -> GetCourseSongIndex () );
2003-12-18 23:19:02 +00:00
2003-03-26 23:08:05 +00:00
int iPlaySongIndex = GAMESTATE -> GetCourseSongIndex ();
iPlaySongIndex %= m_apSongsQueue . size ();
2005-02-24 12:27:30 +00:00
GAMESTATE -> m_pCurSong . Set ( m_apSongsQueue [ iPlaySongIndex ] );
2005-04-20 06:13:06 +00:00
STATSMAN -> m_CurStageStats . vpPlayedSongs . push_back ( GAMESTATE -> m_pCurSong );
2003-12-15 06:24:59 +00:00
2004-07-30 07:18:21 +00:00
// No need to do this here. We do it in SongFinished().
//GAMESTATE->RemoveAllActiveAttacks();
2003-03-26 23:08:05 +00:00
// Restore the player's originally selected options.
GAMESTATE -> RestoreSelectedOptions ();
2002-06-24 22:04:31 +00:00
2004-08-25 08:56:58 +00:00
/* If we're in battery mode, force FailImmediate. We assume in PlayerMinus::Step that
* failed players can't step. */
if ( GAMESTATE -> m_SongOptions . m_LifeType == SongOptions :: LIFE_BATTERY )
GAMESTATE -> m_SongOptions . m_FailType = SongOptions :: FAIL_IMMEDIATE ;
2003-02-17 19:52:16 +00:00
m_textSongOptions . SetText ( GAMESTATE -> m_SongOptions . GetString () );
2002-06-24 22:04:31 +00:00
2005-04-11 07:59:27 +00:00
SetupSong ( iPlaySongIndex );
2004-06-06 21:30:47 +00:00
FOREACH_EnabledPlayer ( p )
2002-06-14 22:25:22 +00:00
{
2004-06-06 21:30:47 +00:00
Song * pSong = GAMESTATE -> m_pCurSong ;
Steps * pSteps = GAMESTATE -> m_pCurSteps [ p ];
2005-04-20 06:13:06 +00:00
STATSMAN -> m_CurStageStats . m_player [ p ]. vpPlayedSteps . push_back ( pSteps );
2004-06-06 21:30:47 +00:00
ASSERT ( GAMESTATE -> m_pCurSteps [ p ] );
m_textStepsDescription [ p ]. SetText ( GAMESTATE -> m_pCurSteps [ p ] -> GetDescription () );
/* Increment the play count even if the player fails. (It's still popular,
* even if the people playing it aren't good at it.) */
2005-01-03 23:20:11 +00:00
if ( ! GAMESTATE -> m_bDemonstrationOrJukebox )
2004-06-06 21:30:47 +00:00
PROFILEMAN -> IncrementStepsPlayCount ( pSong , pSteps , p );
2004-12-20 21:27:24 +00:00
m_textPlayerOptions [ p ]. SetText ( GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerOptions . GetString () );
2004-08-29 05:43:07 +00:00
m_ActiveAttackList [ p ]. Refresh ();
2004-06-06 21:30:47 +00:00
// reset oni game over graphic
2005-05-09 04:07:07 +00:00
SET_XY_AND_ON_COMMAND ( m_sprOniGameOver [ p ] );
2004-06-06 21:30:47 +00:00
2005-02-16 03:25:45 +00:00
if ( GAMESTATE -> m_SongOptions . m_LifeType == SongOptions :: LIFE_BATTERY && STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed ) // already failed
2004-06-08 07:16:28 +00:00
ShowOniGameOver ( p );
2004-06-06 21:30:47 +00:00
2005-04-05 08:30:57 +00:00
if ( GAMESTATE -> m_SongOptions . m_LifeType == SongOptions :: LIFE_BAR &&
GAMESTATE -> m_PlayMode == PLAY_MODE_REGULAR &&
! GAMESTATE -> IsEventMode () &&
! GAMESTATE -> m_bDemonstrationOrJukebox )
2003-07-31 15:07:48 +00:00
{
2004-06-06 21:30:47 +00:00
m_pLifeMeter [ p ] -> UpdateNonstopLifebar (
GAMESTATE -> GetStageIndex (),
2005-04-28 08:27:40 +00:00
PREFSMAN -> m_iSongsPerPlay ,
2004-06-06 21:30:47 +00:00
PREFSMAN -> m_iProgressiveStageLifebar );
2003-04-21 02:41:10 +00:00
}
2004-06-06 21:30:47 +00:00
if ( GAMESTATE -> m_SongOptions . m_LifeType == SongOptions :: LIFE_BAR && GAMESTATE -> m_PlayMode == PLAY_MODE_NONSTOP )
{
m_pLifeMeter [ p ] -> UpdateNonstopLifebar (
GAMESTATE -> GetCourseSongIndex (),
GAMESTATE -> m_pCurCourse -> GetEstimatedNumStages (),
PREFSMAN -> m_iProgressiveNonstopLifebar );
}
m_DifficultyIcon [ p ]. SetFromSteps ( p , GAMESTATE -> m_pCurSteps [ p ] );
m_DifficultyMeter [ p ]. SetName ( m_sName + ssprintf ( " DifficultyMeterP%d" , p + 1 ) );
m_DifficultyMeter [ p ]. SetFromSteps ( GAMESTATE -> m_pCurSteps [ p ] );
/* The actual note data for scoring is the base class of Player. This includes
* transforms, like Wide. Otherwise, the scoring will operate on the wrong data. */
2004-10-23 17:43:49 +00:00
m_pPrimaryScoreKeeper [ p ] -> OnNextSong ( GAMESTATE -> GetCourseSongIndex (), GAMESTATE -> m_pCurSteps [ p ], & m_Player [ p ]. m_NoteData );
2004-06-06 21:30:47 +00:00
if ( m_pSecondaryScoreKeeper [ p ] )
2004-10-23 17:43:49 +00:00
m_pSecondaryScoreKeeper [ p ] -> OnNextSong ( GAMESTATE -> GetCourseSongIndex (), GAMESTATE -> m_pCurSteps [ p ], & m_Player [ p ]. m_NoteData );
2004-06-06 21:30:47 +00:00
2005-01-03 23:20:11 +00:00
if ( GAMESTATE -> m_bDemonstrationOrJukebox )
2004-06-06 21:30:47 +00:00
{
2004-12-20 21:27:24 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerController = PC_CPU ;
GAMESTATE -> m_pPlayerState [ p ] -> m_iCpuSkill = 5 ;
2004-06-06 21:30:47 +00:00
}
else if ( GAMESTATE -> IsCpuPlayer ( p ) )
{
2004-12-20 21:27:24 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerController = PC_CPU ;
2004-06-06 21:30:47 +00:00
int iMeter = GAMESTATE -> m_pCurSteps [ p ] -> GetMeter ();
int iNewSkill = SCALE ( iMeter , MIN_METER , MAX_METER , 0 , NUM_SKILL_LEVELS - 1 );
/* Watch out: songs aren't actually bound by MAX_METER. */
iNewSkill = clamp ( iNewSkill , 0 , NUM_SKILL_LEVELS - 1 );
2004-12-20 21:27:24 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_iCpuSkill = iNewSkill ;
2004-06-06 21:30:47 +00:00
}
else
2004-12-20 21:27:24 +00:00
{
2005-05-18 07:15:56 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerController = PREFSMAN -> m_AutoPlay ;
2004-12-20 21:27:24 +00:00
}
2005-04-24 11:03:02 +00:00
}
2004-12-20 21:27:24 +00:00
const bool bReverse [ NUM_PLAYERS ] =
{
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . m_fScrolls [ PlayerOptions :: SCROLL_REVERSE ] == 1 ,
GAMESTATE -> m_pPlayerState [ PLAYER_2 ] -> m_PlayerOptions . m_fScrolls [ PlayerOptions :: SCROLL_REVERSE ] == 1
2003-02-28 20:50:28 +00:00
};
2004-12-01 20:42:15 +00:00
FOREACH_EnabledPlayer ( p )
2003-02-28 20:50:28 +00:00
{
2004-12-01 20:42:15 +00:00
m_DifficultyIcon [ p ]. SetName ( ssprintf ( "DifficultyP%d%s" , p + 1 , bReverse [ p ] ? "Reverse" : "" ) );
SET_XY ( m_DifficultyIcon [ p ] );
2004-05-31 06:04:30 +00:00
2004-12-01 20:42:15 +00:00
m_DifficultyMeter [ p ]. SetName ( ssprintf ( "DifficultyMeterP%d%s" , p + 1 , bReverse [ p ] ? "Reverse" : "" ) );
SET_XY ( m_DifficultyMeter [ p ] );
2003-02-28 20:50:28 +00:00
}
2003-06-04 20:40:32 +00:00
const bool bBothReverse = bReverse [ PLAYER_1 ] && bReverse [ PLAYER_2 ];
const bool bOneReverse = ! bBothReverse && ( bReverse [ PLAYER_1 ] || bReverse [ PLAYER_2 ]);
/* 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 . SetName ( ssprintf ( "Lyrics%s" , bBothReverse ? "Reverse" : bOneReverse ? "OneReverse" : "" ) );
SET_XY ( m_LyricDisplay );
2004-05-31 08:58:43 +00:00
m_SongFinished . Load ( THEME -> GetPathB ( m_sName , "song finished" ) );
2004-03-06 10:07:17 +00:00
2003-03-19 19:58:22 +00:00
// Load lyrics
// XXX: don't load this here
2003-03-20 18:51:14 +00:00
LyricsLoader LL ;
if ( GAMESTATE -> m_pCurSong -> HasLyrics () )
LL . LoadFromLRCFile ( GAMESTATE -> m_pCurSong -> GetLyricsPath (), * GAMESTATE -> m_pCurSong );
2003-04-13 00:44:50 +00:00
/* Set up song-specific graphics. */
2003-08-20 09:19:46 +00:00
2003-08-27 13:36:22 +00:00
// Check to see if any players are in beginner mode.
// Note: steps can be different if turn modifiers are used.
2003-12-02 19:11:51 +00:00
if ( PREFSMAN -> m_bShowBeginnerHelper )
2003-08-24 23:18:20 +00:00
{
2004-04-18 18:42:42 +00:00
FOREACH_HumanPlayer ( p )
{
2004-05-24 06:12:17 +00:00
if ( GAMESTATE -> m_pCurSteps [ p ] -> GetDifficulty () == DIFFICULTY_BEGINNER )
2004-10-23 17:43:49 +00:00
m_BeginnerHelper . AddPlayer ( p , & m_Player [ p ]. m_NoteData );
2004-04-18 18:42:42 +00:00
}
2003-12-02 19:11:51 +00:00
}
2003-08-27 13:36:22 +00:00
2005-03-11 02:12:21 +00:00
m_SongBackground . Unload ();
2005-03-11 02:06:39 +00:00
if ( ! PREFSMAN -> m_bShowBeginnerHelper || ! m_BeginnerHelper . Initialize ( 2 ) )
2003-12-02 19:11:51 +00:00
{
2005-03-11 02:06:39 +00:00
m_BeginnerHelper . SetHidden ( true );
/* BeginnerHelper disabled, or failed to load. */
2005-03-11 02:12:21 +00:00
m_SongBackground . LoadFromSong ( GAMESTATE -> m_pCurSong );
2005-03-11 02:06:39 +00:00
2005-01-03 23:20:11 +00:00
if ( ! GAMESTATE -> m_bDemonstrationOrJukebox )
2004-04-19 20:28:10 +00:00
{
/* This will fade from a preset brightness to the actual brightness (based
* on prefs and "cover"). The preset brightness may be 0 (to fade from
* black), or it might be 1, if the stage screen has the song BG and we're
* coming from it (like Pump). This used to be done in SM_PlayReady, but
* that means it's impossible to snap to the new brightness immediately. */
2005-03-11 02:12:21 +00:00
m_SongBackground . SetBrightness ( INITIAL_BACKGROUND_BRIGHTNESS );
m_SongBackground . FadeToActualBrightness ();
2004-04-19 20:28:10 +00:00
}
2003-08-20 09:19:46 +00:00
}
2005-03-11 02:06:39 +00:00
else
2005-04-21 04:27:13 +00:00
{
2005-03-11 02:06:39 +00:00
m_BeginnerHelper . SetHidden ( false );
2005-04-21 04:27:13 +00:00
}
FOREACH_EnabledPlayer ( p )
{
if ( ! STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed )
{
// give a little life back between stages
if ( m_pLifeMeter [ p ] )
m_pLifeMeter [ p ] -> OnLoadSong ();
2005-04-21 11:16:01 +00:00
if ( m_pPrimaryScoreDisplay [ p ] )
m_pPrimaryScoreDisplay [ p ] -> OnLoadSong ();
if ( m_pSecondaryScoreDisplay [ p ] )
m_pSecondaryScoreDisplay [ p ] -> OnLoadSong ();
2005-04-21 04:27:13 +00:00
}
}
2005-04-21 11:16:01 +00:00
if ( m_pCombinedLifeMeter )
m_pCombinedLifeMeter -> OnLoadSong ();
2005-04-21 04:27:13 +00:00
2003-08-20 09:19:46 +00:00
2005-03-11 02:52:40 +00:00
m_SongForeground . LoadFromSong ( GAMESTATE -> m_pCurSong );
2003-04-13 00:44:50 +00:00
2004-02-16 05:29:33 +00:00
m_fTimeSinceLastDancingComment = 0 ;
2003-08-07 07:34:42 +00:00
2005-03-11 02:12:21 +00:00
/* m_soundMusic and m_SongBackground take a very long time to load,
2005-03-19 00:03:53 +00:00
* so cap fDelta at 0 so m_NextSong will show up on screen.
2003-08-01 11:41:13 +00:00
* -Chris */
2003-04-13 00:44:50 +00:00
m_bZeroDeltaOnNextUpdate = true ;
2005-05-07 09:58:23 +00:00
SCREENMAN -> ZeroNextUpdate ();
2004-03-30 07:44:29 +00:00
//
2004-04-22 05:25:58 +00:00
// Load cabinet lights data
2004-03-30 07:44:29 +00:00
//
2005-05-04 06:48:34 +00:00
LoadLights ();
2005-03-18 07:08:05 +00:00
/* Load the music last, since it may start streaming and we don't want the music
* to compete with other loading. */
m_AutoKeysounds . FinishLoading ();
m_pSoundMusic = m_AutoKeysounds . GetSound ();
2003-01-25 07:40:47 +00:00
}
2005-05-04 06:48:34 +00:00
void ScreenGameplay :: LoadLights ()
{
if ( ! LIGHTSMAN -> IsEnabled () )
return ;
2005-06-02 21:47:27 +00:00
//
// First, check if the song has explicit lights
//
2005-05-04 06:48:34 +00:00
m_CabinetLightsNoteData . Init ();
ASSERT ( GAMESTATE -> m_pCurSong );
2005-05-04 08:20:12 +00:00
const Steps * pSteps = GAMESTATE -> m_pCurSong -> GetClosestNotes ( STEPS_TYPE_LIGHTS_CABINET , DIFFICULTY_MEDIUM );
2005-05-04 06:48:34 +00:00
if ( pSteps != NULL )
{
pSteps -> GetNoteData ( m_CabinetLightsNoteData );
2005-05-04 06:53:25 +00:00
return ;
2005-05-04 06:48:34 +00:00
}
2005-05-04 06:53:25 +00:00
2005-06-02 21:47:27 +00:00
//
// No explicit lights. Create autogen lights.
//
2005-05-04 08:20:12 +00:00
CString sDifficulty = PREFSMAN -> m_sLightsStepsDifficulty ;
vector < CString > asDifficulties ;
split ( sDifficulty , "," , asDifficulties );
Difficulty d1 = DIFFICULTY_INVALID ;
if ( asDifficulties . size () > 0 )
d1 = StringToDifficulty ( asDifficulties [ 0 ] );
pSteps = GAMESTATE -> m_pCurSong -> GetClosestNotes ( GAMESTATE -> GetCurrentStyle () -> m_StepsType , d1 );
// If we can't find anything at all, stop.
if ( pSteps == NULL )
return ;
NoteData TapNoteData1 ;
pSteps -> GetNoteData ( TapNoteData1 );
if ( asDifficulties . size () > 1 )
{
Difficulty d2 = StringToDifficulty ( asDifficulties [ 1 ] );
const Steps * pSteps2 = GAMESTATE -> m_pCurSong -> GetClosestNotes ( GAMESTATE -> GetCurrentStyle () -> m_StepsType , d2 );
if ( pSteps != NULL && pSteps2 != NULL && pSteps != pSteps2 )
{
NoteData TapNoteData2 ;
pSteps2 -> GetNoteData ( TapNoteData2 );
NoteDataUtil :: LoadTransformedLightsFromTwo ( TapNoteData1 , TapNoteData2 , m_CabinetLightsNoteData );
return ;
}
/* fall through */
}
NoteDataUtil :: LoadTransformedLights ( TapNoteData1 , m_CabinetLightsNoteData , GameManager :: StepsTypeToNumTracks ( STEPS_TYPE_LIGHTS_CABINET ) );
2005-05-04 06:48:34 +00:00
}
2003-01-25 08:32:57 +00:00
float ScreenGameplay :: StartPlayingSong ( float MinTimeToNotes , float MinTimeToMusic )
2003-01-25 07:40:47 +00:00
{
2003-01-25 08:32:57 +00:00
ASSERT ( MinTimeToNotes >= 0 );
ASSERT ( MinTimeToMusic >= 0 );
2003-01-25 07:40:47 +00:00
/* XXX: We want the first beat *in use*, so we don't delay needlessly. */
2002-09-10 08:21:55 +00:00
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 );
2004-02-28 02:09:46 +00:00
RageSoundParams p ;
p . AccurateSync = true ;
p . SetPlaybackRate ( GAMESTATE -> m_SongOptions . m_fMusicRate );
p . StopMode = RageSoundParams :: M_CONTINUE ;
p . m_StartSecond = fStartSecond ;
2005-06-15 02:01:09 +00:00
// Silence music if not playing attract sounds in demonstration.
2005-06-16 18:47:58 +00:00
if ( GAMESTATE -> m_bDemonstrationOrJukebox && ! GAMESTATE -> IsTimeToPlayAttractSounds () )
p . m_Volume = 0 ;
2005-06-15 02:01:09 +00:00
2005-02-24 21:44:08 +00:00
ASSERT ( ! m_pSoundMusic -> IsPlaying () );
2004-10-25 03:47:22 +00:00
m_pSoundMusic -> Play ( & p );
2005-04-16 03:46:14 +00:00
if ( m_bPaused )
m_pSoundMusic -> Pause ( true );
2003-01-25 07:40:47 +00:00
2004-01-29 05:20:27 +00:00
/* Make sure GAMESTATE->m_fMusicSeconds is set up. */
GAMESTATE -> m_fMusicSeconds = - 5000 ;
2004-05-21 00:58:48 +00:00
UpdateSongPosition ( 0 );
2004-01-29 05:20:27 +00:00
ASSERT ( GAMESTATE -> m_fMusicSeconds > - 4000 ); /* make sure the "fake timer" code doesn't trigger */
2003-01-25 07:40:47 +00:00
/* 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
}
2005-03-11 02:52:40 +00:00
2005-04-21 02:07:02 +00:00
void ScreenGameplay :: PauseGame ( bool bPause , GameController gc )
2005-03-11 02:52:40 +00:00
{
if ( m_bPaused == bPause )
{
LOG -> Trace ( "ScreenGameplay::PauseGame(%i) received, but already in that state; ignored" , bPause );
return ;
}
2005-03-11 04:12:48 +00:00
/* Don't pause if we're already tweening out. */
if ( bPause && m_DancingState == STATE_OUTRO )
return ;
2005-04-01 02:34:22 +00:00
AbortGiveUp ( false );
2005-03-11 04:12:48 +00:00
2005-03-11 02:52:40 +00:00
m_bPaused = bPause ;
2005-04-21 02:07:02 +00:00
m_PauseController = gc ;
2005-03-11 02:52:40 +00:00
m_pSoundMusic -> Pause ( bPause );
2005-03-11 03:33:41 +00:00
if ( bPause )
this -> PlayCommand ( "Pause" );
else
this -> PlayCommand ( "Unpause" );
2005-03-11 03:54:40 +00:00
FOREACH_EnabledPlayer ( p )
m_Player [ p ]. SetPaused ( m_bPaused );
2005-03-11 02:52:40 +00:00
}
2002-10-12 00:32:47 +00:00
// play assist ticks
2004-01-12 09:36:01 +00:00
void ScreenGameplay :: PlayTicks ()
2002-10-12 00:32:47 +00:00
{
2004-01-12 09:36:01 +00:00
if ( ! GAMESTATE -> m_SongOptions . m_bAssistTick )
return ;
2002-10-12 00:32:47 +00:00
2004-01-12 09:36:01 +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. This is just to make sure that we request the sound early enough for it to
* come out on time; the actual precise timing is handled by SetStartTime. */
float fPositionSeconds = GAMESTATE -> m_fMusicSeconds ;
fPositionSeconds += SOUND -> GetPlayLatency () + ( float ) TICK_EARLY_SECONDS + 0.250f ;
const float fSongBeat = GAMESTATE -> m_pCurSong -> GetBeatFromElapsedTime ( fPositionSeconds );
const int iSongRow = max ( 0 , BeatToNoteRowNotRounded ( fSongBeat ) );
2004-04-04 04:12:26 +00:00
static int iRowLastCrossed = - 1 ;
if ( iSongRow < iRowLastCrossed )
iRowLastCrossed = - 1 ;
2002-10-12 00:32:47 +00:00
2004-01-12 09:36:01 +00:00
int iTickRow = - 1 ;
2004-12-03 23:50:20 +00:00
// for each index we crossed since the last update:
2005-01-31 19:12:30 +00:00
FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE ( m_Player [ GAMESTATE -> m_MasterPlayerNumber ]. m_NoteData , r , iRowLastCrossed + 1 , iSongRow + 1 )
2004-10-23 17:43:49 +00:00
if ( m_Player [ GAMESTATE -> m_MasterPlayerNumber ]. m_NoteData . IsThereATapOrHoldHeadAtRow ( r ) )
2004-01-12 09:36:01 +00:00
iTickRow = r ;
2002-10-12 00:32:47 +00:00
2004-01-12 09:36:01 +00:00
iRowLastCrossed = iSongRow ;
if ( iTickRow != - 1 )
2002-10-12 00:32:47 +00:00
{
2004-01-12 09:36:01 +00:00
const float fTickBeat = NoteRowToBeat ( iTickRow );
const float fTickSecond = GAMESTATE -> m_pCurSong -> m_Timing . GetElapsedTimeFromBeat ( fTickBeat );
float fSecondsUntil = fTickSecond - GAMESTATE -> m_fMusicSeconds ;
2004-01-20 03:10:55 +00:00
fSecondsUntil /= GAMESTATE -> m_SongOptions . m_fMusicRate ; /* 2x music rate means the time until the tick is halved */
2002-10-12 00:32:47 +00:00
2004-02-28 02:09:46 +00:00
RageSoundParams p ;
2004-04-04 04:11:43 +00:00
p . StartTime = GAMESTATE -> m_LastBeatUpdate + ( fSecondsUntil - ( float ) TICK_EARLY_SECONDS );
2004-02-28 02:09:46 +00:00
m_soundAssistTick . Play ( & p );
2002-10-12 00:32:47 +00:00
}
}
2002-06-14 22:25:22 +00:00
2004-02-16 05:29:33 +00:00
/* Play announcer "type" if it's been at least fSeconds since the last announcer. */
void ScreenGameplay :: PlayAnnouncer ( CString type , float fSeconds )
{
if ( GAMESTATE -> m_fOpponentHealthPercent == 0 )
return ; // Shut the announcer up
2004-03-08 04:30:57 +00:00
/* Don't play in demonstration. */
if ( GAMESTATE -> m_bDemonstrationOrJukebox )
return ;
2004-02-16 05:29:33 +00:00
/* Don't play before the first beat, or after we're finished. */
if ( m_DancingState != STATE_DANCING )
return ;
2004-02-21 17:21:03 +00:00
if ( GAMESTATE -> m_pCurSong == NULL || // this will be true on ScreenDemonstration sometimes
GAMESTATE -> m_fSongBeat < GAMESTATE -> m_pCurSong -> m_fFirstBeat )
2004-02-16 05:29:33 +00:00
return ;
if ( m_fTimeSinceLastDancingComment < fSeconds )
return ;
m_fTimeSinceLastDancingComment = 0 ;
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( type );
2004-02-16 05:29:33 +00:00
if ( m_pCombinedLifeMeter )
m_pCombinedLifeMeter -> OnTaunt ();
}
2002-10-29 01:26:10 +00:00
2004-05-21 00:58:48 +00:00
void ScreenGameplay :: UpdateSongPosition ( float fDeltaTime )
{
2004-10-25 03:47:22 +00:00
if ( ! m_pSoundMusic -> IsPlaying () )
2004-05-21 00:58:48 +00:00
return ;
RageTimer tm ;
2004-10-25 03:47:22 +00:00
const float fSeconds = m_pSoundMusic -> GetPositionSeconds ( NULL , & tm );
2004-05-21 00:58:48 +00:00
const float fAdjust = SOUND -> GetFrameTimingAdjustment ( fDeltaTime );
GAMESTATE -> UpdateSongPosition ( fSeconds + fAdjust , GAMESTATE -> m_pCurSong -> m_Timing , tm + fAdjust );
}
2002-05-20 08:59:37 +00:00
void ScreenGameplay :: Update ( float fDeltaTime )
{
2003-03-24 21:26:12 +00:00
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 ;
}
2003-03-12 01:26:44 +00:00
if ( m_bFirstUpdate )
{
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay intro" ); // crowd cheer
2003-03-16 07:30:50 +00:00
2003-03-12 01:26:44 +00:00
//
// Get the transitions rolling
//
2005-01-03 23:20:11 +00:00
if ( GAMESTATE -> m_bDemonstrationOrJukebox )
2003-03-12 01:26:44 +00:00
{
StartPlayingSong ( 0 , 0 ); // *kick* (no transitions)
}
2005-01-25 05:11:18 +00:00
else if ( NSMAN -> useSMserver )
{
//If we're using networking, we must not have any
//delay. If we do this can cause inconsistancy
//on different computers and differet themes
StartPlayingSong ( 0 , 0 );
m_pSoundMusic -> Stop ();
2005-01-26 06:48:01 +00:00
float startOffset = g_fNetStartOffset ;
2005-01-25 05:11:18 +00:00
NSMAN -> StartRequest ( 1 );
RageSoundParams p ;
p . AccurateSync = true ;
p . SetPlaybackRate ( 1.0 ); //Force 1.0 playback speed
p . StopMode = RageSoundParams :: M_CONTINUE ;
2005-01-26 06:48:01 +00:00
p . m_StartSecond = startOffset ;
2005-01-25 05:11:18 +00:00
m_pSoundMusic -> Play ( & p );
UpdateSongPosition ( 0 );
}
2003-03-12 01:26:44 +00:00
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 );
}
}
2004-05-21 00:58:48 +00:00
UpdateSongPosition ( fDeltaTime );
2003-04-13 00:44:50 +00:00
if ( m_bZeroDeltaOnNextUpdate )
{
Screen :: Update ( 0 );
m_bZeroDeltaOnNextUpdate = false ;
}
else
2004-10-24 10:20:24 +00:00
{
2003-04-13 00:44:50 +00:00
Screen :: Update ( fDeltaTime );
2004-10-24 10:20:24 +00:00
}
2003-02-10 22:08:10 +00:00
2004-02-16 05:30:31 +00:00
/* This happens if ScreenDemonstration::HandleScreenMessage sets a new screen when
* PREFSMAN->m_bDelayedScreenLoad. */
2003-03-24 21:29:06 +00:00
if ( GAMESTATE -> m_pCurSong == NULL )
return ;
2004-02-16 05:30:31 +00:00
/* This can happen if ScreenDemonstration::HandleScreenMessage sets a new screen when
* !PREFSMAN->m_bDelayedScreenLoad. (The new screen was loaded when we called Screen::Update,
* and the ctor might set a new GAMESTATE->m_pCurSong, so the above check can fail.) */
if ( SCREENMAN -> GetTopScreen () != this )
return ;
2003-02-10 22:08:10 +00:00
2005-03-11 03:54:40 +00:00
/* Update actors when paused, but never move on to another state. */
if ( m_bPaused )
return ;
2005-02-28 08:43:49 +00:00
if ( GAMESTATE -> m_MasterPlayerNumber != PLAYER_INVALID && ! m_MaxCombo . GetHidden () )
2005-02-16 03:25:45 +00:00
m_MaxCombo . SetText ( ssprintf ( "%d" , STATSMAN -> m_CurStageStats . m_player [ GAMESTATE -> m_MasterPlayerNumber ]. iMaxCombo ) ); /* MAKE THIS WORK FOR BOTH PLAYERS! */
2003-02-10 22:08:10 +00:00
2002-07-31 19:40:40 +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
2004-10-24 10:45:30 +00:00
m_AutoKeysounds . Update ( fDeltaTime );
2004-06-08 07:16:28 +00:00
2003-12-07 20:29:42 +00:00
//
// update GameState HealthState
//
2004-05-16 12:34:02 +00:00
FOREACH_EnabledPlayer ( p )
2003-12-07 20:29:42 +00:00
{
2004-06-10 19:38:38 +00:00
if (
( m_pLifeMeter [ p ] && m_pLifeMeter [ p ] -> IsFailing ()) ||
( m_pCombinedLifeMeter && m_pCombinedLifeMeter -> IsFailing ( p )) )
2004-06-08 07:16:28 +00:00
{
2004-12-20 21:27:24 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_HealthState = PlayerState :: DEAD ;
2004-06-08 07:16:28 +00:00
}
else if (
2004-05-16 12:34:02 +00:00
( m_pLifeMeter [ p ] && m_pLifeMeter [ p ] -> IsHot ()) ||
2004-06-08 07:16:28 +00:00
( m_pCombinedLifeMeter && m_pCombinedLifeMeter -> IsHot ( p )) )
2003-12-07 20:29:42 +00:00
{
2004-12-20 21:27:24 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_HealthState = PlayerState :: HOT ;
2004-05-16 12:34:02 +00:00
}
else if (
( m_pLifeMeter [ p ] && m_pLifeMeter [ p ] -> IsInDanger ()) ||
2004-06-08 07:16:28 +00:00
( m_pCombinedLifeMeter && m_pCombinedLifeMeter -> IsInDanger ( p )) )
2004-05-16 12:34:02 +00:00
{
2004-12-20 21:27:24 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_HealthState = PlayerState :: DANGER ;
2004-05-16 12:34:02 +00:00
}
else
{
2004-12-20 21:27:24 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_HealthState = PlayerState :: ALIVE ;
2003-12-07 20:29:42 +00:00
}
}
2004-06-08 07:16:28 +00:00
2002-05-20 08:59:37 +00:00
switch ( m_DancingState )
{
case STATE_DANCING :
2005-02-16 03:25:45 +00:00
/* Set STATSMAN->m_CurStageStats.bFailed for failed players. In, FAIL_IMMEDIATE, send
2005-05-09 02:58:30 +00:00
* SM_BeginFailed if all players failed, and kill dead Oni players. */
2005-04-05 08:30:57 +00:00
FOREACH_EnabledPlayer ( pn )
2004-06-11 20:09:53 +00:00
{
2005-04-05 08:30:57 +00:00
SongOptions :: FailType ft = GAMESTATE -> GetPlayerFailType ( pn );
2005-04-08 00:53:17 +00:00
SongOptions :: LifeType lt = GAMESTATE -> m_SongOptions . m_LifeType ;
2005-04-05 08:30:57 +00:00
if ( ft == SongOptions :: FAIL_OFF )
continue ;
2004-06-11 20:09:53 +00:00
2005-04-05 08:30:57 +00:00
// check for individual fail
if ( ( m_pLifeMeter [ pn ] && ! m_pLifeMeter [ pn ] -> IsFailing ()) ||
( m_pCombinedLifeMeter && ! m_pCombinedLifeMeter -> IsFailing ( pn )) )
continue ; /* isn't failing */
if ( STATSMAN -> m_CurStageStats . m_player [ pn ]. bFailed )
continue ; /* failed and is already dead */
/* If recovery is enabled, only set fail if both are failing.
* There's no way to recover mid-song in battery mode. */
2005-04-08 00:53:17 +00:00
if ( lt != SongOptions :: LIFE_BATTERY &&
2005-04-05 08:30:57 +00:00
PREFSMAN -> m_bTwoPlayerRecovery && ! GAMESTATE -> AllAreDead () )
continue ;
2004-06-11 20:09:53 +00:00
2005-04-05 08:30:57 +00:00
LOG -> Trace ( "Player %d failed" , ( int ) pn );
STATSMAN -> m_CurStageStats . m_player [ pn ]. bFailed = true ; // fail
2004-06-11 20:09:53 +00:00
2005-05-09 02:58:30 +00:00
//
// Check for and do Oni die.
//
bool bAllowOniDie = false ;
switch ( lt )
{
case SongOptions :: LIFE_BATTERY :
bAllowOniDie = true ;
break ;
}
if ( bAllowOniDie && ft == SongOptions :: FAIL_IMMEDIATE )
2005-04-05 08:30:57 +00:00
{
if ( ! STATSMAN -> m_CurStageStats . AllFailedEarlier () ) // if not the last one to fail
2004-06-11 20:09:53 +00:00
{
2005-04-05 08:30:57 +00:00
// kill them!
SOUND -> PlayOnceFromDir ( THEME -> GetPathS ( m_sName , "oni die" ) );
ShowOniGameOver ( pn );
m_Player [ pn ]. m_NoteData . Init (); // remove all notes and scoring
m_Player [ pn ]. FadeToFail (); // tell the NoteField to fade to white
2004-06-11 20:09:53 +00:00
}
}
}
2005-04-05 08:30:57 +00:00
bool bAllFailed = true ;
FOREACH_EnabledPlayer ( pn )
2005-02-17 21:30:10 +00:00
{
2005-04-05 08:30:57 +00:00
SongOptions :: FailType ft = GAMESTATE -> GetPlayerFailType ( pn );
switch ( ft )
{
case SongOptions :: FAIL_IMMEDIATE :
if ( GAMESTATE -> m_pPlayerState [ pn ] -> m_HealthState < PlayerState :: DEAD )
bAllFailed = false ;
break ;
case SongOptions :: FAIL_END_OF_SONG :
bAllFailed = false ; // wait until the end of the song to fail.
break ;
case SongOptions :: FAIL_OFF :
bAllFailed = false ; // never fail.
break ;
default :
ASSERT ( 0 );
}
2005-02-17 21:30:10 +00:00
}
2005-04-05 08:30:57 +00:00
if ( bAllFailed )
2004-08-01 00:35:14 +00:00
SCREENMAN -> PostMessageToTopScreen ( SM_BeginFailed , 0 );
2004-06-11 20:09:53 +00:00
2003-01-24 02:43:07 +00:00
//
2003-03-30 20:54:37 +00:00
// Update living players' alive time
2003-01-24 02:43:07 +00:00
//
2004-05-16 12:42:16 +00:00
FOREACH_EnabledPlayer ( pn )
2005-02-16 03:25:45 +00:00
if ( ! STATSMAN -> m_CurStageStats . m_player [ pn ]. bFailed )
STATSMAN -> m_CurStageStats . m_player [ pn ]. fAliveSeconds += fDeltaTime * GAMESTATE -> m_SongOptions . m_fMusicRate ;
2003-01-24 02:43:07 +00:00
2003-12-09 10:20:18 +00:00
// update fGameplaySeconds
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . fGameplaySeconds += fDeltaTime ;
2005-04-23 02:50:26 +00:00
if ( GAMESTATE -> m_fSongBeat >= GAMESTATE -> m_pCurSong -> m_fFirstBeat && GAMESTATE -> m_fSongBeat < GAMESTATE -> m_pCurSong -> m_fLastBeat )
STATSMAN -> m_CurStageStats . fStepsSeconds += fDeltaTime ;
2003-12-09 10:20:18 +00:00
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
//
2004-03-03 08:03:47 +00:00
float fSecondsToStop = GAMESTATE -> m_pCurSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_pCurSong -> m_fLastBeat );
2004-03-13 22:41:31 +00:00
/* Make sure we keep going long enough to register a miss for the last note. */
2005-04-28 00:13:01 +00:00
fSecondsToStop += m_Player [ GAMESTATE -> m_MasterPlayerNumber ]. GetMaxStepDistanceSeconds ();
2004-03-13 22:41:31 +00:00
2005-03-19 00:03:53 +00:00
if ( GAMESTATE -> m_fMusicSeconds > fSecondsToStop && ! m_SongFinished . IsTransitioning () && ! m_NextSong . IsTransitioning () )
2004-03-06 10:07:17 +00:00
m_SongFinished . StartTransitioning ( SM_NotesEnded );
2003-11-10 23:25:44 +00:00
//
// update 2d dancing characters
//
2004-05-16 12:34:02 +00:00
FOREACH_EnabledPlayer ( p )
2003-11-10 23:25:44 +00:00
{
2005-03-11 02:12:21 +00:00
DancingCharacters * pCharacter = m_SongBackground . GetDancingCharacters ();
2005-02-07 04:02:38 +00:00
if ( pCharacter != NULL )
2005-02-07 04:12:51 +00:00
{
TapNoteScore tns = m_Player [ p ]. GetLastTapNoteScore ();
2005-04-13 01:11:44 +00:00
ANIM_STATES_2D state = AS2D_MISS ;
switch ( tns )
2005-02-07 04:12:51 +00:00
{
2005-04-13 01:11:44 +00:00
case TNS_GOOD :
case TNS_GREAT :
state = AS2D_GOOD ;
break ;
case TNS_PERFECT :
case TNS_MARVELOUS :
state = AS2D_GREAT ;
break ;
default :
2005-04-15 11:50:48 +00:00
state = AS2D_MISS ;
break ;
2005-04-13 01:11:44 +00:00
}
2005-02-07 04:12:51 +00:00
if ( state == AS2D_GREAT && m_pLifeMeter [ p ] && m_pLifeMeter [ p ] -> GetLife () == 1.0f ) // full life
state = AS2D_FEVER ;
pCharacter -> Change2DAnimState ( p , state );
}
2003-11-10 23:25:44 +00:00
}
2003-07-08 19:56:56 +00:00
//
// Check for enemy death in enemy battle
//
static float fLastSeenEnemyHealth = 1 ;
if ( fLastSeenEnemyHealth != GAMESTATE -> m_fOpponentHealthPercent )
{
fLastSeenEnemyHealth = GAMESTATE -> m_fOpponentHealthPercent ;
if ( GAMESTATE -> m_fOpponentHealthPercent == 0 )
{
2004-02-16 05:29:33 +00:00
// HACK: Load incorrect directory on purpose for now.
PlayAnnouncer ( "gameplay battle damage level3" , 0 );
2003-07-09 02:27:05 +00:00
2003-07-08 19:56:56 +00:00
GAMESTATE -> RemoveAllActiveAttacks ();
2004-05-16 12:34:02 +00:00
FOREACH_CpuPlayer ( p )
2003-07-08 19:56:56 +00:00
{
2004-05-31 08:58:43 +00:00
SOUND -> PlayOnceFromDir ( THEME -> GetPathS ( m_sName , "oni die" ) );
2004-07-23 04:45:48 +00:00
ShowOniGameOver ( p );
2004-10-23 17:43:49 +00:00
m_Player [ p ]. m_NoteData . Init (); // remove all notes and scoring
2004-05-16 12:34:02 +00:00
m_Player [ p ]. FadeToFail (); // tell the NoteField to fade to white
2003-07-08 19:56:56 +00:00
}
}
}
2002-07-27 19:29:51 +00:00
//
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
//
2004-02-16 05:29:33 +00:00
m_fTimeSinceLastDancingComment += fDeltaTime ;
switch ( GAMESTATE -> m_PlayMode )
2002-05-20 08:59:37 +00:00
{
2004-06-11 06:05:35 +00:00
case PLAY_MODE_REGULAR :
2004-02-16 05:29:33 +00:00
case PLAY_MODE_BATTLE :
case PLAY_MODE_RAVE :
if ( GAMESTATE -> OneIsHot () )
PlayAnnouncer ( "gameplay comment hot" , SECONDS_BETWEEN_COMMENTS );
else if ( GAMESTATE -> AllAreInDangerOrWorse () )
PlayAnnouncer ( "gameplay comment danger" , SECONDS_BETWEEN_COMMENTS );
else
PlayAnnouncer ( "gameplay comment good" , SECONDS_BETWEEN_COMMENTS );
break ;
case PLAY_MODE_NONSTOP :
case PLAY_MODE_ONI :
case PLAY_MODE_ENDLESS :
PlayAnnouncer ( "gameplay comment oni" , SECONDS_BETWEEN_COMMENTS );
break ;
default :
ASSERT ( 0 );
2002-05-20 08:59:37 +00:00
}
}
2003-09-06 03:25:45 +00:00
2003-12-25 05:53:30 +00:00
//
2005-04-27 06:34:53 +00:00
// update give up
2003-12-25 05:53:30 +00:00
//
2005-04-27 06:34:53 +00:00
bool bGiveUpTimerFired = ! m_GiveUpTimer . IsZero () && m_GiveUpTimer . Ago () > 2.5f ;
2005-05-09 15:14:19 +00:00
if ( bGiveUpTimerFired || ( FAIL_AFTER_30_MISSES && GAMESTATE -> AllHumanHaveComboOf30OrMoreMisses ()) )
2003-09-06 03:25:45 +00:00
{
2005-05-09 10:12:03 +00:00
// Give up
FOREACH_PlayerNumber ( p )
2005-05-09 15:14:19 +00:00
{
2005-05-09 10:12:03 +00:00
STATSMAN -> m_CurStageStats . m_player [ p ]. bGaveUp = true ;
2005-05-20 03:21:13 +00:00
STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed |= GAMESTATE -> AllHumanHaveComboOf30OrMoreMisses ();
2005-05-09 15:14:19 +00:00
}
2005-05-09 10:12:03 +00:00
2003-09-06 03:25:45 +00:00
m_GiveUpTimer . SetZero ();
2005-04-27 06:34:53 +00:00
if ( GIVING_UP_GOES_TO_PREV_SCREEN )
2005-03-10 02:45:40 +00:00
{
2005-04-27 06:34:53 +00:00
BackOutFromGameplay ();
2005-03-10 02:45:40 +00:00
2005-03-11 04:53:45 +00:00
}
2005-04-10 06:21:59 +00:00
else if ( GIVING_UP_GOES_TO_NEXT_SCREEN )
{
HandleScreenMessage ( SM_LeaveGameplay );
return ;
}
2005-03-11 04:53:45 +00:00
else
{
2005-04-27 06:34:53 +00:00
this -> PostScreenMessage ( SM_NotesEnded , 0 );
2005-03-10 02:45:40 +00:00
}
2005-04-27 06:34:53 +00:00
return ;
2003-09-06 03:25:45 +00:00
}
2004-12-18 08:15:19 +00:00
//
// update bpm display
//
2005-02-28 08:43:49 +00:00
if ( m_fLastBPS != GAMESTATE -> m_fCurBPS && ! m_BPMDisplay . GetHidden () )
2004-12-18 08:15:19 +00:00
{
m_fLastBPS = GAMESTATE -> m_fCurBPS ;
2005-03-17 17:53:10 +00:00
m_BPMDisplay . SetConstantBpm ( GAMESTATE -> m_fCurBPS * 60.0f );
2004-12-18 08:15:19 +00:00
}
2004-01-12 09:36:01 +00:00
PlayTicks ();
2003-11-20 11:55:45 +00:00
2004-12-03 23:30:50 +00:00
UpdateLights ();
2005-04-24 11:03:02 +00:00
SendCrossedMessages ();
2004-12-03 23:30:50 +00:00
if ( NSMAN -> useSMserver )
{
FOREACH_EnabledPlayer ( pn2 )
if ( m_pLifeMeter [ pn2 ] )
NSMAN -> m_playerLife [ pn2 ] = int ( m_pLifeMeter [ pn2 ] -> GetLife () * 10000 );
FOREACH_NSScoreBoardColumn ( cn )
if ( m_ShowScoreboard && NSMAN -> ChangedScoreboard ( cn ) )
m_Scoreboard [ cn ]. SetText ( NSMAN -> m_Scoreboard [ cn ] );
}
}
void ScreenGameplay :: UpdateLights ()
{
2004-12-03 23:31:35 +00:00
if ( ! LIGHTSMAN -> IsEnabled () )
return ;
2005-06-02 20:06:26 +00:00
if ( m_CabinetLightsNoteData . GetNumTracks () == 0 ) // light data wasn't loaded
return ;
2004-12-03 23:31:35 +00:00
2004-06-28 07:26:00 +00:00
const Style * pStyle = GAMESTATE -> GetCurrentStyle ();
2004-04-22 05:25:58 +00:00
bool bBlinkCabinetLight [ NUM_CABINET_LIGHTS ];
bool bBlinkGameButton [ MAX_GAME_CONTROLLERS ][ MAX_GAME_BUTTONS ];
ZERO ( bBlinkCabinetLight );
ZERO ( bBlinkGameButton );
2004-03-30 07:44:29 +00:00
bool bCrossedABeat = false ;
2004-01-12 09:36:01 +00:00
{
2005-05-04 20:37:41 +00:00
const float fSongBeat = GAMESTATE -> m_fLightSongBeat ;
2005-04-29 01:34:52 +00:00
const int iSongRow = BeatToNoteRowNotRounded ( fSongBeat );
2004-01-12 09:36:01 +00:00
static int iRowLastCrossed = 0 ;
2004-03-30 07:44:29 +00:00
float fBeatLast = roundf ( NoteRowToBeat ( iRowLastCrossed ));
2005-04-29 01:31:41 +00:00
float fBeatNow = roundf ( NoteRowToBeat ( iSongRow ));
2004-03-30 07:44:29 +00:00
bCrossedABeat = fBeatLast != fBeatNow ;
2004-01-12 09:36:01 +00:00
2004-12-03 23:39:50 +00:00
FOREACH_CabinetLight ( cl )
{
// for each index we crossed since the last update:
2005-04-29 01:31:41 +00:00
FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE ( m_CabinetLightsNoteData , cl , r , iRowLastCrossed + 1 , iSongRow + 1 )
2004-12-03 23:39:50 +00:00
{
2005-04-29 01:35:44 +00:00
if ( m_CabinetLightsNoteData . GetTapNote ( cl , r ). type != TapNote :: empty )
bBlinkCabinetLight [ cl ] = true ;
2004-04-22 05:25:58 +00:00
}
2005-01-23 06:31:41 +00:00
2005-04-29 01:31:41 +00:00
if ( m_CabinetLightsNoteData . IsHoldNoteAtBeat ( cl , iSongRow ) )
2005-04-29 01:35:44 +00:00
bBlinkCabinetLight [ cl ] = true ;
2004-12-03 23:33:06 +00:00
}
2004-12-03 23:43:35 +00:00
FOREACH_EnabledPlayer ( pn )
2004-12-03 23:33:06 +00:00
{
2004-12-03 23:43:35 +00:00
for ( int t = 0 ; t < m_Player [ pn ]. m_NoteData . GetNumTracks (); t ++ )
2004-04-22 05:25:58 +00:00
{
2005-04-29 01:35:44 +00:00
bool bBlink = false ;
2004-12-03 23:43:35 +00:00
// for each index we crossed since the last update:
2005-04-29 01:31:41 +00:00
FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE ( m_Player [ pn ]. m_NoteData , t , r , iRowLastCrossed + 1 , iSongRow + 1 )
2004-04-22 05:25:58 +00:00
{
2004-10-23 17:43:49 +00:00
TapNote tn = m_Player [ pn ]. m_NoteData . GetTapNote ( t , r );
2005-04-29 01:35:44 +00:00
if ( tn . type != TapNote :: empty && tn . type != TapNote :: mine )
bBlink = true ;
}
// check if a hold should be active
if ( m_Player [ pn ]. m_NoteData . IsHoldNoteAtBeat ( t , iSongRow ) )
bBlink = true ;
if ( bBlink )
{
StyleInput si ( pn , t );
GameInput gi = pStyle -> StyleInputToGameInput ( si );
bBlinkGameButton [ gi . controller ][ gi . button ] = true ;
2004-04-22 05:25:58 +00:00
}
}
2004-01-12 09:36:01 +00:00
}
2005-04-29 01:31:41 +00:00
iRowLastCrossed = iSongRow ;
2004-01-12 09:36:01 +00:00
}
2005-05-09 04:48:18 +00:00
// Before the first beat of the song, all cabinet lights solid on (except for menu buttons).
bool bOverrideCabinetBlink = ( GAMESTATE -> m_fSongBeat < GAMESTATE -> m_pCurSong -> m_fFirstBeat );
2004-04-20 02:35:30 +00:00
FOREACH_CabinetLight ( cl )
{
2004-10-15 14:37:33 +00:00
switch ( cl )
{
case LIGHT_BUTTONS_LEFT :
case LIGHT_BUTTONS_RIGHT :
// don't blink
break ;
default :
bBlinkCabinetLight [ cl ] |= bOverrideCabinetBlink ;
break ;
}
}
// Send blink data.
FOREACH_CabinetLight ( cl )
{
if ( bBlinkCabinetLight [ cl ] )
2004-04-22 05:25:58 +00:00
LIGHTSMAN -> BlinkCabinetLight ( cl );
}
FOREACH_GameController ( gc )
{
FOREACH_GameButton ( gb )
{
if ( bBlinkGameButton [ gc ][ gb ] )
LIGHTSMAN -> BlinkGameButton ( GameInput ( gc , gb ) );
}
2004-04-20 02:35:30 +00:00
}
2002-05-20 08:59:37 +00:00
}
2005-04-24 11:03:02 +00:00
void ScreenGameplay :: SendCrossedMessages ()
{
{
2005-05-01 22:59:00 +00:00
static int iRowLastCrossed = 0 ;
2005-04-24 11:03:02 +00:00
2005-05-01 22:59:00 +00:00
float fPositionSeconds = GAMESTATE -> m_fMusicSeconds ;
2005-04-24 11:15:07 +00:00
float fSongBeat = GAMESTATE -> m_pCurSong -> GetBeatFromElapsedTime ( fPositionSeconds );
int iRowNow = BeatToNoteRowNotRounded ( fSongBeat );
iRowNow = max ( 0 , iRowNow );
2005-05-01 22:59:00 +00:00
for ( int r = iRowLastCrossed + 1 ; r <= iRowNow ; r ++ )
2005-04-24 11:03:02 +00:00
{
2005-05-01 22:59:00 +00:00
if ( GetNoteType ( r ) == NOTE_TYPE_4TH )
MESSAGEMAN -> Broadcast ( MESSAGE_BEAT_CROSSED );
2005-04-24 11:03:02 +00:00
}
2005-04-24 11:15:07 +00:00
iRowLastCrossed = iRowNow ;
2005-04-24 11:03:02 +00:00
}
2005-05-01 22:59:00 +00:00
{
const int NUM_MESSAGES_TO_SEND = 4 ;
const float MESSAGE_SPACING_SECONDS = 0.5f ;
PlayerNumber pn = PLAYER_INVALID ;
FOREACH_EnabledPlayer ( p )
{
if ( GAMESTATE -> m_pCurSteps [ p ] -> GetDifficulty () == DIFFICULTY_BEGINNER )
{
pn = p ;
break ;
}
}
if ( pn == PLAYER_INVALID )
return ;
NoteData & nd = m_Player [ pn ]. m_NoteData ;
static int iRowLastCrossedAll [ NUM_MESSAGES_TO_SEND ] = { 0 , 0 , 0 , 0 };
for ( int i = 0 ; i < NUM_MESSAGES_TO_SEND ; i ++ )
{
float fOffsetFromCurrentSeconds = MESSAGE_SPACING_SECONDS * i ;
float fPositionSeconds = GAMESTATE -> m_fMusicSeconds + fOffsetFromCurrentSeconds ;
float fSongBeat = GAMESTATE -> m_pCurSong -> GetBeatFromElapsedTime ( fPositionSeconds );
int iRowNow = BeatToNoteRowNotRounded ( fSongBeat );
iRowNow = max ( 0 , iRowNow );
int & iRowLastCrossed = iRowLastCrossedAll [ i ];
FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE ( nd , r , iRowLastCrossed + 1 , iRowNow + 1 )
{
2005-05-09 12:26:44 +00:00
int iNumTracksWithTapOrHoldHead = 0 ;
for ( int t = 0 ; t < nd . GetNumTracks (); t ++ )
2005-05-01 22:59:00 +00:00
{
2005-05-09 12:26:44 +00:00
if ( nd . GetTapNote ( t , r ). type == TapNote :: empty )
continue ;
iNumTracksWithTapOrHoldHead ++ ;
2005-05-08 04:10:16 +00:00
// Send col-specific crossed
if ( i == 0 )
{
2005-05-09 12:26:44 +00:00
StyleInput si ( pn , t );
2005-05-08 04:10:16 +00:00
const Game * pGame = GAMESTATE -> GetCurrentGame ();
2005-05-09 12:26:44 +00:00
CString sButton = pGame -> ColToButtonName ( t );
2005-05-08 04:10:16 +00:00
CString sMessageName = "NoteCrossed" + sButton ;
MESSAGEMAN -> Broadcast ( sMessageName );
}
2005-05-09 12:26:44 +00:00
}
if ( iNumTracksWithTapOrHoldHead > 0 )
MESSAGEMAN -> Broadcast ( ( Message )( MESSAGE_NOTE_CROSSED + i ) );
if ( i == 0 && iNumTracksWithTapOrHoldHead >= 2 )
{
CString sMessageName = "NoteCrossedJump" ;
MESSAGEMAN -> Broadcast ( sMessageName );
2005-05-01 22:59:00 +00:00
}
}
iRowLastCrossed = iRowNow ;
}
}
2005-04-24 11:03:02 +00:00
}
2005-03-10 02:45:40 +00:00
void ScreenGameplay :: BackOutFromGameplay ()
{
m_DancingState = STATE_OUTRO ;
2005-03-15 08:44:35 +00:00
AbortGiveUp ( false );
2005-03-10 02:45:40 +00:00
m_pSoundMusic -> StopPlaying ();
m_soundAssistTick . StopPlaying (); /* Stop any queued assist ticks. */
this -> ClearMessageQueue ();
2005-06-29 07:57:15 +00:00
// If this is the final stage, don't allow extra stage
if ( GAMESTATE -> IsFinalStage () )
GAMESTATE -> m_bBackedOutOfFinalStage = true ;
// Disallow backing out of extra stage
if ( GAMESTATE -> IsExtraStage () || GAMESTATE -> IsExtraStage2 () )
SCREENMAN -> PostMessageToTopScreen ( SM_BeginFailed , 0 );
else
m_Cancel . StartTransitioning ( SM_GoToScreenAfterBack );
2005-03-10 02:45:40 +00:00
}
2005-03-15 08:44:35 +00:00
void ScreenGameplay :: AbortGiveUp ( bool bShowText )
2003-09-06 03:25:45 +00:00
{
if ( m_GiveUpTimer . IsZero () )
return ;
m_textDebug . StopTweening ();
2005-03-15 08:44:35 +00:00
if ( bShowText )
m_textDebug . SetText ( GIVE_UP_ABORTED_TEXT );
// otherwise tween out the text that's there
2003-09-06 03:25:45 +00:00
m_textDebug . BeginTweening ( 1 / 2.f );
m_textDebug . SetDiffuse ( RageColor ( 1 , 1 , 1 , 0 ) );
m_GiveUpTimer . SetZero ();
}
2002-05-20 08:59:37 +00:00
void ScreenGameplay :: Input ( const DeviceInput & DeviceI , const InputEventType type , const GameInput & GameI , const MenuInput & MenuI , const StyleInput & StyleI )
{
2002-07-31 19:40:40 +00:00
//LOG->Trace( "ScreenGameplay::Input()" );
2003-01-19 21:57:13 +00:00
2004-09-09 22:21:50 +00:00
if ( type == IET_LEVEL_CHANGED )
return ;
2005-03-11 03:54:40 +00:00
if ( m_bPaused )
{
/* If we're paused, only accept MENU_BUTTON_START to unpause. */
2005-04-21 02:07:02 +00:00
if ( MenuI . IsValid () && GAMESTATE -> IsHumanPlayer ( MenuI . player ) && MenuI . button == MENU_BUTTON_START && type == IET_FIRST_PRESS )
{
if ( m_PauseController == GAME_CONTROLLER_INVALID || m_PauseController == GameI . controller )
this -> PauseGame ( false );
}
2005-03-11 03:54:40 +00:00
return ;
}
2003-01-19 21:57:13 +00:00
if ( MenuI . IsValid () &&
m_DancingState != STATE_OUTRO &&
2005-03-15 08:37:18 +00:00
GAMESTATE -> IsHumanPlayer ( MenuI . player ) &&
2005-03-20 06:14:41 +00:00
! m_Cancel . IsTransitioning () )
2003-01-19 21:57:13 +00:00
{
2003-11-24 02:03:09 +00:00
/* Allow bailing out by holding the START button of all active players. This
* gives a way to "give up" when a back button isn't available. Doing this is
* treated as failing the song, unlike BACK, since it's always available.
*
* However, if this is also a style button, don't do this. (pump center = start) */
2005-03-10 02:45:40 +00:00
bool bHoldingGiveUp = false ;
2005-03-14 20:26:50 +00:00
bHoldingGiveUp |= ( START_GIVES_UP && MenuI . button == MENU_BUTTON_START && ! StyleI . IsValid () );
bHoldingGiveUp |= ( BACK_GIVES_UP && MenuI . button == MENU_BUTTON_BACK && ! StyleI . IsValid () );
2005-03-10 02:45:40 +00:00
if ( bHoldingGiveUp )
2003-09-06 03:25:45 +00:00
{
/* No PREFSMAN->m_bDelayedEscape; always delayed. */
if ( type == IET_RELEASE )
2005-03-15 08:44:35 +00:00
AbortGiveUp ( true );
2003-11-24 02:03:09 +00:00
else if ( type == IET_FIRST_PRESS && m_GiveUpTimer . IsZero () )
2003-09-06 03:25:45 +00:00
{
2005-03-12 00:04:27 +00:00
m_textDebug . SetText ( GIVE_UP_TEXT );
2003-09-06 03:25:45 +00:00
m_textDebug . StopTweening ();
m_textDebug . SetDiffuse ( RageColor ( 1 , 1 , 1 , 0 ) );
m_textDebug . BeginTweening ( 1 / 8.f );
m_textDebug . SetDiffuse ( RageColor ( 1 , 1 , 1 , 1 ) );
m_GiveUpTimer . Touch (); /* start the timer */
}
return ;
}
2005-03-10 02:45:40 +00:00
/* Only handle MENU_BUTTON_BACK as a regular BACK button if BACK_GIVES_UP is
* disabled. */
2005-03-14 20:26:50 +00:00
if ( MenuI . button == MENU_BUTTON_BACK && ! BACK_GIVES_UP )
2003-01-19 21:57:13 +00:00
{
2005-03-10 02:45:40 +00:00
if ( (( ! PREFSMAN -> m_bDelayedBack && type == IET_FIRST_PRESS ) ||
( DeviceI . device == DEVICE_KEYBOARD && ( type == IET_SLOW_REPEAT || type == IET_FAST_REPEAT )) ||
( DeviceI . device != DEVICE_KEYBOARD && type == IET_FAST_REPEAT )) )
{
LOG -> Trace ( "Player %i went back" , MenuI . player + 1 );
BackOutFromGameplay ();
}
else if ( PREFSMAN -> m_bDelayedBack && 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 . SetDiffuse ( RageColor ( 1 , 1 , 1 , 1 ) );
}
else if ( PREFSMAN -> m_bDelayedBack && type == IET_RELEASE )
{
m_textDebug . StopTweening ();
m_textDebug . BeginTweening ( 1 / 8.f );
m_textDebug . SetDiffuse ( RageColor ( 1 , 1 , 1 , 0 ) );
}
2004-02-16 01:35:59 +00:00
2004-02-15 02:06:39 +00:00
return ;
}
2003-01-19 21:57:13 +00:00
}
2004-12-22 07:31:27 +00:00
/* Nothing below cares about releases. */
2003-01-19 21:57:13 +00:00
if ( type == IET_RELEASE ) return ;
2002-05-20 08:59:37 +00:00
2002-06-24 22:04:31 +00:00
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 &&
StyleI . IsValid () &&
2004-01-01 04:11:18 +00:00
GAMESTATE -> IsHumanPlayer ( StyleI . player ) )
2003-02-27 10:56:37 +00:00
{
2005-03-15 08:44:35 +00:00
AbortGiveUp ( true );
2003-11-24 02:03:09 +00:00
2005-05-18 07:15:56 +00:00
if ( PREFSMAN -> m_AutoPlay == PC_HUMAN )
2003-11-24 02:03:09 +00:00
m_Player [ StyleI . player ]. Step ( StyleI . col , DeviceI . ts );
2003-02-27 10:56:37 +00:00
}
2002-05-20 08:59:37 +00:00
}
2003-01-11 08:55:21 +00:00
2002-07-27 19:29:51 +00:00
2003-12-23 02:18:27 +00:00
/*
* Saving StageStats that are affected by the note pattern is a little tricky:
*
* Stats are cumulative for course play.
*
* For regular songs, it doesn't matter how we do it; the pattern doesn't change
* during play.
*
* The pattern changes during play in battle and course mode. We want to include these
* changes, so run stats for a song after the song finishes.
*
* If we fail, be sure to include the current song in stats, with the current modifier set.
*
* So:
*
* 1. At the end of a song in any mode, pass or fail, add stats for that song (from m_Player).
* 2. At the end of gameplay in course mode, add stats for any songs that weren't played,
* applying the modifiers the song would have been played with. This doesn't include songs
* that were played but failed; that was done in #1.
*/
2003-12-15 06:24:59 +00:00
void ScreenGameplay :: SongFinished ()
{
// save any statistics
2004-05-16 12:34:02 +00:00
FOREACH_EnabledPlayer ( p )
2003-12-15 06:24:59 +00:00
{
2004-07-11 07:21:33 +00:00
/* Note that adding stats is only meaningful for the counters (eg. RADAR_NUM_JUMPS),
* not for the percentages (RADAR_AIR). */
RadarValues v ;
2005-04-26 04:16:45 +00:00
NoteDataUtil :: CalculateRadarValues ( m_Player [ p ]. m_NoteData , GAMESTATE -> m_pCurSong -> m_fMusicLengthSeconds , v );
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . m_player [ p ]. radarPossible += v ;
2004-07-11 07:21:33 +00:00
2005-01-22 18:22:38 +00:00
NoteDataWithScoring :: GetActualRadarValues ( m_Player [ p ]. m_NoteData , p , GAMESTATE -> m_pCurSong -> m_fMusicLengthSeconds , v );
2005-02-16 03:25:45 +00:00
STATSMAN -> m_CurStageStats . m_player [ p ]. radarActual += v ;
2003-12-15 06:24:59 +00:00
}
2004-02-16 10:22:18 +00:00
/* Extremely important: if we don't remove attacks before moving on to the next
* screen, they'll still be turned on eventually. */
GAMESTATE -> RemoveAllActiveAttacks ();
2004-07-30 07:18:21 +00:00
FOREACH_EnabledPlayer ( p )
m_ActiveAttackList [ p ]. Refresh ();
2003-12-23 02:18:27 +00:00
}
2003-12-15 06:24:59 +00:00
2004-02-21 21:00:49 +00:00
void ScreenGameplay :: StageFinished ( bool bBackedOut )
2003-12-23 02:18:27 +00:00
{
if ( GAMESTATE -> IsCourseMode () && GAMESTATE -> m_PlayMode != PLAY_MODE_ENDLESS )
{
2004-01-03 04:38:17 +00:00
LOG -> Trace ( "Stage finished at index %i/%i" , GAMESTATE -> GetCourseSongIndex (), ( int ) m_apSongsQueue . size () );
2003-12-23 02:18:27 +00:00
/* +1 to skip the current song; that's done already. */
for ( unsigned iPlaySongIndex = GAMESTATE -> GetCourseSongIndex () + 1 ;
iPlaySongIndex < m_apSongsQueue . size (); ++ iPlaySongIndex )
{
LOG -> Trace ( "Running stats for %i" , iPlaySongIndex );
2005-04-11 07:59:27 +00:00
SetupSong ( iPlaySongIndex );
2004-05-16 12:34:02 +00:00
FOREACH_EnabledPlayer ( p )
2003-12-23 02:18:27 +00:00
m_Player [ p ]. ApplyWaitingTransforms ();
2005-04-11 07:59:27 +00:00
SongFinished ();
2003-12-23 02:18:27 +00:00
}
}
2003-12-15 06:24:59 +00:00
// save current stage stats
2004-02-21 21:00:49 +00:00
if ( ! bBackedOut )
2005-02-16 03:25:45 +00:00
STATSMAN -> m_vPlayedStageStats . push_back ( STATSMAN -> m_CurStageStats );
2004-01-23 02:04:34 +00:00
/* Reset options. */
GAMESTATE -> RestoreSelectedOptions ();
2003-12-15 06:24:59 +00:00
}
2002-05-20 08:59:37 +00:00
void ScreenGameplay :: HandleScreenMessage ( const ScreenMessage SM )
{
2003-11-14 18:33:12 +00:00
CHECKPOINT_M ( ssprintf ( "HandleScreenMessage(%i)" , SM ) );
2005-04-02 02:45:17 +00:00
if ( SM == SM_DoneFadingIn )
2002-05-20 08:59:37 +00:00
{
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay ready" );
2003-03-09 00:55:49 +00:00
m_Ready . StartTransitioning ( SM_PlayGo );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_PlayGo )
{
2004-02-16 05:29:33 +00:00
if ( GAMESTATE -> IsExtraStage () || GAMESTATE -> IsExtraStage2 () )
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay here we go extra" );
2004-02-16 05:29:33 +00:00
else if ( GAMESTATE -> IsFinalStage () )
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay here we go final" );
2004-02-16 05:29:33 +00:00
else
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay here we go normal" );
2004-02-16 05:29:33 +00:00
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 ;
2003-01-25 07:40:47 +00:00
m_DancingState = STATE_DANCING ; // STATE CHANGE! Now the user is allowed to press Back
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_NotesEnded ) // received while STATE_DANCING
{
2005-04-24 02:21:25 +00:00
AbortGiveUp ( false ); // don't allow giveup while the next song is loading
2005-03-23 08:48:38 +00:00
/* Do this in LoadNextSong, so we don't tween off old attacks until
2005-04-06 06:12:23 +00:00
* m_NextSong finishes. */
2005-03-23 08:48:38 +00:00
// GAMESTATE->RemoveAllActiveAttacks();
2003-01-25 07:40:47 +00:00
2005-04-06 06:12:23 +00:00
FOREACH_EnabledPlayer ( p )
2002-07-23 01:41:40 +00:00
{
2005-03-23 08:48:38 +00:00
/* If either player's passmark is enabled, check it. */
if ( GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerOptions . m_fPassmark > 0 &&
m_pLifeMeter [ p ] &&
m_pLifeMeter [ p ] -> GetLife () < GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerOptions . m_fPassmark )
2003-02-24 02:45:01 +00:00
{
2005-03-23 08:48:38 +00:00
LOG -> Trace ( "Player %i failed: life %f is under %f" ,
p + 1 , m_pLifeMeter [ p ] -> GetLife (), GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerOptions . m_fPassmark );
STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed = true ;
2003-02-24 02:45:01 +00:00
}
2002-07-28 20:28:37 +00:00
2005-03-23 08:48:38 +00:00
/* Mark failure. This hasn't been done yet if m_bTwoPlayerRecovery is set. */
2005-04-05 08:30:57 +00:00
if ( GAMESTATE -> GetPlayerFailType ( p ) != SongOptions :: FAIL_OFF &&
2005-03-23 08:48:38 +00:00
( m_pLifeMeter [ p ] && m_pLifeMeter [ p ] -> IsFailing ()) ||
( m_pCombinedLifeMeter && m_pCombinedLifeMeter -> IsFailing ( p )) )
STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed = true ;
2003-11-03 19:42:06 +00:00
2005-03-23 08:48:38 +00:00
if ( ! STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed )
STATSMAN -> m_CurStageStats . m_player [ p ]. iSongsPassed ++ ;
2005-04-27 06:34:53 +00:00
// set a life record at the point of failue
if ( STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed )
STATSMAN -> m_CurStageStats . m_player [ p ]. SetLifeRecordAt ( 0 , STATSMAN -> m_CurStageStats . fGameplaySeconds );
2005-03-23 08:48:38 +00:00
}
2003-04-13 00:44:50 +00:00
2005-03-23 08:48:38 +00:00
/* If all players have *really* failed (bFailed, not the life meter or
2005-04-06 06:12:23 +00:00
* bFailedEarlier): */
2005-03-23 08:48:38 +00:00
const bool bAllReallyFailed = STATSMAN -> m_CurStageStats . AllFailed ();
2005-04-09 11:32:10 +00:00
const bool bStopCourseEarly = STOP_COURSE_EARLY ;
const bool bIsLastSong = IsLastSong ();
2005-03-23 02:11:33 +00:00
2005-04-09 11:32:10 +00:00
LOG -> Trace ( "bAllReallyFailed = %d, bStopCourseEarly = %d, bIsLastSong = %d" , bAllReallyFailed , bStopCourseEarly , bIsLastSong );
2005-03-23 08:48:38 +00:00
2005-04-09 11:32:10 +00:00
if ( bStopCourseEarly || bAllReallyFailed || bIsLastSong )
2005-03-23 08:48:38 +00:00
{
2005-04-09 11:32:10 +00:00
// Time to leave from ScreenGameplay
2005-04-10 06:21:59 +00:00
HandleScreenMessage ( SM_LeaveGameplay );
2005-04-09 11:32:10 +00:00
}
else
{
/* Load the next song in the course. First, fade out and stop the music. */
2005-03-23 08:48:38 +00:00
float fFadeLengthSeconds = MUSIC_FADE_OUT_SECONDS ;
RageSoundParams p = m_pSoundMusic -> GetParams ();
p . m_FadeLength = fFadeLengthSeconds ;
2005-06-15 02:01:09 +00:00
p . m_LengthSeconds = GAMESTATE -> m_fMusicSeconds + fFadeLengthSeconds ;
2005-03-23 08:48:38 +00:00
m_pSoundMusic -> SetParams ( p );
SCREENMAN -> PostMessageToTopScreen ( SM_StartLoadingNextSong , fFadeLengthSeconds );
return ;
}
}
2005-04-10 06:21:59 +00:00
else if ( SM == SM_LeaveGameplay )
{
// update dancing characters for win / lose
DancingCharacters * Dancers = m_SongBackground . GetDancingCharacters ();
if ( Dancers )
{
FOREACH_EnabledPlayer ( p )
{
/* XXX: In battle modes, switch( GAMESTATE->GetStageResult(p) ). */
if ( STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed )
Dancers -> Change2DAnimState ( p , AS2D_FAIL ); // fail anim
else if ( m_pLifeMeter [ p ] && m_pLifeMeter [ p ] -> GetLife () == 1.0f ) // full life
Dancers -> Change2DAnimState ( p , AS2D_WINFEVER ); // full life pass anim
else
Dancers -> Change2DAnimState ( p , AS2D_WIN ); // pass anim
}
}
/* End round. */
if ( m_DancingState == STATE_OUTRO ) // ScreenGameplay already ended
return ; // ignore
m_DancingState = STATE_OUTRO ;
AbortGiveUp ( false );
GAMESTATE -> RemoveAllActiveAttacks ();
FOREACH_EnabledPlayer ( p )
m_ActiveAttackList [ p ]. Refresh ();
LIGHTSMAN -> SetLightsMode ( LIGHTSMODE_ALL_CLEARED );
bool bAllReallyFailed = STATSMAN -> m_CurStageStats . AllFailed ();
if ( bAllReallyFailed )
{
this -> PostScreenMessage ( SM_BeginFailed , 0 );
return ;
}
// do they deserve an extra stage?
if ( GAMESTATE -> HasEarnedExtraStage () )
{
TweenOffScreen ();
m_Extra . StartTransitioning ( SM_GoToNextScreen );
SOUND -> PlayOnceFromAnnouncer ( "gameplay extra" );
}
else
{
TweenOffScreen ();
switch ( GAMESTATE -> m_PlayMode )
{
case PLAY_MODE_BATTLE :
case PLAY_MODE_RAVE :
{
PlayerNumber winner = GAMESTATE -> GetBestPlayer ();
switch ( winner )
{
case PLAYER_INVALID :
m_Draw . StartTransitioning ( SM_GoToNextScreen );
break ;
default :
m_Win [ winner ]. StartTransitioning ( SM_GoToNextScreen );
break ;
}
}
break ;
default :
m_Cleared . StartTransitioning ( SM_GoToNextScreen );
break ;
}
SOUND -> PlayOnceFromAnnouncer ( "gameplay cleared" );
}
}
2005-03-23 08:48:38 +00:00
else if ( SM == SM_StartLoadingNextSong )
2005-05-08 22:03:41 +00:00
{
2005-03-23 08:48:38 +00:00
m_pSoundMusic -> Stop ();
/* Next song. */
2005-04-21 11:16:01 +00:00
// give a little life back between stages
2005-03-23 08:48:38 +00:00
FOREACH_EnabledPlayer ( p )
{
if ( ! STATSMAN -> m_CurStageStats . m_player [ p ]. bFailed )
{
if ( m_pLifeMeter [ p ] )
m_pLifeMeter [ p ] -> OnSongEnded ();
2005-04-21 11:16:01 +00:00
if ( m_pPrimaryScoreDisplay [ p ] )
m_pPrimaryScoreDisplay [ p ] -> OnSongEnded ();
if ( m_pSecondaryScoreDisplay [ p ] )
m_pSecondaryScoreDisplay [ p ] -> OnSongEnded ();
2005-03-23 08:48:38 +00:00
}
}
2005-04-21 11:16:01 +00:00
if ( m_pCombinedLifeMeter )
m_pCombinedLifeMeter -> OnSongEnded ();
2005-03-23 08:48:38 +00:00
int iPlaySongIndex = GAMESTATE -> GetCourseSongIndex () + 1 ;
iPlaySongIndex %= m_apSongsQueue . size ();
2005-06-16 03:18:13 +00:00
Lua * L = LUA -> Get ();
m_apSongsQueue [ iPlaySongIndex ] -> PushSelf ( L );
GAMESTATE -> m_Environment -> Set ( L , "NextSong" );
2005-03-23 08:48:38 +00:00
MESSAGEMAN -> Broadcast ( "NextCourseSong" );
2005-06-16 03:18:13 +00:00
GAMESTATE -> m_Environment -> Unset ( L , "NextSong" );
LUA -> Release ( L );
2005-03-23 08:48:38 +00:00
m_NextSong . PlayCommand ( "Start" );
m_NextSong . Reset ();
m_NextSong . StartTransitioning ( SM_LoadNextSong );
LoadCourseSongNumber ( GAMESTATE -> GetCourseSongIndex () + 1 );
2005-05-07 09:58:23 +00:00
COMMAND ( m_sprCourseSongNumber , "ChangeIn" );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_LoadNextSong )
{
2003-12-15 06:24:59 +00:00
SongFinished ();
2005-05-07 09:58:23 +00:00
COMMAND ( m_sprCourseSongNumber , "ChangeOut" );
2004-02-14 00:39:24 +00:00
2003-01-25 07:40:47 +00:00
LoadNextSong ();
2003-02-09 21:10:56 +00:00
GAMESTATE -> m_bPastHereWeGo = true ;
2005-03-19 00:03:53 +00:00
m_NextSong . Reset ();
m_NextSong . PlayCommand ( "Finish" );
m_NextSong . StartTransitioning ( SM_None );
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. */
2005-03-19 00:03:53 +00:00
StartPlayingSong ( m_NextSong . GetLengthSeconds () + 2 , 0 );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_PlayToasty )
{
2003-01-11 08:55:21 +00:00
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 ();
2005-03-23 08:48:38 +00:00
}
else if ( SM >= SM_100Combo && SM <= SM_1000Combo )
{
int iCombo = ( SM - SM_100Combo + 1 ) * 100 ;
PlayAnnouncer ( ssprintf ( "gameplay %d combo" , iCombo ), 2 );
}
else if ( SM == SM_ComboStopped )
{
2004-02-16 05:29:33 +00:00
PlayAnnouncer ( "gameplay combo stopped" , 2 );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_ComboContinuing )
{
2004-02-16 05:29:33 +00:00
PlayAnnouncer ( "gameplay combo overflow" , 2 );
2005-03-23 08:48:38 +00:00
}
else if ( SM >= SM_BattleTrickLevel1 && SM <= SM_BattleTrickLevel3 )
{
int iTrickLevel = SM - SM_BattleTrickLevel1 + 1 ;
PlayAnnouncer ( ssprintf ( "gameplay battle trick level%d" , iTrickLevel ), 3 );
switch ( SM )
{
case SM_BattleTrickLevel1 : m_soundBattleTrickLevel1 . Play (); break ;
case SM_BattleTrickLevel2 : m_soundBattleTrickLevel2 . Play (); break ;
case SM_BattleTrickLevel3 : m_soundBattleTrickLevel3 . Play (); break ;
default : ASSERT ( 0 );
}
}
else if ( SM >= SM_BattleDamageLevel1 && SM <= SM_BattleDamageLevel3 )
{
int iDamageLevel = SM - SM_BattleDamageLevel1 + 1 ;
PlayAnnouncer ( ssprintf ( "gameplay battle damage level%d" , iDamageLevel ), 3 );
}
else if ( SM == SM_GoToScreenAfterBack )
{
2003-12-15 06:24:59 +00:00
SongFinished ();
2004-02-21 21:00:49 +00:00
StageFinished ( true );
2003-12-15 06:24:59 +00:00
2004-01-23 02:04:34 +00:00
GAMESTATE -> CancelStage ();
2005-04-16 05:05:25 +00:00
HandleScreenMessage ( SM_GoToPrevScreen );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_GoToNextScreen )
{
2005-04-16 05:05:25 +00:00
SongFinished ();
StageFinished ( false );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_LoseFocus )
{
2004-02-09 19:56:28 +00:00
/* We might have turned the song timer off. Be sure to turn it back on. */
SOUND -> HandleSongTimer ( true );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_BeginFailed )
{
2002-05-20 08:59:37 +00:00
m_DancingState = STATE_OUTRO ;
2005-03-15 08:44:35 +00:00
AbortGiveUp ( false );
2004-10-25 03:47:22 +00:00
m_pSoundMusic -> StopPlaying ();
2004-01-12 09:36:01 +00:00
m_soundAssistTick . StopPlaying (); /* Stop any queued assist ticks. */
2003-04-13 21:17:14 +00:00
TweenOffScreen ();
2005-01-30 03:08:42 +00:00
m_Failed . StartTransitioning ( SM_GoToNextScreen );
2002-05-20 08:59:37 +00:00
2002-08-01 13:42:56 +00:00
// show the survive time if extra stage
if ( GAMESTATE -> IsExtraStage () || GAMESTATE -> IsExtraStage2 () )
{
2003-01-24 02:43:07 +00:00
float fMaxSurviveSeconds = 0 ;
2004-05-16 12:34:02 +00:00
FOREACH_EnabledPlayer ( p )
2005-02-16 03:25:45 +00:00
fMaxSurviveSeconds = max ( fMaxSurviveSeconds , STATSMAN -> m_CurStageStats . m_player [ p ]. fAliveSeconds );
2004-02-22 19:51:46 +00:00
m_textSurviveTime . SetText ( "TIME: " + SecondsToMMSSMsMs ( fMaxSurviveSeconds ) );
2003-08-07 10:15:16 +00:00
SET_XY_AND_ON_COMMAND ( m_textSurviveTime );
2002-08-01 13:42:56 +00:00
}
2003-08-25 17:15:47 +00:00
2004-02-15 23:10:40 +00:00
if ( GAMESTATE -> IsCourseMode () )
2005-03-11 02:38:08 +00:00
if ( GAMESTATE -> GetCourseSongIndex () >= int ( m_apSongsQueue . size () / 2 ) )
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay oni failed halfway" );
2003-08-25 17:15:47 +00:00
else
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay oni failed" );
2003-08-25 17:15:47 +00:00
else
2004-04-12 20:11:36 +00:00
SOUND -> PlayOnceFromAnnouncer ( "gameplay failed" );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_StopMusic )
{
2004-10-25 03:47:22 +00:00
m_pSoundMusic -> Stop ();
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_Pause )
{
2005-03-11 04:12:48 +00:00
/* Ignore SM_Pause when in demonstration. */
if ( GAMESTATE -> m_bDemonstrationOrJukebox )
return ;
2005-03-11 03:54:40 +00:00
if ( ! m_bPaused )
PauseGame ( true );
2002-05-20 08:59:37 +00:00
}
2005-04-16 05:05:25 +00:00
ScreenWithMenuElements :: HandleScreenMessage ( SM );
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 ()
{
2003-04-13 21:17:14 +00:00
ON_COMMAND ( m_sprLifeFrame );
2005-05-07 09:58:23 +00:00
ON_COMMAND ( m_sprCourseSongNumber );
2004-02-14 00:39:24 +00:00
ON_COMMAND ( m_sprStageFrame );
2003-04-13 21:17:14 +00:00
ON_COMMAND ( m_textSongOptions );
ON_COMMAND ( m_sprScoreFrame );
2004-07-18 17:16:57 +00:00
ON_COMMAND ( m_BPMDisplay );
ON_COMMAND ( m_MaxCombo );
2003-06-30 18:08:27 +00:00
if ( m_pCombinedLifeMeter )
ON_COMMAND ( * m_pCombinedLifeMeter );
2004-05-16 12:34:02 +00:00
FOREACH_PlayerNumber ( p )
2002-08-28 22:42:40 +00:00
{
2003-06-30 18:08:27 +00:00
if ( m_pLifeMeter [ p ] )
ON_COMMAND ( * m_pLifeMeter [ p ] );
2002-08-28 22:42:40 +00:00
if ( ! GAMESTATE -> IsPlayerEnabled ( p ) )
continue ;
2003-04-13 21:17:14 +00:00
ON_COMMAND ( m_textCourseSongNumber [ p ] );
2004-01-23 06:20:28 +00:00
ON_COMMAND ( m_textStepsDescription [ p ] );
2003-11-26 06:40:03 +00:00
if ( m_pPrimaryScoreDisplay [ p ] )
ON_COMMAND ( * m_pPrimaryScoreDisplay [ p ] );
if ( m_pSecondaryScoreDisplay [ p ] )
ON_COMMAND ( * m_pSecondaryScoreDisplay [ p ] );
2003-04-13 21:17:14 +00:00
ON_COMMAND ( m_textPlayerOptions [ p ] );
2004-03-17 06:01:17 +00:00
ON_COMMAND ( m_ActiveAttackList [ p ] );
2003-04-13 21:17:14 +00:00
ON_COMMAND ( m_DifficultyIcon [ p ] );
2004-05-31 06:04:30 +00:00
ON_COMMAND ( m_DifficultyMeter [ p ] );
2005-05-21 01:56:08 +00:00
ON_COMMAND ( m_Player [ p ] );
2002-08-28 22:42:40 +00:00
}
2004-08-13 08:24:11 +00:00
2004-08-13 08:40:53 +00:00
if ( m_ShowScoreboard )
FOREACH_NSScoreBoardColumn ( sc )
ON_COMMAND ( m_Scoreboard [ sc ] );
2002-05-20 08:59:37 +00:00
}
2002-06-14 22:25:22 +00:00
void ScreenGameplay :: TweenOffScreen ()
{
2005-04-02 02:45:17 +00:00
ScreenWithMenuElements :: TweenOffScreen ();
2003-04-13 21:17:14 +00:00
OFF_COMMAND ( m_sprLifeFrame );
2005-05-07 09:58:23 +00:00
OFF_COMMAND ( m_sprCourseSongNumber );
2004-02-14 00:39:24 +00:00
OFF_COMMAND ( m_sprStageFrame );
2003-04-13 21:17:14 +00:00
OFF_COMMAND ( m_textSongOptions );
OFF_COMMAND ( m_sprScoreFrame );
2004-07-18 17:16:57 +00:00
OFF_COMMAND ( m_BPMDisplay );
OFF_COMMAND ( m_MaxCombo );
2003-06-30 18:08:27 +00:00
if ( m_pCombinedLifeMeter )
OFF_COMMAND ( * m_pCombinedLifeMeter );
2004-05-16 12:34:02 +00:00
FOREACH_PlayerNumber ( p )
2003-04-13 21:17:14 +00:00
{
2003-06-30 18:08:27 +00:00
if ( m_pLifeMeter [ p ] )
OFF_COMMAND ( * m_pLifeMeter [ p ] );
2003-04-13 21:17:14 +00:00
if ( ! GAMESTATE -> IsPlayerEnabled ( p ) )
continue ;
OFF_COMMAND ( m_textCourseSongNumber [ p ] );
2004-01-23 06:20:28 +00:00
OFF_COMMAND ( m_textStepsDescription [ p ] );
2003-11-26 06:40:03 +00:00
if ( m_pPrimaryScoreDisplay [ p ] )
OFF_COMMAND ( * m_pPrimaryScoreDisplay [ p ] );
if ( m_pSecondaryScoreDisplay [ p ] )
OFF_COMMAND ( * m_pSecondaryScoreDisplay [ p ] );
2003-04-13 21:17:14 +00:00
OFF_COMMAND ( m_textPlayerOptions [ p ] );
2004-03-17 06:01:17 +00:00
OFF_COMMAND ( m_ActiveAttackList [ p ] );
2003-04-13 21:17:14 +00:00
OFF_COMMAND ( m_DifficultyIcon [ p ] );
2004-05-31 06:04:30 +00:00
OFF_COMMAND ( m_DifficultyMeter [ p ] );
2005-05-21 01:56:08 +00:00
OFF_COMMAND ( m_Player [ p ] );
2003-04-13 21:17:14 +00:00
}
2003-04-18 04:00:24 +00:00
2004-08-13 08:40:53 +00:00
if ( m_ShowScoreboard )
FOREACH_NSScoreBoardColumn ( sc )
OFF_COMMAND ( m_Scoreboard [ sc ] );
2004-08-13 08:24:11 +00:00
2003-06-13 02:54:58 +00:00
m_textDebug . StopTweening ();
m_textDebug . BeginTweening ( 1 / 8.f );
m_textDebug . SetDiffuse ( RageColor ( 1 , 1 , 1 , 0 ) );
2002-06-14 22:25:22 +00:00
}
2002-09-04 03:49:08 +00:00
void ScreenGameplay :: ShowOniGameOver ( PlayerNumber pn )
2002-08-01 21:55:40 +00:00
{
2005-05-09 04:07:07 +00:00
m_sprOniGameOver [ pn ]. PlayCommand ( "Die" );
2002-08-01 21:55:40 +00:00
}
2004-06-08 05:22:33 +00:00
2005-05-18 07:15:56 +00:00
2004-06-08 05:22:33 +00:00
/*
* (c) 2001-2004 Chris Danford, 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.
*/