Separate styles for players. Notefields positioned between margins. Edit mode works for kickbox.

This commit is contained in:
Kyzentun
2014-12-09 22:27:00 -07:00
parent c65c1eb386
commit 3fb36af157
71 changed files with 883 additions and 451 deletions
+169 -46
View File
@@ -20,6 +20,7 @@
#include "LuaReference.h"
#include "MessageManager.h"
#include "MemoryCardManager.h"
#include "NoteData.h"
#include "NoteSkinManager.h"
#include "PlayerState.h"
#include "PrefsManager.h"
@@ -136,7 +137,11 @@ GameState::GameState() :
{
g_pImpl = new GameStateImpl;
SetCurrentStyle( NULL );
m_pCurStyle.Set(NULL);
FOREACH_PlayerNumber(rpn)
{
m_SeparatedStyles[rpn]= NULL;
}
m_pCurGame.Set( NULL );
m_iCoins.Set( 0 );
@@ -153,12 +158,12 @@ GameState::GameState() :
FOREACH_PlayerNumber( p )
{
m_pPlayerState[p] = new PlayerState;
m_pPlayerState[p]->m_PlayerNumber = p;
m_pPlayerState[p]->SetPlayerNumber(p);
}
FOREACH_MultiPlayer( p )
{
m_pMultiPlayerState[p] = new PlayerState;
m_pMultiPlayerState[p]->m_PlayerNumber = PLAYER_1;
m_pMultiPlayerState[p]->SetPlayerNumber(PLAYER_1);
m_pMultiPlayerState[p]->m_mp = p;
}
@@ -285,7 +290,7 @@ void GameState::Reset()
ASSERT( THEME != NULL );
m_timeGameStarted.SetZero();
SetCurrentStyle( NULL );
SetCurrentStyle( NULL, PLAYER_INVALID );
FOREACH_MultiPlayer( p )
m_MultiPlayerStatus[p] = MultiPlayerStatus_NotJoined;
FOREACH_PlayerNumber( pn )
@@ -391,23 +396,23 @@ void GameState::JoinPlayer( PlayerNumber pn )
}
// Set the current style to something appropriate for the new number of joined players.
if( ALLOW_LATE_JOIN && m_pCurStyle != NULL )
if( ALLOW_LATE_JOIN && GetCurrentStyle(PLAYER_INVALID) != NULL )
{
const Style *pStyle;
// Only use one player for StyleType_OnePlayerTwoSides and StepsTypes
// that can only be played by one player (e.g. dance-solo,
// dance-threepanel, popn-nine). -aj
// XXX?: still shows joined player as "Insert Card". May not be an issue? -aj
if( m_pCurStyle->m_StyleType == StyleType_OnePlayerTwoSides ||
m_pCurStyle->m_StepsType == StepsType_dance_solo ||
m_pCurStyle->m_StepsType == StepsType_dance_threepanel ||
m_pCurStyle->m_StepsType == StepsType_popn_nine )
pStyle = GAMEMAN->GetFirstCompatibleStyle( m_pCurGame, 1, m_pCurStyle->m_StepsType );
if( GetCurrentStyle(PLAYER_INVALID)->m_StyleType == StyleType_OnePlayerTwoSides ||
GetCurrentStyle(PLAYER_INVALID)->m_StepsType == StepsType_dance_solo ||
GetCurrentStyle(PLAYER_INVALID)->m_StepsType == StepsType_dance_threepanel ||
GetCurrentStyle(PLAYER_INVALID)->m_StepsType == StepsType_popn_nine )
pStyle = GAMEMAN->GetFirstCompatibleStyle( m_pCurGame, 1, GetCurrentStyle(PLAYER_INVALID)->m_StepsType );
else
pStyle = GAMEMAN->GetFirstCompatibleStyle( m_pCurGame, GetNumSidesJoined(), m_pCurStyle->m_StepsType );
pStyle = GAMEMAN->GetFirstCompatibleStyle( m_pCurGame, GetNumSidesJoined(), GetCurrentStyle(PLAYER_INVALID)->m_StepsType );
// use SetCurrentStyle in case of StyleType_OnePlayerTwoSides
SetCurrentStyle( pStyle );
SetCurrentStyle( pStyle, pn );
}
Message msg( MessageIDToString(Message_PlayerJoined) );
@@ -657,7 +662,7 @@ int GameState::GetNumStagesForCurrentSongAndStepsOrCourse() const
int iNumStagesOfThisSong = 1;
if( m_pCurSong )
{
const Style *pStyle = m_pCurStyle;
const Style *pStyle = GetCurrentStyle(PLAYER_INVALID);
int numSidesJoined = GetNumSidesJoined();
if( pStyle == NULL )
{
@@ -894,6 +899,86 @@ void GameState::SaveCurrentSettingsToProfile( PlayerNumber pn )
pProfile->m_lastCourse.FromCourse( m_pPreferredCourse );
}
bool GameState::CanSafelyEnterGameplay(RString& reason)
{
if(!IsCourseMode())
{
Song const* song= m_pCurSong;
if(song == NULL)
{
reason= "Current song is NULL.";
return false;
}
}
else
{
Course const* song= m_pCurCourse;
if(song == NULL)
{
reason= "Current course is NULL.";
return false;
}
}
FOREACH_EnabledPlayer(pn)
{
Style const* style= GetCurrentStyle(pn);
if(style == NULL)
{
reason= ssprintf("Style for player %d is NULL.", pn+1);
return false;
}
if(!IsCourseMode())
{
Steps const* steps= m_pCurSteps[pn];
if(steps == NULL)
{
reason= ssprintf("Steps for player %d is NULL.", pn+1);
return false;
}
if(steps->m_StepsType != style->m_StepsType)
{
reason= ssprintf("Player %d StepsType %s for steps does not equal "
"StepsType %s for style.", pn+1,
GAMEMAN->GetStepsTypeInfo(steps->m_StepsType).szName,
GAMEMAN->GetStepsTypeInfo(style->m_StepsType).szName);
return false;
}
if(steps->m_pSong != m_pCurSong)
{
reason= ssprintf("Steps for player %d are not for the current song.",
pn+1);
return false;
}
NoteData ndtemp;
steps->GetNoteData(ndtemp);
if(ndtemp.GetNumTracks() != style->m_iColsPerPlayer)
{
reason= ssprintf("Steps for player %d have %d columns, style has %d "
"columns.", pn+1, ndtemp.GetNumTracks(), style->m_iColsPerPlayer);
return false;
}
}
else
{
Trail const* steps= m_pCurTrail[pn];
if(steps == NULL)
{
reason= ssprintf("Steps for player %d is NULL.", pn+1);
return false;
}
if(steps->m_StepsType != style->m_StepsType)
{
reason= ssprintf("Player %d StepsType %s for steps does not equal "
"StepsType %s for style.", pn+1,
GAMEMAN->GetStepsTypeInfo(steps->m_StepsType).szName,
GAMEMAN->GetStepsTypeInfo(style->m_StepsType).szName);
return false;
}
}
}
return true;
}
void GameState::Update( float fDelta )
{
m_SongOptions.Update( fDelta );
@@ -1197,7 +1282,7 @@ RString GameState::GetPlayerDisplayName( PlayerNumber pn ) const
bool GameState::PlayersCanJoin() const
{
bool b = GetNumSidesJoined() == 0 || GetCurrentStyle() == NULL; // selecting a style finalizes the players
bool b = GetNumSidesJoined() == 0 || GetCurrentStyle(PLAYER_INVALID) == NULL; // selecting a style finalizes the players
if( ALLOW_LATE_JOIN.IsLoaded() && ALLOW_LATE_JOIN )
{
Screen *pScreen = SCREENMAN->GetTopScreen();
@@ -1216,39 +1301,66 @@ int GameState::GetNumSidesJoined() const
return iNumSidesJoined;
}
const Game* GameState::GetCurrentGame()
const Game* GameState::GetCurrentGame() const
{
ASSERT( m_pCurGame != NULL ); // the game must be set before calling this
return m_pCurGame;
}
const Style* GameState::GetCurrentStyle() const
const Style* GameState::GetCurrentStyle(PlayerNumber pn) const
{
return m_pCurStyle;
}
void GameState::SetCurrentStyle( const Style *pStyle )
{
m_pCurStyle.Set( pStyle );
if( INPUTMAPPER )
if(GetCurrentGame() == NULL) { return NULL; }
if(!GetCurrentGame()->m_PlayersHaveSeparateStyles)
{
if( GetCurrentStyle() && GetCurrentStyle()->m_StyleType == StyleType_OnePlayerTwoSides )
INPUTMAPPER->SetJoinControllers( this->GetMasterPlayerNumber() );
else
INPUTMAPPER->SetJoinControllers( PLAYER_INVALID );
return m_pCurStyle;
}
else
{
if(pn >= NUM_PLAYERS)
{
return m_SeparatedStyles[PLAYER_1] == NULL ? m_SeparatedStyles[PLAYER_2]
: m_SeparatedStyles[PLAYER_1];
}
return m_SeparatedStyles[pn];
}
}
bool GameState::SetCompatibleStyle(StepsType stype)
void GameState::SetCurrentStyle(const Style *style, PlayerNumber pn)
{
if(!GetCurrentGame()->m_PlayersHaveSeparateStyles)
{
m_pCurStyle.Set(style);
}
else
{
m_SeparatedStyles[pn]= style;
if(pn == PLAYER_INVALID)
{
FOREACH_PlayerNumber(rpn)
{
m_SeparatedStyles[rpn]= style;
}
}
}
if(INPUTMAPPER)
{
if(GetCurrentStyle(pn) && GetCurrentStyle(pn)->m_StyleType == StyleType_OnePlayerTwoSides)
INPUTMAPPER->SetJoinControllers(this->GetMasterPlayerNumber());
else
INPUTMAPPER->SetJoinControllers(PLAYER_INVALID);
}
}
bool GameState::SetCompatibleStyle(StepsType stype, PlayerNumber pn)
{
bool style_incompatible= false;
if(!m_pCurStyle)
if(!GetCurrentStyle(pn))
{
style_incompatible= true;
}
else
{
style_incompatible= stype != m_pCurStyle->m_StepsType;
style_incompatible= stype != GetCurrentStyle(pn)->m_StepsType;
}
if(CommonMetrics::AUTO_SET_STYLE && style_incompatible)
{
@@ -1258,9 +1370,9 @@ bool GameState::SetCompatibleStyle(StepsType stype)
{
return false;
}
SetCurrentStyle(compatible_style);
SetCurrentStyle(compatible_style, pn);
}
return stype == m_pCurStyle->m_StepsType;
return stype == GetCurrentStyle(pn)->m_StepsType;
}
bool GameState::IsPlayerEnabled( PlayerNumber pn ) const
@@ -1303,7 +1415,7 @@ bool GameState::IsHumanPlayer( PlayerNumber pn ) const
if( pn == PLAYER_INVALID )
return false;
if( GetCurrentStyle() == NULL ) // no style chosen
if( GetCurrentStyle(pn) == NULL ) // no style chosen
{
if( PlayersCanJoin() )
return m_bSideIsJoined[pn]; // only allow input from sides that have already joined
@@ -1311,7 +1423,7 @@ bool GameState::IsHumanPlayer( PlayerNumber pn ) const
return true; // if we can't join, then we're on a screen like MusicScroll or GameOver
}
StyleType type = GetCurrentStyle()->m_StyleType;
StyleType type = GetCurrentStyle(pn)->m_StyleType;
switch( type )
{
case StyleType_TwoPlayersTwoSides:
@@ -1669,7 +1781,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
{
CHECKPOINT;
StepsType st = GetCurrentStyle()->m_StepsType;
StepsType st = GetCurrentStyle(pn)->m_StepsType;
// Find unique Song and Steps combinations that were played.
// We must keep only the unique combination or else we'll double-count
@@ -2012,7 +2124,7 @@ bool GameState::DifficultiesLocked() const
return true;
if( IsCourseMode() )
return PREFSMAN->m_bLockCourseDifficulties;
if( GetCurrentStyle()->m_bLockDifficulties )
if( GetCurrentStyle(PLAYER_INVALID)->m_bLockDifficulties )
return true;
return false;
}
@@ -2099,7 +2211,7 @@ bool GameState::ChangePreferredCourseDifficulty( PlayerNumber pn, int dir )
return false;
if( find(v.begin(),v.end(),cd) == v.end() )
continue; /* not available */
if( !pCourse || pCourse->GetTrail( GetCurrentStyle()->m_StepsType, cd ) )
if( !pCourse || pCourse->GetTrail( GetCurrentStyle(pn)->m_StepsType, cd ) )
break;
}
@@ -2319,13 +2431,21 @@ public:
else { Song *pS = Luna<Song>::check( L, 1, true ); p->m_pCurSong.Set( pS ); }
COMMON_RETURN_SELF;
}
static void SetCompatibleStyleOrError(T* p, lua_State* L, StepsType stype)
static int CanSafelyEnterGameplay(T* p, lua_State* L)
{
if(!p->SetCompatibleStyle(stype))
RString reason;
bool can= p->CanSafelyEnterGameplay(reason);
lua_pushboolean(L, can);
LuaHelpers::Push(L, reason);
return 2;
}
static void SetCompatibleStyleOrError(T* p, lua_State* L, StepsType stype, PlayerNumber pn)
{
if(!p->SetCompatibleStyle(stype, pn))
{
luaL_error(L, "No compatible style for steps/trail.");
}
if(!p->m_pCurStyle)
if(!p->GetCurrentStyle(pn))
{
luaL_error(L, "No style set and AutoSetStyle is false, cannot set steps/trail.");
}
@@ -2348,7 +2468,7 @@ public:
else
{
Steps *pS = Luna<Steps>::check(L,2);
SetCompatibleStyleOrError(p, L, pS->m_StepsType);
SetCompatibleStyleOrError(p, L, pS->m_StepsType, pn);
p->m_pCurSteps[pn].Set(pS);
}
COMMON_RETURN_SELF;
@@ -2378,7 +2498,7 @@ public:
else
{
Trail *pS = Luna<Trail>::check(L,2);
SetCompatibleStyleOrError(p, L, pS->m_StepsType);
SetCompatibleStyleOrError(p, L, pS->m_StepsType, pn);
p->m_pCurTrail[pn].Set(pS);
}
COMMON_RETURN_SELF;
@@ -2579,7 +2699,8 @@ public:
}
static int GetCurrentStyle( T* p, lua_State *L )
{
Style *pStyle = const_cast<Style *> (p->GetCurrentStyle());
PlayerNumber pn= Enum::Check<PlayerNumber>(L, 1, true, true);
Style *pStyle = const_cast<Style *> (p->GetCurrentStyle(pn));
LuaHelpers::Push( L, pStyle );
return 1;
}
@@ -2732,9 +2853,9 @@ public:
static void ClearIncompatibleStepsAndTrails( T *p, lua_State* L )
{
const Style *style = p->m_pCurStyle;
FOREACH_HumanPlayer( pn )
{
const Style *style = p->GetCurrentStyle(pn);
if( p->m_pCurSteps[pn] && ( !style || style->m_StepsType != p->m_pCurSteps[pn]->m_StepsType ) )
{
p->m_pCurSteps[pn].Set( NULL );
@@ -2779,8 +2900,9 @@ public:
{
COMMON_RETURN_SELF;
}
PlayerNumber pn= Enum::Check<PlayerNumber>(L, 2, true, true);
p->SetCurrentStyle( pStyle );
p->SetCurrentStyle(pStyle, pn);
ClearIncompatibleStepsAndTrails( p, L );
COMMON_RETURN_SELF;
@@ -2789,7 +2911,7 @@ public:
static int SetCurrentPlayMode( T* p, lua_State *L )
{
PlayMode pm = Enum::Check<PlayMode>( L, 1 );
if( AreStyleAndPlayModeCompatible( p, L, p->m_pCurStyle, pm ) )
if( AreStyleAndPlayModeCompatible( p, L, p->GetCurrentStyle(PLAYER_INVALID), pm ) )
{
p->m_PlayMode.Set( pm );
}
@@ -2811,6 +2933,7 @@ public:
ADD_METHOD( GetPlayerState );
ADD_METHOD( GetMultiPlayerState );
ADD_METHOD( ApplyGameCommand );
ADD_METHOD( CanSafelyEnterGameplay );
ADD_METHOD( GetCurrentSong );
ADD_METHOD( SetCurrentSong );
ADD_METHOD( GetCurrentSteps );