merge Multiplayer into ScreenGameplay. This needs cleanup.
This commit is contained in:
@@ -1884,7 +1884,7 @@ public:
|
|||||||
static int IsHumanPlayer( T* p, lua_State *L ) { lua_pushboolean(L, p->IsHumanPlayer((PlayerNumber)IArg(1)) ); return 1; }
|
static int IsHumanPlayer( T* p, lua_State *L ) { lua_pushboolean(L, p->IsHumanPlayer((PlayerNumber)IArg(1)) ); return 1; }
|
||||||
static int GetPlayerDisplayName( T* p, lua_State *L ) { lua_pushstring(L, p->GetPlayerDisplayName((PlayerNumber)IArg(1)) ); return 1; }
|
static int GetPlayerDisplayName( T* p, lua_State *L ) { lua_pushstring(L, p->GetPlayerDisplayName((PlayerNumber)IArg(1)) ); return 1; }
|
||||||
static int GetMasterPlayerNumber( T* p, lua_State *L ) { lua_pushnumber(L, p->m_MasterPlayerNumber ); return 1; }
|
static int GetMasterPlayerNumber( T* p, lua_State *L ) { lua_pushnumber(L, p->m_MasterPlayerNumber ); return 1; }
|
||||||
static int GetMultiplayer( T* p, lua_State *L ) { lua_pushnumber(L, p->m_bMultiplayer); return 1; }
|
static int GetMultiplayer( T* p, lua_State *L ) { lua_pushboolean(L, p->m_bMultiplayer); return 1; }
|
||||||
static int ApplyGameCommand( T* p, lua_State *L )
|
static int ApplyGameCommand( T* p, lua_State *L )
|
||||||
{
|
{
|
||||||
PlayerNumber pn = PLAYER_INVALID;
|
PlayerNumber pn = PLAYER_INVALID;
|
||||||
|
|||||||
@@ -33,7 +33,10 @@ ScreenEditMenu.cpp ScreenEditMenu.h ScreenEnding.cpp ScreenEnding.h \
|
|||||||
ScreenEvaluation.cpp ScreenEvaluation.h ScreenExit.cpp ScreenExit.h ScreenNetEvaluation.cpp ScreenNetEvaluation.h \
|
ScreenEvaluation.cpp ScreenEvaluation.h ScreenExit.cpp ScreenExit.h ScreenNetEvaluation.cpp ScreenNetEvaluation.h \
|
||||||
ScreenNetSelectMusic.cpp ScreenNetSelectMusic.h ScreenNetSelectBase.cpp ScreenNetSelectBase.h ScreenNetRoom.cpp ScreenNetRoom.h \
|
ScreenNetSelectMusic.cpp ScreenNetSelectMusic.h ScreenNetSelectBase.cpp ScreenNetSelectBase.h ScreenNetRoom.cpp ScreenNetRoom.h \
|
||||||
ScreenEz2SelectMusic.cpp ScreenEz2SelectMusic.h ScreenEz2SelectPlayer.cpp ScreenEz2SelectPlayer.h \
|
ScreenEz2SelectMusic.cpp ScreenEz2SelectMusic.h ScreenEz2SelectPlayer.cpp ScreenEz2SelectPlayer.h \
|
||||||
ScreenGameplay.cpp ScreenGameplay.h ScreenHowToPlay.cpp ScreenHowToPlay.h \
|
ScreenGameplay.cpp ScreenGameplay.h \
|
||||||
|
ScreenGameplayMultiplayer.cpp ScreenGameplayMultiplayer.h \
|
||||||
|
ScreenGameplayNormal.cpp ScreenGameplayNormal.h \
|
||||||
|
ScreenHowToPlay.cpp ScreenHowToPlay.h \
|
||||||
ScreenInstructions.cpp ScreenInstructions.h \
|
ScreenInstructions.cpp ScreenInstructions.h \
|
||||||
ScreenJoinMultiplayer.cpp ScreenJoinMultiplayer.h \
|
ScreenJoinMultiplayer.cpp ScreenJoinMultiplayer.h \
|
||||||
ScreenJukebox.cpp ScreenJukebox.h \
|
ScreenJukebox.cpp ScreenJukebox.h \
|
||||||
|
|||||||
+654
-404
File diff suppressed because it is too large
Load Diff
@@ -1,35 +1,39 @@
|
|||||||
/* ScreenGameplay - The music plays, the notes scroll, and the Player is pressing buttons. */
|
/* ScreenGameplay - The music plays, the notes scroll, and the Player is pressing buttons. */
|
||||||
|
|
||||||
#ifndef SCREEN_GAMEPLAY_H
|
#ifndef ScreenGameplay_H
|
||||||
#define SCREEN_GAMEPLAY_H
|
#define ScreenGameplay_H
|
||||||
|
|
||||||
#include "ScreenWithMenuElements.h"
|
#include "ScreenWithMenuElements.h"
|
||||||
#include "Sprite.h"
|
#include "Sprite.h"
|
||||||
#include "Transition.h"
|
#include "Transition.h"
|
||||||
#include "BitmapText.h"
|
#include "BitmapText.h"
|
||||||
#include "Player.h"
|
|
||||||
#include "RandomSample.h"
|
#include "RandomSample.h"
|
||||||
#include "RageSound.h"
|
#include "RageSound.h"
|
||||||
#include "Background.h"
|
#include "Background.h"
|
||||||
#include "Foreground.h"
|
#include "Foreground.h"
|
||||||
#include "LifeMeter.h"
|
|
||||||
#include "ScoreDisplay.h"
|
|
||||||
#include "DifficultyIcon.h"
|
|
||||||
#include "DifficultyMeter.h"
|
|
||||||
#include "BPMDisplay.h"
|
#include "BPMDisplay.h"
|
||||||
class Inventory;
|
|
||||||
#include "BeginnerHelper.h"
|
#include "BeginnerHelper.h"
|
||||||
#include "LyricDisplay.h"
|
#include "LyricDisplay.h"
|
||||||
#include "Character.h"
|
|
||||||
#include "Attack.h"
|
#include "Attack.h"
|
||||||
#include "ActiveAttackList.h"
|
|
||||||
#include "NetworkSyncManager.h"
|
#include "NetworkSyncManager.h"
|
||||||
#include "AutoKeysounds.h"
|
#include "AutoKeysounds.h"
|
||||||
#include "ThemeMetric.h"
|
#include "ThemeMetric.h"
|
||||||
|
#include "PlayerStageStats.h"
|
||||||
|
#include "PlayerState.h"
|
||||||
|
|
||||||
|
class LyricsLoader;
|
||||||
|
class ActiveAttackList;
|
||||||
|
class CombinedLifeMeter;
|
||||||
|
class Player;
|
||||||
|
class LifeMeter;
|
||||||
|
class ScoreDisplay;
|
||||||
|
class DifficultyIcon;
|
||||||
|
class DifficultyMeter;
|
||||||
|
class Inventory;
|
||||||
|
class ScoreKeeper;
|
||||||
|
|
||||||
AutoScreenMessage( SM_NotesEnded )
|
AutoScreenMessage( SM_NotesEnded )
|
||||||
|
|
||||||
class LyricsLoader;
|
|
||||||
class ScreenGameplay : public ScreenWithMenuElements
|
class ScreenGameplay : public ScreenWithMenuElements
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -93,10 +97,9 @@ protected:
|
|||||||
NUM_DANCING_STATES
|
NUM_DANCING_STATES
|
||||||
} m_DancingState;
|
} m_DancingState;
|
||||||
bool m_bPaused;
|
bool m_bPaused;
|
||||||
|
|
||||||
GameController m_PauseController;
|
GameController m_PauseController;
|
||||||
vector<Song*> m_apSongsQueue; // size may be >1 if playing a course
|
vector<Song*> m_apSongsQueue; // size may be >1 if playing a course
|
||||||
vector<Steps*> m_vpStepsQueue[NUM_PLAYERS]; // size may be >1 if playing a course
|
|
||||||
vector<AttackArray> m_asModifiersQueue[NUM_PLAYERS];// size may be >1 if playing a course
|
|
||||||
|
|
||||||
float m_fTimeSinceLastDancingComment; // this counter is only running while STATE_DANCING
|
float m_fTimeSinceLastDancingComment; // this counter is only running while STATE_DANCING
|
||||||
|
|
||||||
@@ -110,24 +113,15 @@ protected:
|
|||||||
|
|
||||||
Sprite m_sprStaticBackground;
|
Sprite m_sprStaticBackground;
|
||||||
AutoActor m_sprLifeFrame;
|
AutoActor m_sprLifeFrame;
|
||||||
LifeMeter* m_pLifeMeter[NUM_PLAYERS];
|
|
||||||
CombinedLifeMeter* m_pCombinedLifeMeter;
|
CombinedLifeMeter* m_pCombinedLifeMeter;
|
||||||
Sprite m_sprCourseSongNumber;
|
Sprite m_sprCourseSongNumber;
|
||||||
AutoActor m_sprStageFrame;
|
AutoActor m_sprStageFrame;
|
||||||
BitmapText m_textCourseSongNumber[NUM_PLAYERS];
|
|
||||||
BitmapText m_textStepsDescription[NUM_PLAYERS];
|
|
||||||
|
|
||||||
BPMDisplay m_BPMDisplay;
|
BPMDisplay m_BPMDisplay;
|
||||||
float m_fLastBPS;
|
float m_fLastBPS;
|
||||||
|
|
||||||
Sprite m_sprScoreFrame;
|
Sprite m_sprScoreFrame;
|
||||||
ScoreDisplay* m_pPrimaryScoreDisplay[NUM_PLAYERS];
|
|
||||||
ScoreDisplay* m_pSecondaryScoreDisplay[NUM_PLAYERS];
|
|
||||||
ScoreKeeper* m_pPrimaryScoreKeeper[NUM_PLAYERS];
|
|
||||||
ScoreKeeper* m_pSecondaryScoreKeeper[NUM_PLAYERS];
|
|
||||||
BitmapText m_textPlayerOptions[NUM_PLAYERS];
|
|
||||||
BitmapText m_textSongOptions;
|
BitmapText m_textSongOptions;
|
||||||
ActiveAttackList m_ActiveAttackList[NUM_PLAYERS];
|
|
||||||
BitmapText m_Scoreboard[NUM_NSSB_CATEGORIES]; // for NSMAN, so we can have a scoreboard
|
BitmapText m_Scoreboard[NUM_NSSB_CATEGORIES]; // for NSMAN, so we can have a scoreboard
|
||||||
|
|
||||||
bool m_ShowScoreboard;
|
bool m_ShowScoreboard;
|
||||||
@@ -145,24 +139,13 @@ protected:
|
|||||||
Transition m_Failed;
|
Transition m_Failed;
|
||||||
Transition m_Extra;
|
Transition m_Extra;
|
||||||
Transition m_Toasty; // easter egg
|
Transition m_Toasty; // easter egg
|
||||||
Transition m_Win[NUM_PLAYERS];
|
|
||||||
Transition m_Draw;
|
Transition m_Draw;
|
||||||
|
|
||||||
BitmapText m_textSurviveTime; // used in extra stage
|
BitmapText m_textSurviveTime; // used in extra stage
|
||||||
|
|
||||||
Player m_Player[NUM_PLAYERS];
|
|
||||||
|
|
||||||
AutoKeysounds m_AutoKeysounds;
|
AutoKeysounds m_AutoKeysounds;
|
||||||
|
|
||||||
// used in PLAY_MODE_BATTLE
|
|
||||||
Inventory* m_pInventory[NUM_PLAYERS];
|
|
||||||
|
|
||||||
DifficultyIcon m_DifficultyIcon[NUM_PLAYERS];
|
|
||||||
DifficultyMeter m_DifficultyMeter[NUM_PLAYERS];
|
|
||||||
|
|
||||||
Sprite m_sprOniGameOver[NUM_PLAYERS];
|
|
||||||
void ShowOniGameOver( PlayerNumber pn );
|
|
||||||
|
|
||||||
RageSound m_soundBattleTrickLevel1;
|
RageSound m_soundBattleTrickLevel1;
|
||||||
RageSound m_soundBattleTrickLevel2;
|
RageSound m_soundBattleTrickLevel2;
|
||||||
RageSound m_soundBattleTrickLevel3;
|
RageSound m_soundBattleTrickLevel3;
|
||||||
@@ -175,8 +158,81 @@ protected:
|
|||||||
BeginnerHelper m_BeginnerHelper;
|
BeginnerHelper m_BeginnerHelper;
|
||||||
|
|
||||||
NoteData m_CabinetLightsNoteData;
|
NoteData m_CabinetLightsNoteData;
|
||||||
|
|
||||||
|
class PlayerInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlayerInfo();
|
||||||
|
~PlayerInfo();
|
||||||
|
|
||||||
|
void Load( PlayerNumber pn, MultiPlayer mp, bool bShowNoteField );
|
||||||
|
void LoadDummyP1();
|
||||||
|
|
||||||
|
void ShowOniGameOver();
|
||||||
|
MultiPlayer GetPlayerStateAndStageStatsIndex() { return m_pn == PLAYER_INVALID ? m_mp : (MultiPlayer)m_pn; }
|
||||||
|
PlayerState *GetPlayerState();
|
||||||
|
PlayerStageStats *GetPlayerStageStats();
|
||||||
|
PlayerNumber GetStepsAndTrailIndex() { return m_pn == PLAYER_INVALID ? PLAYER_1 : m_pn; }
|
||||||
|
bool IsEnabled();
|
||||||
|
bool IsMultiPlayer() { return m_mp != MultiPlayer_INVALID; }
|
||||||
|
CString GetName()
|
||||||
|
{
|
||||||
|
if( m_bIsDummy )
|
||||||
|
return "Dummy";
|
||||||
|
if( IsMultiPlayer() )
|
||||||
|
return MultiPlayerToString( m_mp );
|
||||||
|
else
|
||||||
|
return PlayerNumberToString( m_pn );
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerNumber m_pn;
|
||||||
|
MultiPlayer m_mp;
|
||||||
|
bool m_bIsDummy;
|
||||||
|
PlayerState m_PlayerStateDummy;
|
||||||
|
PlayerStageStats m_PlayerStageStatsDummy;
|
||||||
|
|
||||||
|
vector<Steps*> m_vpStepsQueue; // size may be >1 if playing a course
|
||||||
|
vector<AttackArray> m_asModifiersQueue;// size may be >1 if playing a course
|
||||||
|
|
||||||
|
LifeMeter *m_pLifeMeter;
|
||||||
|
BitmapText *m_ptextCourseSongNumber;
|
||||||
|
BitmapText *m_ptextStepsDescription;
|
||||||
|
|
||||||
|
ScoreDisplay *m_pPrimaryScoreDisplay;
|
||||||
|
ScoreDisplay *m_pSecondaryScoreDisplay;
|
||||||
|
ScoreKeeper *m_pPrimaryScoreKeeper;
|
||||||
|
ScoreKeeper *m_pSecondaryScoreKeeper;
|
||||||
|
BitmapText *m_ptextPlayerOptions;
|
||||||
|
ActiveAttackList *m_pActiveAttackList;
|
||||||
|
|
||||||
|
Transition *m_pWin;
|
||||||
|
|
||||||
|
Player *m_pPlayer;
|
||||||
|
|
||||||
|
// used in PLAY_MODE_BATTLE
|
||||||
|
Inventory *m_pInventory;
|
||||||
|
|
||||||
|
DifficultyIcon *m_pDifficultyIcon;
|
||||||
|
DifficultyMeter *m_pDifficultyMeter;
|
||||||
|
|
||||||
|
AutoActor m_sprOniGameOver;
|
||||||
|
};
|
||||||
|
vector<PlayerInfo> m_vPlayerInfo; // filled by SGameplay derivatives in Init
|
||||||
|
virtual void FillPlayerInfo( vector<PlayerInfo> &vPlayerInfoOut ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vector<ScreenGameplay::PlayerInfo>::iterator GetNextEnabledPlayerInfo ( vector<ScreenGameplay::PlayerInfo>::iterator iter, vector<ScreenGameplay::PlayerInfo> &v );
|
||||||
|
vector<ScreenGameplay::PlayerInfo>::iterator GetNextEnabledPlayerInfoNotDummy ( vector<ScreenGameplay::PlayerInfo>::iterator iter, vector<ScreenGameplay::PlayerInfo> &v );
|
||||||
|
vector<ScreenGameplay::PlayerInfo>::iterator GetNextEnabledPlayerNumberInfo ( vector<ScreenGameplay::PlayerInfo>::iterator iter, vector<ScreenGameplay::PlayerInfo> &v );
|
||||||
|
vector<ScreenGameplay::PlayerInfo>::iterator GetNextPlayerNumberInfo ( vector<ScreenGameplay::PlayerInfo>::iterator iter, vector<ScreenGameplay::PlayerInfo> &v );
|
||||||
|
vector<ScreenGameplay::PlayerInfo>::iterator GetNextVisiblePlayerInfo ( vector<ScreenGameplay::PlayerInfo>::iterator iter, vector<ScreenGameplay::PlayerInfo> &v );
|
||||||
|
|
||||||
|
#define FOREACH_EnabledPlayerInfo( v, pi ) for( vector<PlayerInfo>::iterator pi = GetNextEnabledPlayerInfo (v.begin()-1,v); pi != v.end(); pi = GetNextEnabledPlayerInfo(pi,v) )
|
||||||
|
#define FOREACH_EnabledPlayerInfoNotDummy( v, pi ) for( vector<PlayerInfo>::iterator pi = GetNextEnabledPlayerInfoNotDummy (v.begin()-1,v); pi != v.end(); pi = GetNextEnabledPlayerInfoNotDummy(pi,v) )
|
||||||
|
#define FOREACH_EnabledPlayerNumberInfo( v, pi ) for( vector<PlayerInfo>::iterator pi = GetNextEnabledPlayerNumberInfo (v.begin()-1,v); pi != v.end(); pi = GetNextEnabledPlayerNumberInfo(pi,v) )
|
||||||
|
#define FOREACH_PlayerNumberInfo( v, pi ) for( vector<PlayerInfo>::iterator pi = GetNextPlayerNumberInfo (v.begin()-1,v); pi != v.end(); pi = GetNextPlayerNumberInfo(pi,v) )
|
||||||
|
#define FOREACH_VisiblePlayerInfo( v, pi ) for( vector<PlayerInfo>::iterator pi = GetNextVisiblePlayerInfo (v.begin()-1,v); pi != v.end(); pi = GetNextVisiblePlayerInfo(pi,v) )
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,644 +1,36 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "ScreenGameplayMultiplayer.h"
|
#include "ScreenGameplayMultiplayer.h"
|
||||||
#include "ThemeMetric.h"
|
|
||||||
#include "GameSoundManager.h"
|
|
||||||
#include "GameState.h"
|
|
||||||
#include "Foreach.h"
|
|
||||||
#include "Course.h"
|
|
||||||
#include "StatsManager.h"
|
|
||||||
#include "ScoreKeeperMAX2.h"
|
|
||||||
#include "ScoreKeeperRave.h"
|
|
||||||
#include "ScreenDimensions.h"
|
|
||||||
#include "ScreenManager.h"
|
|
||||||
#include "ScoreDisplayPercentage.h"
|
|
||||||
#include "ScoreDisplayNormal.h"
|
|
||||||
#include "ScoreDisplayOni.h"
|
|
||||||
#include "song.h"
|
|
||||||
#include "Steps.h"
|
|
||||||
#include "NoteDataUtil.h"
|
|
||||||
#include "RageLog.h"
|
|
||||||
#include "Style.h"
|
|
||||||
#include "PlayerState.h"
|
|
||||||
#include "InputMapper.h"
|
|
||||||
#include "ActorUtil.h"
|
|
||||||
#include "PrefsManager.h"
|
|
||||||
|
|
||||||
// received while STATE_DANCING
|
|
||||||
AutoScreenMessage( SM_NotesEnded )
|
|
||||||
AutoScreenMessage( SM_Ready )
|
|
||||||
AutoScreenMessage( SM_GoToStateAfterCleared )
|
|
||||||
AutoScreenMessage( SM_GoToScreenAfterBack )
|
|
||||||
|
|
||||||
|
|
||||||
REGISTER_SCREEN_CLASS( ScreenGameplayMultiplayer );
|
REGISTER_SCREEN_CLASS( ScreenGameplayMultiplayer );
|
||||||
ScreenGameplayMultiplayer::ScreenGameplayMultiplayer( CString sName, bool bDemonstration ) : Screen(sName)
|
|
||||||
|
ScreenGameplayMultiplayer::ScreenGameplayMultiplayer( CString sName ) : ScreenGameplay(sName)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::Init()
|
void ScreenGameplayMultiplayer::Init()
|
||||||
{
|
{
|
||||||
Screen::Init();
|
ScreenGameplay::Init();
|
||||||
|
|
||||||
m_pSoundMusic = NULL;
|
// force the dummy player into autoplay
|
||||||
|
PlayerInfo &pi = m_vPlayerInfo.back();
|
||||||
/* We do this ourself. */
|
pi.LoadDummyP1(); // dummy autoplay NoteField
|
||||||
SOUND->HandleSongTimer( false );
|
}
|
||||||
|
|
||||||
//need to initialize these before checking for demonstration mode
|
|
||||||
//otherwise destructor will try to delete possibly invalid pointers
|
|
||||||
|
|
||||||
FOREACH_MultiPlayer(p)
|
|
||||||
{
|
|
||||||
m_pPrimaryScoreDisplay[p] = NULL;
|
|
||||||
m_pPrimaryScoreKeeper[p] = NULL;
|
|
||||||
|
|
||||||
m_PlayerState[p].m_PlayerNumber = GAMESTATE->m_MasterPlayerNumber;
|
|
||||||
m_PlayerState[p].m_PlayerController = PC_HUMAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL )
|
|
||||||
return; // ScreenDemonstration will move us to the next scren. We just need to survive for one update without crashing.
|
|
||||||
|
|
||||||
/* Save selected options before we change them. */
|
|
||||||
GAMESTATE->StoreSelectedOptions();
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
GAMESTATE->ResetStageStatistics();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// fill in difficulty of CPU players with that of the first human player
|
|
||||||
FOREACH_PotentialCpuPlayer(p)
|
|
||||||
GAMESTATE->m_pCurSteps[p].Set( GAMESTATE->m_pCurSteps[ GAMESTATE->GetFirstHumanPlayer() ] );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// fill in m_vpSongsQueue, m_vpStepsQueue, m_asModifiersQueue
|
|
||||||
//
|
|
||||||
if( GAMESTATE->IsCourseMode() )
|
|
||||||
{
|
|
||||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
|
||||||
ASSERT( pCourse );
|
|
||||||
|
|
||||||
|
|
||||||
m_vpSongsQueue.clear();
|
|
||||||
PlayerNumber pnMaster = GAMESTATE->m_MasterPlayerNumber;
|
|
||||||
Trail *pTrail = GAMESTATE->m_pCurTrail[pnMaster];
|
|
||||||
FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e )
|
|
||||||
{
|
|
||||||
m_vpSongsQueue.push_back( e->pSong );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_vpStepsQueue.clear();
|
|
||||||
FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e )
|
|
||||||
{
|
|
||||||
m_vpStepsQueue.push_back( e->pSteps );
|
|
||||||
m_vModifiersQueue.push_back( AttackArray() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_vpSongsQueue.push_back( GAMESTATE->m_pCurSong );
|
|
||||||
|
|
||||||
{
|
|
||||||
m_vpStepsQueue.push_back( GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber] );
|
|
||||||
m_vModifiersQueue.push_back( AttackArray() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called once per stage (single song or single course). */
|
|
||||||
GAMESTATE->BeginStage();
|
|
||||||
|
|
||||||
STATSMAN->m_CurStageStats.playMode = GAMESTATE->m_PlayMode;
|
|
||||||
STATSMAN->m_CurStageStats.pStyle = GAMESTATE->m_pCurStyle;
|
|
||||||
|
|
||||||
{
|
|
||||||
ASSERT( !m_vpStepsQueue.empty() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( GAMESTATE->IsExtraStage() )
|
|
||||||
STATSMAN->m_CurStageStats.StageType = StageStats::STAGE_EXTRA;
|
|
||||||
else if( GAMESTATE->IsExtraStage2() )
|
|
||||||
STATSMAN->m_CurStageStats.StageType = StageStats::STAGE_EXTRA2;
|
|
||||||
else
|
|
||||||
STATSMAN->m_CurStageStats.StageType = StageStats::STAGE_NORMAL;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Init ScoreKeepers
|
|
||||||
//
|
|
||||||
|
|
||||||
|
void ScreenGameplayMultiplayer::FillPlayerInfo( vector<PlayerInfo> &vPlayerInfoOut )
|
||||||
|
{
|
||||||
|
vPlayerInfoOut.resize( NUM_MultiPlayer+1 );
|
||||||
FOREACH_MultiPlayer( p )
|
FOREACH_MultiPlayer( p )
|
||||||
{
|
vPlayerInfoOut[p].Load( PLAYER_INVALID, p, false );
|
||||||
switch( PREFSMAN->m_ScoringType )
|
PlayerInfo &pi = vPlayerInfoOut.back();
|
||||||
{
|
pi.LoadDummyP1(); // dummy autoplay NoteField
|
||||||
case PrefsManager::SCORING_MAX2:
|
};
|
||||||
case PrefsManager::SCORING_5TH:
|
|
||||||
m_pPrimaryScoreKeeper[p] = new ScoreKeeperMAX2(
|
|
||||||
&m_PlayerState[p],
|
|
||||||
&m_PlayerStageStats[p] );
|
|
||||||
m_pPrimaryScoreKeeper[p]->Load(
|
|
||||||
m_vpSongsQueue,
|
|
||||||
m_vpStepsQueue,
|
|
||||||
m_vModifiersQueue );
|
|
||||||
break;
|
|
||||||
default: ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Background.SetDrawOrder( DRAW_ORDER_BEFORE_EVERYTHING );
|
|
||||||
this->AddChild( &m_Background );
|
|
||||||
|
|
||||||
m_Foreground.SetDrawOrder( DRAW_ORDER_AFTER_EVERYTHING ); // on top of everything else, including transitions
|
|
||||||
this->AddChild( &m_Foreground );
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
float fPlayerX = SCREEN_CENTER_X;
|
|
||||||
|
|
||||||
/* 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) */
|
|
||||||
if( PREFSMAN->m_bSoloSingle &&
|
|
||||||
GAMESTATE->m_PlayMode != PLAY_MODE_BATTLE &&
|
|
||||||
GAMESTATE->m_PlayMode != PLAY_MODE_RAVE &&
|
|
||||||
GAMESTATE->GetCurrentStyle()->m_StyleType == ONE_PLAYER_ONE_SIDE )
|
|
||||||
fPlayerX = SCREEN_CENTER_X;
|
|
||||||
|
|
||||||
m_AutoPlayer.SetName( "Player" );
|
|
||||||
m_AutoPlayer.SetX( fPlayerX );
|
|
||||||
m_AutoPlayer.SetY( SCREEN_CENTER_Y );
|
|
||||||
this->AddChild( &m_AutoPlayer );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FOREACH_MultiPlayer( p )
|
|
||||||
{
|
|
||||||
this->AddChild( &m_HumanPlayer[p] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FOREACH_MultiPlayer( p )
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// primary score display
|
|
||||||
//
|
|
||||||
switch( GAMESTATE->m_PlayMode )
|
|
||||||
{
|
|
||||||
case PLAY_MODE_REGULAR:
|
|
||||||
case PLAY_MODE_NONSTOP:
|
|
||||||
case PLAY_MODE_BATTLE:
|
|
||||||
case PLAY_MODE_RAVE:
|
|
||||||
if( PREFSMAN->m_bPercentageScoring )
|
|
||||||
m_pPrimaryScoreDisplay[p] = new ScoreDisplayPercentage;
|
|
||||||
else
|
|
||||||
m_pPrimaryScoreDisplay[p] = new ScoreDisplayNormal;
|
|
||||||
break;
|
|
||||||
case PLAY_MODE_ONI:
|
|
||||||
case PLAY_MODE_ENDLESS:
|
|
||||||
m_pPrimaryScoreDisplay[p] = new ScoreDisplayOni;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pPrimaryScoreDisplay[p]->Init( &m_PlayerState[p] );
|
|
||||||
m_pPrimaryScoreDisplay[p]->SetName( ssprintf("ScoreP%d",p+1) );
|
|
||||||
SET_XY( *m_pPrimaryScoreDisplay[p] );
|
|
||||||
this->AddChild( m_pPrimaryScoreDisplay[p] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
m_In.Load( THEME->GetPathB(m_sName,"in") );
|
|
||||||
m_In.SetDrawOrder( DRAW_ORDER_TRANSITIONS );
|
|
||||||
this->AddChild( &m_In );
|
|
||||||
|
|
||||||
m_Out.Load( THEME->GetPathB(m_sName,"out") );
|
|
||||||
m_Out.SetDrawOrder( DRAW_ORDER_TRANSITIONS );
|
|
||||||
this->AddChild( &m_Out );
|
|
||||||
|
|
||||||
m_Cancel.Load( THEME->GetPathB(m_sName,"cancel") );
|
|
||||||
m_Cancel.SetDrawOrder( DRAW_ORDER_TRANSITIONS ); // on top of everything else
|
|
||||||
this->AddChild( &m_Cancel );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* LoadNextSong first, since that positions some elements which need to be
|
|
||||||
* positioned before we TweenOursOnScreen. */
|
|
||||||
LoadNextSong();
|
|
||||||
|
|
||||||
TweenOursOnScreen();
|
|
||||||
|
|
||||||
this->SortByDrawOrder();
|
|
||||||
|
|
||||||
// Get the transitions rolling on the first update.
|
|
||||||
// We can't do this in the constructor because ScreenGameplayMultiplayer is constructed
|
|
||||||
// in the middle of ScreenStage.
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenGameplayMultiplayer::~ScreenGameplayMultiplayer()
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
FOREACH_MultiPlayer( p )
|
|
||||||
{
|
|
||||||
SAFE_DELETE( m_pPrimaryScoreDisplay[p] );
|
|
||||||
SAFE_DELETE( m_pPrimaryScoreKeeper[p] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_pSoundMusic )
|
|
||||||
m_pSoundMusic->StopPlaying();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScreenGameplayMultiplayer::IsLastSong()
|
|
||||||
{
|
|
||||||
if( GAMESTATE->m_pCurCourse && GAMESTATE->m_pCurCourse->m_bRepeat )
|
|
||||||
return false;
|
|
||||||
return GAMESTATE->GetCourseSongIndex()+1 == (int)m_vpSongsQueue.size(); // GetCourseSongIndex() is 0-based but size() is not
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::SetupSong( MultiPlayer p, int iSongIndex )
|
|
||||||
{
|
|
||||||
/* 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[GAMESTATE->m_MasterPlayerNumber]->m_fLastDrawnBeat = -100;
|
|
||||||
GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber].Set( m_vpStepsQueue[iSongIndex] );
|
|
||||||
|
|
||||||
/* Load new NoteData into Player. Do this before
|
|
||||||
* RebuildPlayerOptionsFromActiveAttacks or else transform mods will get
|
|
||||||
* propogated to GAMESTATE->m_AutoPlayerOptions 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[GAMESTATE->m_MasterPlayerNumber]->GetNoteData( originalNoteData );
|
|
||||||
|
|
||||||
const Style* pStyle = GAMESTATE->GetCurrentStyle();
|
|
||||||
NoteData ndTransformed;
|
|
||||||
pStyle->GetTransformedNoteDataForStyle( GAMESTATE->m_MasterPlayerNumber, originalNoteData, ndTransformed );
|
|
||||||
|
|
||||||
// load player
|
|
||||||
{
|
|
||||||
NoteData nd = ndTransformed;
|
|
||||||
NoteDataUtil::RemoveAllTapsOfType( nd, TapNote::autoKeysound );
|
|
||||||
m_AutoPlayer.Init(
|
|
||||||
"Player",
|
|
||||||
GAMESTATE->m_pPlayerState[ GAMESTATE->m_MasterPlayerNumber ],
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL );
|
|
||||||
m_AutoPlayer.Load( nd );
|
|
||||||
|
|
||||||
m_HumanPlayer[p].Init(
|
|
||||||
"Player",
|
|
||||||
&m_PlayerState[p],
|
|
||||||
&m_PlayerStageStats[p],
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
m_pPrimaryScoreDisplay[p],
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
m_pPrimaryScoreKeeper[p],
|
|
||||||
NULL );
|
|
||||||
m_HumanPlayer[p].Load( nd );
|
|
||||||
}
|
|
||||||
|
|
||||||
// load auto keysounds
|
|
||||||
{
|
|
||||||
NoteData nd = ndTransformed;
|
|
||||||
NoteDataUtil::RemoveAllTapsExceptForType( nd, TapNote::autoKeysound );
|
|
||||||
m_AutoKeysounds.Load( GAMESTATE->m_MasterPlayerNumber, nd );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::LoadNextSong()
|
|
||||||
{
|
|
||||||
GAMESTATE->ResetMusicStatistics();
|
|
||||||
|
|
||||||
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
|
|
||||||
iPlaySongIndex %= m_vpSongsQueue.size();
|
|
||||||
GAMESTATE->m_pCurSong.Set( m_vpSongsQueue[iPlaySongIndex] );
|
|
||||||
STATSMAN->m_CurStageStats.vpPlayedSongs.push_back( GAMESTATE->m_pCurSong );
|
|
||||||
|
|
||||||
// No need to do this here. We do it in SongFinished().
|
|
||||||
//GAMESTATE->RemoveAllActiveAttacks();
|
|
||||||
|
|
||||||
// Restore the player's originally selected options.
|
|
||||||
GAMESTATE->RestoreSelectedOptions();
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
Steps* pSteps = GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber];
|
|
||||||
|
|
||||||
STATSMAN->m_CurStageStats.m_player[GAMESTATE->m_MasterPlayerNumber].vpPlayedSteps.push_back( pSteps );
|
|
||||||
|
|
||||||
FOREACH_MultiPlayer( p )
|
|
||||||
{
|
|
||||||
SetupSong( p, iPlaySongIndex );
|
|
||||||
|
|
||||||
ASSERT( GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber] );
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
m_pPrimaryScoreKeeper[p]->OnNextSong(
|
|
||||||
GAMESTATE->GetCourseSongIndex(),
|
|
||||||
GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber],
|
|
||||||
&m_HumanPlayer[p].m_NoteData );
|
|
||||||
}
|
|
||||||
|
|
||||||
GAMESTATE->m_pPlayerState[GAMESTATE->m_MasterPlayerNumber]->m_PlayerController = PC_AUTOPLAY;
|
|
||||||
|
|
||||||
m_AutoKeysounds.FinishLoading();
|
|
||||||
m_pSoundMusic = m_AutoKeysounds.GetSound();
|
|
||||||
|
|
||||||
{
|
|
||||||
/* BeginnerHelper disabled/failed to load. */
|
|
||||||
m_Background.LoadFromSong( GAMESTATE->m_pCurSong );
|
|
||||||
/* 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. */
|
|
||||||
m_Background.FadeToActualBrightness();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Foreground.LoadFromSong( GAMESTATE->m_pCurSong );
|
|
||||||
}
|
|
||||||
|
|
||||||
float ScreenGameplayMultiplayer::StartPlayingSong(float MinTimeToNotes, float MinTimeToMusic)
|
|
||||||
{
|
|
||||||
ASSERT(MinTimeToNotes >= 0);
|
|
||||||
ASSERT(MinTimeToMusic >= 0);
|
|
||||||
|
|
||||||
/* XXX: We want the first beat *in use*, so we don't delay needlessly. */
|
|
||||||
const float fFirstBeat = GAMESTATE->m_pCurSong->m_fFirstBeat;
|
|
||||||
const float fFirstSecond = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat( fFirstBeat );
|
|
||||||
float fStartSecond = fFirstSecond - MinTimeToNotes;
|
|
||||||
|
|
||||||
fStartSecond = min(fStartSecond, -MinTimeToMusic);
|
|
||||||
|
|
||||||
RageSoundParams p;
|
|
||||||
p.AccurateSync = true;
|
|
||||||
p.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
|
|
||||||
p.StopMode = RageSoundParams::M_CONTINUE;
|
|
||||||
p.m_StartSecond = fStartSecond;
|
|
||||||
|
|
||||||
|
|
||||||
m_pSoundMusic->Play( &p );
|
|
||||||
|
|
||||||
/* Make sure GAMESTATE->m_fMusicSeconds is set up. */
|
|
||||||
GAMESTATE->m_fMusicSeconds = -5000;
|
|
||||||
UpdateSongPosition(0);
|
|
||||||
|
|
||||||
ASSERT( GAMESTATE->m_fMusicSeconds > -4000 ); /* make sure the "fake timer" code doesn't trigger */
|
|
||||||
|
|
||||||
/* Return the amount of time until the first beat. */
|
|
||||||
return fFirstSecond - fStartSecond;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::UpdateSongPosition( float fDeltaTime )
|
|
||||||
{
|
|
||||||
if( !m_pSoundMusic->IsPlaying() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
RageTimer tm;
|
|
||||||
const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm );
|
|
||||||
const float fAdjust = SOUND->GetFrameTimingAdjustment( fDeltaTime );
|
|
||||||
GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_Timing, tm+fAdjust );
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::Update( float fDeltaTime )
|
|
||||||
{
|
|
||||||
if( GAMESTATE->m_pCurSong == NULL )
|
|
||||||
{
|
|
||||||
/* ScreenDemonstration will move us to the next screen. We just need to
|
|
||||||
* survive for one update without crashing. We need to call Screen::Update
|
|
||||||
* to make sure we receive the next-screen message. */
|
|
||||||
Screen::Update( fDeltaTime );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_bFirstUpdate )
|
|
||||||
{
|
|
||||||
SOUND->PlayOnceFromAnnouncer( "gameplay intro" ); // crowd cheer
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the transitions rolling
|
|
||||||
//
|
|
||||||
StartPlayingSong( 0, 0 ); // *kick* (no transitions)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UpdateSongPosition( fDeltaTime );
|
|
||||||
|
|
||||||
Screen::Update( fDeltaTime );
|
|
||||||
|
|
||||||
/* This happens if ScreenDemonstration::HandleScreenMessage sets a new screen when
|
|
||||||
* PREFSMAN->m_bDelayedScreenLoad. */
|
|
||||||
if( GAMESTATE->m_pCurSong == NULL )
|
|
||||||
return;
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
m_AutoKeysounds.Update(fDeltaTime);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check for end of song
|
|
||||||
//
|
|
||||||
float fSecondsToStop = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat );
|
|
||||||
|
|
||||||
/* Make sure we keep going long enough to register a miss for the last note. */
|
|
||||||
fSecondsToStop += m_AutoPlayer.GetMaxStepDistanceSeconds();
|
|
||||||
|
|
||||||
if( GAMESTATE->m_fMusicSeconds > fSecondsToStop && !m_Out.IsTransitioning() )
|
|
||||||
this->HandleScreenMessage( SM_NotesEnded );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
|
|
||||||
{
|
|
||||||
//LOG->Trace( "ScreenGameplayMultiplayer::Input()" );
|
|
||||||
|
|
||||||
if( type == IET_LEVEL_CHANGED )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( MenuI.IsValid() && !m_Cancel.IsTransitioning() )
|
|
||||||
{
|
|
||||||
if( MenuI.button == MENU_BUTTON_BACK &&
|
|
||||||
((!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)) )
|
|
||||||
{
|
|
||||||
/* I had battle mode back out on me mysteriously once. -glenn */
|
|
||||||
LOG->Trace("Player %i went back", MenuI.player+1);
|
|
||||||
|
|
||||||
/* Hmm. There are a bunch of subtly different ways we can
|
|
||||||
* tween out:
|
|
||||||
* 1. Keep rendering the song, and keep it moving. This might
|
|
||||||
* cause problems if the cancel and the end of the song overlap.
|
|
||||||
* 2. Stop the song completely, so all song motion under the tween
|
|
||||||
* ceases.
|
|
||||||
* 3. Stop the song, but keep effects (eg. Drunk) running.
|
|
||||||
* 4. Don't display the song at all.
|
|
||||||
*
|
|
||||||
* We're doing #3. I'm not sure which is best.
|
|
||||||
*/
|
|
||||||
|
|
||||||
m_pSoundMusic->StopPlaying();
|
|
||||||
|
|
||||||
this->ClearMessageQueue();
|
|
||||||
m_Cancel.StartTransitioning( SM_GoToScreenAfterBack );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nothing below cares about releases. */
|
|
||||||
if(type == IET_RELEASE) return;
|
|
||||||
|
|
||||||
// Handle special keys to adjust the offset
|
|
||||||
if( DeviceI.device == DEVICE_KEYBOARD )
|
|
||||||
{
|
|
||||||
switch( DeviceI.button )
|
|
||||||
{
|
|
||||||
case KEY_F5:
|
|
||||||
this->HandleScreenMessage( SM_NotesEnded );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Translate input and sent to the appropriate player. Assume that all
|
|
||||||
// joystick devices are mapped the same as the master player.
|
|
||||||
if( DeviceI.device >= DEVICE_JOY1 &&
|
|
||||||
DeviceI.device < DEVICE_JOY1 + NUM_JOYSTICKS )
|
|
||||||
{
|
|
||||||
DeviceInput _DeviceI = DeviceI;
|
|
||||||
_DeviceI.device = DEVICE_JOY1;
|
|
||||||
GameInput _GameI;
|
|
||||||
INPUTMAPPER->DeviceToGame( _DeviceI, _GameI );
|
|
||||||
|
|
||||||
if( GameI.IsValid() )
|
|
||||||
{
|
|
||||||
StyleInput _StyleI;
|
|
||||||
INPUTMAPPER->GameToStyle( _GameI, _StyleI );
|
|
||||||
|
|
||||||
MultiPlayer mp = (MultiPlayer)(DeviceI.device - DEVICE_JOY1);
|
|
||||||
|
|
||||||
ASSERT( mp>=0 && mp<NUM_MultiPlayer );
|
|
||||||
m_HumanPlayer[mp].Step( _StyleI.col, DeviceI.ts );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::StageFinished( bool bBackedOut )
|
|
||||||
{
|
|
||||||
if( GAMESTATE->IsCourseMode() && GAMESTATE->m_PlayMode != PLAY_MODE_ENDLESS )
|
|
||||||
{
|
|
||||||
LOG->Trace("Stage finished at index %i/%i", GAMESTATE->GetCourseSongIndex(), (int) m_vpSongsQueue.size() );
|
|
||||||
/* +1 to skip the current song; that's done already. */
|
|
||||||
for( unsigned iPlaySongIndex = GAMESTATE->GetCourseSongIndex()+1;
|
|
||||||
iPlaySongIndex < m_vpSongsQueue.size(); ++iPlaySongIndex )
|
|
||||||
{
|
|
||||||
LOG->Trace("Running stats for %i", iPlaySongIndex );
|
|
||||||
FOREACH_MultiPlayer(p)
|
|
||||||
{
|
|
||||||
SetupSong( p, iPlaySongIndex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// save current stage stats
|
|
||||||
if( !bBackedOut )
|
|
||||||
STATSMAN->m_vPlayedStageStats.push_back( STATSMAN->m_CurStageStats );
|
|
||||||
|
|
||||||
/* Reset options. */
|
|
||||||
GAMESTATE->RestoreSelectedOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::HandleScreenMessage( const ScreenMessage SM )
|
|
||||||
{
|
|
||||||
CHECKPOINT_M( ssprintf("HandleScreenMessage(%i)", SM) );
|
|
||||||
if( SM == SM_Ready )
|
|
||||||
{
|
|
||||||
GAMESTATE->m_bPastHereWeGo = true;
|
|
||||||
}
|
|
||||||
else if( SM == SM_NotesEnded )
|
|
||||||
{
|
|
||||||
m_Out.StartTransitioning( SM_GoToStateAfterCleared );
|
|
||||||
}
|
|
||||||
else if( SM == SM_GoToScreenAfterBack )
|
|
||||||
{
|
|
||||||
StageFinished( true );
|
|
||||||
|
|
||||||
GAMESTATE->CancelStage();
|
|
||||||
|
|
||||||
SCREENMAN->PostMessageToTopScreen( SM_GoToPrevScreen, 0 );
|
|
||||||
}
|
|
||||||
else if( SM == SM_GoToStateAfterCleared )
|
|
||||||
{
|
|
||||||
StageFinished( false );
|
|
||||||
|
|
||||||
SCREENMAN->PostMessageToTopScreen( SM_GoToNextScreen, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
Screen::HandleScreenMessage( SM );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::TweenOursOnScreen()
|
|
||||||
{
|
|
||||||
FOREACH_MultiPlayer(p)
|
|
||||||
{
|
|
||||||
if( m_pPrimaryScoreDisplay[p] )
|
|
||||||
ON_COMMAND( *m_pPrimaryScoreDisplay[p] );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_In.StartTransitioning( SM_Ready );
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenGameplayMultiplayer::TweenOursOffScreen()
|
|
||||||
{
|
|
||||||
FOREACH_MultiPlayer(p)
|
|
||||||
{
|
|
||||||
if( m_pPrimaryScoreDisplay[p] )
|
|
||||||
OFF_COMMAND( *m_pPrimaryScoreDisplay[p] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// lua end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2001-2004 Chris Danford, Glenn Maynard
|
* (c) 2005 Chris Danford
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|||||||
@@ -1,76 +1,24 @@
|
|||||||
/* ScreenGameplayMultiplayer */
|
/* ScreenGameplayMultiplayer - The music plays, the notes scroll, and the Player is pressing buttons. */
|
||||||
|
|
||||||
#ifndef ScreenGameplayMultiplayer_H
|
#ifndef ScreenGameplayMultiplayer_H
|
||||||
#define ScreenGameplayMultiplayer_H
|
#define ScreenGameplayMultiplayer_H
|
||||||
|
|
||||||
#include "Screen.h"
|
#include "ScreenGameplay.h"
|
||||||
#include "Background.h"
|
|
||||||
#include "Foreground.h"
|
|
||||||
#include "ScoreDisplay.h"
|
|
||||||
#include "Transition.h"
|
|
||||||
#include "Player.h"
|
|
||||||
#include "EnumHelper.h"
|
|
||||||
#include "AutoKeysounds.h"
|
|
||||||
#include "PlayerState.h"
|
|
||||||
#include "StageStats.h"
|
|
||||||
|
|
||||||
class Song;
|
class LyricsLoader;
|
||||||
class Steps;
|
class ScreenGameplayMultiplayer : public ScreenGameplay
|
||||||
|
|
||||||
class ScreenGameplayMultiplayer : public Screen
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScreenGameplayMultiplayer( CString sName, bool bDemonstration = false );
|
ScreenGameplayMultiplayer( CString sName );
|
||||||
virtual void Init();
|
void Init();
|
||||||
virtual ~ScreenGameplayMultiplayer();
|
virtual void FillPlayerInfo( vector<ScreenGameplay::PlayerInfo> &vPlayerInfoOut );
|
||||||
|
|
||||||
virtual void Update( float fDeltaTime );
|
|
||||||
virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI );
|
|
||||||
virtual void HandleScreenMessage( const ScreenMessage SM );
|
|
||||||
|
|
||||||
virtual bool UsesBackground() const { return false; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void TweenOursOnScreen();
|
|
||||||
void TweenOursOffScreen();
|
|
||||||
|
|
||||||
bool IsLastSong();
|
|
||||||
void SetupSong( MultiPlayer p, int iSongIndex );
|
|
||||||
void LoadNextSong();
|
|
||||||
float StartPlayingSong(float MinTimeToNotes, float MinTimeToMusic);
|
|
||||||
void ShowSavePrompt( ScreenMessage SM_SendWhenDone );
|
|
||||||
|
|
||||||
void UpdateSongPosition( float fDeltaTime );
|
|
||||||
void StageFinished( bool bBackedOut );
|
|
||||||
|
|
||||||
vector<Song*> m_vpSongsQueue;
|
|
||||||
vector<Steps*> m_vpStepsQueue;
|
|
||||||
vector<AttackArray> m_vModifiersQueue;
|
|
||||||
|
|
||||||
Background m_Background;
|
|
||||||
Foreground m_Foreground;
|
|
||||||
|
|
||||||
ScoreDisplay* m_pPrimaryScoreDisplay[NUM_MultiPlayer];
|
|
||||||
ScoreKeeper* m_pPrimaryScoreKeeper[NUM_MultiPlayer];
|
|
||||||
|
|
||||||
Transition m_In;
|
|
||||||
Transition m_Out;
|
|
||||||
Transition m_Cancel;
|
|
||||||
|
|
||||||
Player m_AutoPlayer;
|
|
||||||
PlayerState m_PlayerState[NUM_MultiPlayer];
|
|
||||||
PlayerStageStats m_PlayerStageStats[NUM_MultiPlayer];
|
|
||||||
Player m_HumanPlayer[NUM_MultiPlayer];
|
|
||||||
|
|
||||||
AutoKeysounds m_AutoKeysounds;
|
|
||||||
RageSound *m_pSoundMusic;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2001-2004 Chris Danford, Glenn Maynard
|
* (c) 2005 Chris Danford
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "ScreenGameplayNormal.h"
|
||||||
|
|
||||||
|
|
||||||
|
REGISTER_SCREEN_CLASS( ScreenGameplayNormal );
|
||||||
|
|
||||||
|
ScreenGameplayNormal::ScreenGameplayNormal( CString sName ) : ScreenGameplay(sName)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenGameplayNormal::FillPlayerInfo( vector<PlayerInfo> &vPlayerInfoOut )
|
||||||
|
{
|
||||||
|
vPlayerInfoOut.resize( NUM_PLAYERS );
|
||||||
|
FOREACH_PlayerNumber( p )
|
||||||
|
vPlayerInfoOut[p].Load( p, MultiPlayer_INVALID, true );
|
||||||
|
};
|
||||||
|
|
||||||
|
// lua end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (c) 2005 Chris Danford
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* ScreenGameplay - The music plays, the notes scroll, and the Player is pressing buttons. */
|
||||||
|
|
||||||
|
#ifndef ScreenGameplayNormal_H
|
||||||
|
#define ScreenGameplayNormal_H
|
||||||
|
|
||||||
|
#include "ScreenGameplay.h"
|
||||||
|
|
||||||
|
class LyricsLoader;
|
||||||
|
class ScreenGameplayNormal : public ScreenGameplay
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScreenGameplayNormal( CString sName );
|
||||||
|
virtual void FillPlayerInfo( vector<ScreenGameplay::PlayerInfo> &vPlayerInfoOut );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (c) 2005 Chris Danford
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
@@ -166,7 +166,7 @@ void ScreenJukebox::SetSong()
|
|||||||
return; // didn't find a song
|
return; // didn't find a song
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenJukebox::ScreenJukebox( CString sName ) : ScreenGameplay( sName )
|
ScreenJukebox::ScreenJukebox( CString sName ) : ScreenGameplayNormal( sName )
|
||||||
{
|
{
|
||||||
LOG->Trace( "ScreenJukebox::ScreenJukebox()" );
|
LOG->Trace( "ScreenJukebox::ScreenJukebox()" );
|
||||||
m_bDemonstration = false;
|
m_bDemonstration = false;
|
||||||
@@ -307,19 +307,19 @@ void ScreenJukebox::InitSongQueues()
|
|||||||
if( i != iIndexToKeep )
|
if( i != iIndexToKeep )
|
||||||
{
|
{
|
||||||
m_apSongsQueue.erase( m_apSongsQueue.begin()+i );
|
m_apSongsQueue.erase( m_apSongsQueue.begin()+i );
|
||||||
FOREACH_EnabledPlayer(p)
|
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
|
||||||
{
|
{
|
||||||
m_vpStepsQueue[p].erase( m_vpStepsQueue[p].begin()+i );
|
pi->m_vpStepsQueue.erase( pi->m_vpStepsQueue.begin()+i );
|
||||||
m_asModifiersQueue[p].erase( m_asModifiersQueue[p].begin()+i );
|
pi->m_asModifiersQueue.erase( pi->m_asModifiersQueue.begin()+i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_M( m_apSongsQueue.size() == 1, ssprintf("%i", (int) m_apSongsQueue.size()) );
|
ASSERT_M( m_apSongsQueue.size() == 1, ssprintf("%i", (int) m_apSongsQueue.size()) );
|
||||||
FOREACH_PlayerNumber(p)
|
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
|
||||||
{
|
{
|
||||||
ASSERT_M( m_vpStepsQueue[p].size() == 1, ssprintf("%i", (int) m_vpStepsQueue[p].size()) );
|
ASSERT_M( pi->m_vpStepsQueue.size() == 1, ssprintf("%i", (int) pi->m_vpStepsQueue.size()) );
|
||||||
ASSERT_M( m_asModifiersQueue[p].size() == 1, ssprintf("%i", (int) m_asModifiersQueue[p].size()) );
|
ASSERT_M( pi->m_asModifiersQueue.size() == 1, ssprintf("%i", (int) pi->m_asModifiersQueue.size()) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
#ifndef ScreenJukebox_H
|
#ifndef ScreenJukebox_H
|
||||||
#define ScreenJukebox_H
|
#define ScreenJukebox_H
|
||||||
|
|
||||||
#include "ScreenGameplay.h"
|
#include "ScreenGameplayNormal.h"
|
||||||
#include "Sprite.h"
|
#include "Sprite.h"
|
||||||
class CourseEntry;
|
class CourseEntry;
|
||||||
|
|
||||||
class ScreenJukebox : public ScreenGameplay
|
class ScreenJukebox : public ScreenGameplayNormal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScreenJukebox( CString sName );
|
ScreenJukebox( CString sName );
|
||||||
|
|||||||
@@ -357,6 +357,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
|||||||
<File
|
<File
|
||||||
RelativePath="ScreenGameplayMultiplayer.h">
|
RelativePath="ScreenGameplayMultiplayer.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ScreenGameplayNormal.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ScreenGameplayNormal.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="ScreenHowToPlay.cpp">
|
RelativePath="ScreenHowToPlay.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@@ -2640,6 +2640,14 @@ SOURCE=.\ScreenGameplayMultiplayer.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ScreenGameplayNormal.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ScreenGameplayNormal.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\ScreenHowToPlay.cpp
|
SOURCE=.\ScreenHowToPlay.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -337,6 +337,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
|||||||
<File
|
<File
|
||||||
RelativePath="ScreenGameplayMultiplayer.h">
|
RelativePath="ScreenGameplayMultiplayer.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="ScreenGameplayNormal.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="ScreenGameplayNormal.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="ScreenHowToPlay.cpp">
|
RelativePath="ScreenHowToPlay.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
Reference in New Issue
Block a user