diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt
index 64fdd5115f..1887d83591 100644
--- a/Docs/Changelog_sm5.txt
+++ b/Docs/Changelog_sm5.txt
@@ -15,6 +15,34 @@ ________________________________________________________________________________
* [Player] "ComboBreakOnImmediateHoldLetGo" theme metric added. [sillybear]
* [PlayerState] ApplyPreferredOptionsToOtherLevels function added. [kyzentun]
+2014/12/07
+----------
+* [Game] GetSeparateStyles function added. Use this to detect whether a game
+ allows the players to play different styles. [kyzentun] (used by kickbox)
+* [GameManager] Lua Scripts/ folders are now reloaded when the Game mode is
+ changed. [kyzentun]
+* [GameState] CanSafelyEnterGameplay function added. [kyzentun]
+ In kickbox game mode, players can have different styles set, pass a
+ PlayerNumber when using SetCurrentStyle or GetCurrentStyle.
+* [kickbox] New game mode with 4 styles. [kyzentun]
+* [ScreenGameplay] Notefield positioning is handled a bit differently now.
+ See comments in _fallback/metrics.ini above the [ScreenGameplay]
+ MarginFunction metric. Basically, you can define a lua function that
+ returns the space you want at the edges and in the center instead of
+ setting position metrics. Do NOT use Style:GetWidth to calculate the
+ margins your function returns.
+ ScreenGameplay now handles zooming the notefield to fit in the space
+ instead of using the NeedsZoomOutWith2Players flag in the style.
+ If the notefield doesn't fit in the space between the margins, and there is
+ only one player, the player will be centered even if the Center1Player pref
+ is false. [kyzentun]
+* [Style] NeedsZoomOutWith2Players decapitated. Always returns false now.
+ GetWidth added. [kyzentun]
+* [techno] Techno game mode no longer has special column width for versus.
+ Techno was the only game mode that used the NeedsZoomOutWith2Players flag,
+ and the zoom factor it applied was 0.6, and the special versus column width
+ was 0.6*normal, so this should make no difference. [kyzentun]
+
2014/12/03
----------
* [command line arg] --game command line arg added for setting the game type
@@ -68,6 +96,10 @@ ________________________________________________________________________________
----------
* [RollingNumbers] Cropping and color during tweens fixed. [kyzentun]
+2014/10/27
+----------
+* [Changelog] Vospi read the release notes.
+
2014/10/23
----------
* [Global] approach, multiapproach, lerp, and lerp_color lua functions added. [kyzentun]
diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml
index 0500f90ab0..156b39ba02 100644
--- a/Docs/Luadoc/Lua.xml
+++ b/Docs/Luadoc/Lua.xml
@@ -702,6 +702,7 @@
+
@@ -750,6 +751,7 @@
+
@@ -1659,6 +1661,7 @@
+
diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index 421749d111..7f37c5e4a2 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -2131,6 +2131,9 @@ save yourself some time, copy this for undocumented things:
Returns the name of the game such as "dance" or "pump".
+
+ Returns whether this game allows the players to have separate styles.
+
@@ -2270,6 +2273,16 @@ save yourself some time, copy this for undocumented things:
The second argument is optional. Apply the GameCommand represented by sCommand
for pn, if given. See .
+
+ Checks various things to determine whether the game will crash when gameplay starts. Returns false and a string if gameplay cannot be entered safely.
+ Might not work in all cases, but will catch things like a player not having
+ steps set or no current song or style. Mainly exists for people with a custom ScreenSelectMusic replacement.
+ Example:
+ local can, reason= GAMESTATE:CanSafelyEnterGameplay()
+ if not can then
+ lua.ReportScriptError("Cannot safely enter gameplay: " .. tostring(reason))
+ end
+
Removes any stage modifiers that are illegal for course play.
@@ -4716,11 +4729,14 @@ save yourself some time, copy this for undocumented things:
Returns the draw order of the column.
+
+ Returns the width of the notefield for the given player with this style.
+
Returns true if this style locks the difficulty for both players.
- Returns true if the Style needs to be zoomed out with two players.
+ Deprecated. Always returns false.
diff --git a/Themes/_fallback/Scripts/03 Gameplay.lua b/Themes/_fallback/Scripts/03 Gameplay.lua
index aefe34ac87..339a3c0bd8 100644
--- a/Themes/_fallback/Scripts/03 Gameplay.lua
+++ b/Themes/_fallback/Scripts/03 Gameplay.lua
@@ -27,6 +27,55 @@ function GetExtraColorThreshold()
return Modes[CurGameName()] or 10
end
+-- GameplayMargins exists to provide a layer of backwards compatibility for
+-- people using the X position metrics to set where the notefields are.
+-- This makes it somewhat complex.
+-- Rather than trying to understand how it works, you can simply do this:
+-- (example values in parentheses)
+-- 1. Decide how much space you want in the center between notefields. (80)
+-- 2. Decide how much space you want on each side. (40)
+-- 3. Write a simple function that just returns those numbers:
+-- function GameplayMargins() return 40, 80, 40 end
+-- Then the engine does the work of figuring out where each notefield should
+-- be centered.
+function GameplayMargins(enabled_players, styletype)
+ local other= {[PLAYER_1]= PLAYER_2, [PLAYER_2]= PLAYER_1}
+ local margins= {[PLAYER_1]= {40, 40}, [PLAYER_2]= {40, 40}}
+ -- Use a fake style width because calculating the real style width throws off
+ -- the code in the engine.
+ local fake_style_width= 272
+ -- Handle the case of a single player that is centered first because it's
+ -- simpler.
+ if Center1Player() then
+ local pn= enabled_players[1]
+ fake_style_width= 544
+ local center= _screen.cx
+ local left= center - (fake_style_width / 2)
+ local right= _screen.w - center - (fake_style_width / 2)
+ -- center margin width will be ignored.
+ return left, 80, right
+ end
+ local half_screen= _screen.w / 2
+ local left= {[PLAYER_1]= 0, [PLAYER_2]= half_screen}
+ for i, pn in ipairs(enabled_players) do
+ local edge= left[pn]
+ local center= THEME:GetMetric("ScreenGameplay",
+ "Player"..ToEnumShortString(pn)..ToEnumShortString(styletype).."X")
+ -- Adjust for the p2 center being on the right side.
+ center= center - edge
+ margins[pn][1]= center - (fake_style_width / 2)
+ margins[pn][2]= half_screen - center - (fake_style_width / 2)
+ if #enabled_players == 1 then
+ margins[other[pn]][1]= margins[pn][2]
+ margins[other[pn]][2]= margins[pn][1]
+ end
+ end
+ local left= margins[PLAYER_1][1]
+ local center= margins[PLAYER_1][2] + margins[PLAYER_2][1]
+ local right= margins[PLAYER_2][2]
+ return left, center, right
+end
+
-- AllowOptionsMenu()
-- [en] returns if you are able to select options
-- on ScreenSelectMusic.
diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini
index 81cbcf0444..3b10eb0549 100644
--- a/Themes/_fallback/metrics.ini
+++ b/Themes/_fallback/metrics.ini
@@ -1130,7 +1130,7 @@ AttackDisplayXOffsetOneSideP2=0
AttackDisplayXOffsetBothSides=0
AttackDisplayY=-70
AttackDisplayYReverse=70
-; HACK: These shouldn't go to the render pipe at all if IsGame("pump")
+# HACK: These shouldn't go to the render pipe at all if IsGame("pump")
HoldJudgmentYStandard=IsGame("pump") and -99999 or -90
HoldJudgmentYReverse=IsGame("pump") and -99999 or 90
BrightGhostComboThreshold=100
@@ -3413,7 +3413,25 @@ MusicFadeOutSeconds=0.5
OutTransitionLength=5
CourseTransitionLength=0.5
BeginFailedDelay=1.0
-#
+# New way to control where the notefields are on gameplay.
+# The MarginFunction will be passed GAMESTATE:EnabledPlayers() and the
+# current styletype. The function must return three values:
+# Left margin width, center margin width, right margin width.
+# The engine will then position the notefields and adjust their size to fit
+# in the space not occupied by the margins. If there is only one player and
+# that player would normally be centered (OnePlayerTwoSides or
+# TwoPlayersSharedSides, or the Center1Player preference), then the center
+# margin value will be ignored.
+# Mods applied to the player may still move the notefield into the margin,
+# this is just for controlling its initial position and size.
+# The purpose of this is to allow the engine more flexibility in styles,
+# for example, one player playing dance-solo while the other plays
+# dance-single.
+MarginFunction=GameplayMargins
+# These X values for each player and styletype are deprecated in favor of
+# writing a MarginFunction that returns the margin sizes you prefer.
+# The MarginFunction supplied by _fallback will use these metrics for
+# backwards compatibility.
PlayerP1OnePlayerOneSideX=math.floor(scale((0.85/3),0,1,SCREEN_LEFT,SCREEN_RIGHT))
PlayerP2OnePlayerOneSideX=math.floor(scale((2.15/3),0,1,SCREEN_LEFT,SCREEN_RIGHT))
PlayerP1TwoPlayersTwoSidesX=math.floor(scale((0.85/3),0,1,SCREEN_LEFT,SCREEN_RIGHT))
diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp
index 76f2a17d94..ae0ee06754 100644
--- a/src/ArrowEffects.cpp
+++ b/src/ArrowEffects.cpp
@@ -82,16 +82,16 @@ namespace
void ArrowEffects::Update()
{
- const Style* pStyle = GAMESTATE->GetCurrentStyle();
-
static float fLastTime = 0;
float fTime = RageTimer::GetTimeSinceStartFast();
FOREACH_EnabledPlayer( pn )
{
+ const Style* pStyle = GAMESTATE->GetCurrentStyle(pn);
const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn];
const SongPosition &position = GAMESTATE->m_bIsUsingStepTiming
? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position;
+ const float field_zoom= GAMESTATE->m_pPlayerState[pn]->m_NotefieldZoom;
PerPlayerData &data = g_EffectData[pn];
@@ -127,8 +127,8 @@ void ArrowEffects::Update()
for( int i=iStartCol; i<=iEndCol; i++ )
{
- data.m_fMinTornadoX[iColNum] = min( data.m_fMinTornadoX[iColNum], pCols[i].fXOffset );
- data.m_fMaxTornadoX[iColNum] = max( data.m_fMaxTornadoX[iColNum], pCols[i].fXOffset );
+ data.m_fMinTornadoX[iColNum] = min( data.m_fMinTornadoX[iColNum], pCols[i].fXOffset * field_zoom );
+ data.m_fMaxTornadoX[iColNum] = max( data.m_fMaxTornadoX[iColNum], pCols[i].fXOffset * field_zoom);
}
}
@@ -439,7 +439,7 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
{
float fPixelOffsetFromCenter = 0; // fill this in below
- const Style* pStyle = GAMESTATE->GetCurrentStyle();
+ const Style* pStyle = GAMESTATE->GetCurrentStyle(pPlayerState->m_PlayerNumber);
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
// TODO: Don't index by PlayerNumber.
@@ -448,7 +448,7 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
if( fEffects[PlayerOptions::EFFECT_TORNADO] != 0 )
{
- const float fRealPixelOffset = pCols[iColNum].fXOffset;
+ const float fRealPixelOffset = pCols[iColNum].fXOffset * pPlayerState->m_NotefieldZoom;
const float fPositionBetween = SCALE( fRealPixelOffset, data.m_fMinTornadoX[iColNum], data.m_fMaxTornadoX[iColNum],
TORNADO_POSITION_SCALE_TO_LOW, TORNADO_POSITION_SCALE_TO_HIGH );
float fRads = acosf( fPositionBetween );
@@ -469,8 +469,8 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
const int iFirstCol = 0;
const int iLastCol = pStyle->m_iColsPerPlayer-1;
const int iNewCol = SCALE( iColNum, iFirstCol, iLastCol, iLastCol, iFirstCol );
- const float fOldPixelOffset = pCols[iColNum].fXOffset;
- const float fNewPixelOffset = pCols[iNewCol].fXOffset;
+ const float fOldPixelOffset = pCols[iColNum].fXOffset * pPlayerState->m_NotefieldZoom;
+ const float fNewPixelOffset = pCols[iNewCol].fXOffset * pPlayerState->m_NotefieldZoom;
const float fDistance = fNewPixelOffset - fOldPixelOffset;
fPixelOffsetFromCenter += fDistance * fEffects[PlayerOptions::EFFECT_FLIP];
}
@@ -515,7 +515,7 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
}
}
- fPixelOffsetFromCenter += pCols[iColNum].fXOffset;
+ fPixelOffsetFromCenter += pCols[iColNum].fXOffset * pPlayerState->m_NotefieldZoom;
if( fEffects[PlayerOptions::EFFECT_TINY] != 0 )
{
@@ -764,10 +764,11 @@ bool ArrowEffects::NeedZBuffer( const PlayerState* pPlayerState )
float ArrowEffects::GetZoom( const PlayerState* pPlayerState )
{
float fZoom = 1.0f;
- // FIXME: Move the zoom values into Style
- if( GAMESTATE->GetCurrentStyle()->m_bNeedsZoomOutWith2Players &&
- (GAMESTATE->GetNumSidesJoined()==2 || GAMESTATE->AnyPlayersAreCpu()) )
- fZoom *= 0.6f;
+ // Design change: Instead of having a flag in the style that toggles a
+ // fixed zoom (0.6) that is only applied to the columns, ScreenGameplay now
+ // calculates a zoom factor to apply to the notefield and puts it in the
+ // PlayerState. -Kyz
+ fZoom*= pPlayerState->m_NotefieldZoom;
float fTinyPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_TINY];
if( fTinyPercent != 0 )
diff --git a/src/BPMDisplay.cpp b/src/BPMDisplay.cpp
index 3e138d9155..1f10ccbadc 100644
--- a/src/BPMDisplay.cpp
+++ b/src/BPMDisplay.cpp
@@ -213,9 +213,9 @@ void BPMDisplay::SetBpmFromSteps( const Steps* pSteps )
void BPMDisplay::SetBpmFromCourse( const Course* pCourse )
{
ASSERT( pCourse != NULL );
- ASSERT( GAMESTATE->GetCurrentStyle() != NULL );
+ ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != NULL );
- StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
+ StepsType st = GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType;
Trail *pTrail = pCourse->GetTrail( st );
// GetTranslitFullTitle because "Crashinfo.txt is garbled because of the ANSI output as usual." -f
ASSERT_M( pTrail != NULL, ssprintf("Course '%s' has no trail for StepsType '%s'", pCourse->GetTranslitFullTitle().c_str(), StringConversion::ToString(st).c_str() ) );
@@ -259,7 +259,7 @@ void BPMDisplay::SetFromGameState()
}
if( GAMESTATE->m_pCurCourse.Get() )
{
- if( GAMESTATE->GetCurrentStyle() == NULL )
+ if( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == NULL )
; // This is true when backing out from ScreenSelectCourse to ScreenTitleMenu. So, don't call SetBpmFromCourse where an assert will fire.
else
SetBpmFromCourse( GAMESTATE->m_pCurCourse );
diff --git a/src/Background.cpp b/src/Background.cpp
index d607a20122..e70e86e6e9 100644
--- a/src/Background.cpp
+++ b/src/Background.cpp
@@ -205,7 +205,7 @@ void BackgroundImpl::Init()
{
bOneOrMoreChars = true;
// Disable dancing characters if Beginner Helper will be showing.
- if( PREFSMAN->m_bShowBeginnerHelper && BeginnerHelper::CanUse() &&
+ if( PREFSMAN->m_bShowBeginnerHelper && BeginnerHelper::CanUse(p) &&
GAMESTATE->m_pCurSteps[p] && GAMESTATE->m_pCurSteps[p]->GetDifficulty() == Difficulty_Beginner )
bShowingBeginnerHelper = true;
}
diff --git a/src/BeginnerHelper.cpp b/src/BeginnerHelper.cpp
index 5c6f2968ee..f43bf118c1 100644
--- a/src/BeginnerHelper.cpp
+++ b/src/BeginnerHelper.cpp
@@ -78,7 +78,7 @@ BeginnerHelper::~BeginnerHelper()
bool BeginnerHelper::Init( int iDancePadType )
{
ASSERT( !m_bInitialized );
- if( !CanUse() )
+ if( !CanUse(PLAYER_INVALID) )
return false;
// If no players were successfully added, bail.
@@ -200,7 +200,7 @@ void BeginnerHelper::AddPlayer( PlayerNumber pn, const NoteData &ns )
ASSERT( pn >= 0 && pn < NUM_PLAYERS );
ASSERT( GAMESTATE->IsHumanPlayer(pn) );
- if( !CanUse() )
+ if( !CanUse(pn) )
return;
const Character *Character = GAMESTATE->m_pCurCharacters[pn];
@@ -212,13 +212,20 @@ void BeginnerHelper::AddPlayer( PlayerNumber pn, const NoteData &ns )
m_bPlayerEnabled[pn] = true;
}
-bool BeginnerHelper::CanUse()
+bool BeginnerHelper::CanUse(PlayerNumber pn)
{
for (int i=0; iGetCurrentStyle()->m_bCanUseBeginnerHelper;
+ // This does not pass PLAYER_INVALID to GetCurrentStyle because that would
+ // only check the first non-NULL style. Both styles need to be checked. -Kyz
+ if(pn == PLAYER_INVALID)
+ {
+ return GAMESTATE->GetCurrentStyle(PLAYER_1)->m_bCanUseBeginnerHelper ||
+ GAMESTATE->GetCurrentStyle(PLAYER_2)->m_bCanUseBeginnerHelper;
+ }
+ return GAMESTATE->GetCurrentStyle(pn)->m_bCanUseBeginnerHelper;
}
void BeginnerHelper::DrawPrimitives()
diff --git a/src/BeginnerHelper.h b/src/BeginnerHelper.h
index a5941e7e85..38bb8b144a 100644
--- a/src/BeginnerHelper.h
+++ b/src/BeginnerHelper.h
@@ -18,7 +18,7 @@ public:
bool Init( int iDancePadType );
bool IsInitialized() { return m_bInitialized; }
- static bool CanUse();
+ static bool CanUse(PlayerNumber pn);
void AddPlayer( PlayerNumber pn, const NoteData &nd );
void ShowStepCircle( PlayerNumber pn, int CSTEP );
bool m_bShowBackground;
diff --git a/src/CourseUtil.cpp b/src/CourseUtil.cpp
index 44ed9212c4..5c67882ed6 100644
--- a/src/CourseUtil.cpp
+++ b/src/CourseUtil.cpp
@@ -95,14 +95,14 @@ void CourseUtil::SortCoursePointerArrayByDifficulty( vector &vpCoursesI
void CourseUtil::SortCoursePointerArrayByRanking( vector &vpCoursesInOut )
{
for( unsigned i=0; iUpdateCourseStats( GAMESTATE->GetCurrentStyle()->m_StepsType );
+ vpCoursesInOut[i]->UpdateCourseStats( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType );
sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), CompareCoursePointersByRanking );
}
void CourseUtil::SortCoursePointerArrayByTotalDifficulty( vector &vpCoursesInOut )
{
for( unsigned i=0; iUpdateCourseStats( GAMESTATE->GetCurrentStyle()->m_StepsType );
+ vpCoursesInOut[i]->UpdateCourseStats( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType );
sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), CompareCoursePointersByTotalDifficulty );
}
@@ -176,7 +176,7 @@ void CourseUtil::SortCoursePointerArrayByAvgDifficulty( vector &vpCours
course_sort_val.clear();
for( unsigned i = 0; i < vpCoursesInOut.size(); ++i )
{
- int iMeter = vpCoursesInOut[i]->GetMeter( GAMESTATE->GetCurrentStyle()->m_StepsType, Difficulty_Medium );
+ int iMeter = vpCoursesInOut[i]->GetMeter( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType, Difficulty_Medium );
course_sort_val[vpCoursesInOut[i]] = ssprintf( "%06i", iMeter );
}
sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), CompareCoursePointersByTitle );
@@ -448,8 +448,8 @@ bool EditCourseUtil::ValidateEditCourseName( const RString &sAnswer, RString &sE
void EditCourseUtil::UpdateAndSetTrail()
{
- ASSERT( GAMESTATE->m_pCurStyle != NULL );
- StepsType st = GAMESTATE->m_pCurStyle->m_StepsType;
+ ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != NULL );
+ StepsType st = GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType;
Trail *pTrail = NULL;
if( GAMESTATE->m_pCurCourse )
pTrail = GAMESTATE->m_pCurCourse->GetTrailForceRegenCache( st );
diff --git a/src/DifficultyList.cpp b/src/DifficultyList.cpp
index a3ce25a8a9..192931c37e 100644
--- a/src/DifficultyList.cpp
+++ b/src/DifficultyList.cpp
@@ -277,7 +277,7 @@ void StepsDisplayList::SetFromGameState()
FOREACH_CONST( Difficulty, difficulties, d )
{
m_Rows[i].m_dc = *d;
- m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GAMESTATE->m_pCurStyle->m_StepsType, 0, *d, CourseType_Invalid );
+ m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType, 0, *d, CourseType_Invalid );
++i;
}
}
diff --git a/src/Game.cpp b/src/Game.cpp
index 07aac354c4..12763ed4ff 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -62,12 +62,14 @@ public:
static int GetName( T* p, lua_State *L ) { lua_pushstring( L, p->m_szName ); return 1; }
static int CountNotesSeparately( T* p, lua_State *L ) { lua_pushboolean( L, p->m_bCountNotesSeparately ); return 1; }
DEFINE_METHOD( GetMapJudgmentTo, GetMapJudgmentTo(Enum::Check(L, 1)) )
+ DEFINE_METHOD(GetSeparateStyles, m_PlayersHaveSeparateStyles);
LunaGame()
{
ADD_METHOD( GetName );
ADD_METHOD( CountNotesSeparately );
ADD_METHOD( GetMapJudgmentTo );
+ ADD_METHOD( GetSeparateStyles );
}
};
diff --git a/src/Game.h b/src/Game.h
index e3d1eb3e39..2f06b933a7 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -34,6 +34,7 @@ struct Game
/** @brief Do we count multiple notes in a row as separate notes, or as one note? */
bool m_bCountNotesSeparately;
bool m_bTickHolds;
+ bool m_PlayersHaveSeparateStyles;
InputScheme m_InputScheme;
diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp
index 60d788df96..83da0bb0a5 100644
--- a/src/GameCommand.cpp
+++ b/src/GameCommand.cpp
@@ -84,7 +84,7 @@ bool GameCommand::DescribesCurrentMode( PlayerNumber pn ) const
{
if( m_pm != PlayMode_Invalid && GAMESTATE->m_PlayMode != m_pm )
return false;
- if( m_pStyle && GAMESTATE->GetCurrentStyle() != m_pStyle )
+ if( m_pStyle && GAMESTATE->GetCurrentStyle(pn) != m_pStyle )
return false;
// HACK: don't compare m_dc if m_pSteps is set. This causes problems
// in ScreenSelectOptionsMaster::ImportOptions if m_PreferredDifficulty
@@ -289,7 +289,7 @@ void GameCommand::LoadOne( const Command& cmd )
if( !m_bInvalid )
{
Song *pSong = (m_pSong != NULL)? m_pSong:GAMESTATE->m_pCurSong;
- const Style *pStyle = m_pStyle ? m_pStyle : GAMESTATE->GetCurrentStyle();
+ const Style *pStyle = m_pStyle ? m_pStyle : GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber());
if( pSong == NULL || pStyle == NULL )
{
MAKE_INVALID("Must set Song and Style to set Steps.");
@@ -327,7 +327,7 @@ void GameCommand::LoadOne( const Command& cmd )
if( !m_bInvalid )
{
Course *pCourse = (m_pCourse != NULL)? m_pCourse:GAMESTATE->m_pCurCourse;
- const Style *pStyle = m_pStyle ? m_pStyle : GAMESTATE->GetCurrentStyle();
+ const Style *pStyle = m_pStyle ? m_pStyle : GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber());
if( pCourse == NULL || pStyle == NULL )
{
MAKE_INVALID("Must set Course and Style to set Trail.");
@@ -598,7 +598,7 @@ bool GameCommand::IsPlayable( RString *why ) const
if( m_pm != PlayMode_Invalid || m_pStyle != NULL )
{
const PlayMode pm = (m_pm != PlayMode_Invalid) ? m_pm : GAMESTATE->m_PlayMode;
- const Style *style = (m_pStyle != NULL)? m_pStyle: GAMESTATE->GetCurrentStyle();
+ const Style *style = (m_pStyle != NULL)? m_pStyle: GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber());
if( !AreStyleAndPlayModeCompatible( style, pm ) )
{
if( why )
@@ -705,7 +705,7 @@ void GameCommand::ApplySelf( const vector &vpns ) const
if( m_pStyle != NULL )
{
- GAMESTATE->SetCurrentStyle( m_pStyle );
+ GAMESTATE->SetCurrentStyle( m_pStyle, GAMESTATE->GetMasterPlayerNumber() );
// It's possible to choose a style that didn't have enough players joined.
// If enough players aren't joined, then we need to subtract credits
diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp
index 98976a2d91..7b1366e46a 100644
--- a/src/GameLoop.cpp
+++ b/src/GameLoop.cpp
@@ -239,6 +239,7 @@ namespace
* case going from theme to theme, but if it was, it should be fixed
* now. There's probably be a better way to do it, but I'm not sure
* what it'd be. -aj */
+ THEME->UpdateLuaGlobals();
THEME->ReloadMetrics();
g_NewGame= RString();
g_NewTheme= RString();
diff --git a/src/GameManager.cpp b/src/GameManager.cpp
index d2472ec585..5ae0657765 100644
--- a/src/GameManager.cpp
+++ b/src/GameManager.cpp
@@ -170,7 +170,6 @@ static const Style g_Style_Dance_Single =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // m_bNeedsZoomOutWith2Players
true, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -206,7 +205,6 @@ static const Style g_Style_Dance_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // m_bNeedsZoomOutWith2Players
true, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -250,7 +248,6 @@ static const Style g_Style_Dance_Double =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -286,7 +283,6 @@ static const Style g_Style_Dance_Couple =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3
},
- false, // m_bNeedsZoomOutWith2Players
true, // m_bCanUseBeginnerHelper
true, // m_bLockDifficulties
};
@@ -326,7 +322,6 @@ static const Style g_Style_Dance_Solo =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -370,7 +365,6 @@ static const Style g_Style_Dance_Couple_Edit =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -405,7 +399,6 @@ static const Style g_Style_Dance_ThreePanel =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -443,7 +436,6 @@ static const Style g_Style_Dance_Solo_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,5,1,4,2,3 // outside in
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
}; */
@@ -487,10 +479,8 @@ static const Style g_Style_Dance_Routine =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
true, // m_bLockDifficulties
-
};
static const Style *g_apGame_Dance_Styles[] =
@@ -512,6 +502,7 @@ static const Game g_Game_Dance =
g_apGame_Dance_Styles, // m_apStyles
false, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"dance", // m_szName
NUM_DANCE_BUTTONS, // m_iButtonsPerController
@@ -600,7 +591,6 @@ static const Style g_Style_Pump_Single =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,1,3,0,4
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -638,7 +628,6 @@ static const Style g_Style_Pump_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,1,3,0,4
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -678,7 +667,6 @@ static const Style g_Style_Pump_HalfDouble =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,3,1,4,0,5
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -726,7 +714,6 @@ static const Style g_Style_Pump_Double =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,1,3,0,4, 2+5,1+5,3+5,0+5,4+5
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -764,7 +751,6 @@ static const Style g_Style_Pump_Couple =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,1,3,0,4
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
true, // m_bLockDifficulties
};
@@ -812,7 +798,6 @@ static const Style g_Style_Pump_Couple_Edit =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,1,3,0,4, 2+5,1+5,3+5,0+5,4+5
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -860,7 +845,6 @@ static const Style g_Style_Pump_Routine =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,1,3,0,4,7,6,8,5,9
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
true, // m_bLockDifficulties
};
@@ -883,6 +867,7 @@ static const Game g_Game_Pump =
g_apGame_Pump_Styles, // m_apStyles
false, // m_bCountNotesSeparately
true, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"pump", // m_szName
NUM_PUMP_BUTTONS, // m_iButtonsPerController
@@ -961,7 +946,6 @@ static const Style g_Style_KB7_Single =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6 // doesn't work?
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1005,7 +989,6 @@ static const Style g_Style_KB7_Small =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6 // doesn't work?
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
}; */
@@ -1047,7 +1030,6 @@ static const Style g_Style_KB7_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6
},
- true, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1066,6 +1048,7 @@ static const Game g_Game_KB7 =
g_apGame_KB7_Styles, // m_apStyles
true, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"kb7", // m_szName
NUM_KB7_BUTTONS, // m_iButtonsPerController
@@ -1134,7 +1117,6 @@ static const Style g_Style_Ez2_Single =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,0,4,1,3 // This should be from back to front: Down, UpLeft, UpRight, Upper Left Hand, Upper Right Hand
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1176,7 +1158,6 @@ static const Style g_Style_Ez2_Real =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
3,0,6,1,5,2,4 // This should be from back to front: Down, UpLeft, UpRight, Lower Left Hand, Lower Right Hand, Upper Left Hand, Upper Right Hand
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1214,7 +1195,6 @@ static const Style g_Style_Ez2_Single_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,0,4,1,3 // This should be from back to front: Down, UpLeft, UpRight, Upper Left Hand, Upper Right Hand
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1256,7 +1236,6 @@ static const Style g_Style_Ez2_Real_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
3,0,6,2,4,1,5 // This should be from back to front: Down, UpLeft, UpRight, Lower Left Hand, Lower Right Hand, Upper Left Hand, Upper Right Hand
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1304,7 +1283,6 @@ static const Style g_Style_Ez2_Double =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,0,4,1,3,7,5,9,6,8 // This should be from back to front: Down, UpLeft, UpRight, Upper Left Hand, Upper Right Hand
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1338,6 +1316,7 @@ static const Game g_Game_Ez2 =
g_apGame_Ez2_Styles, // m_apStyles
true, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"ez2", // m_szName
NUM_EZ2_BUTTONS, // m_iButtonsPerController
@@ -1404,7 +1383,6 @@ static const Style g_Style_Para_Single =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,0,4,1,3
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1442,7 +1420,6 @@ static const Style g_Style_Para_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
2,0,4,1,3
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1471,6 +1448,7 @@ static const Game g_Game_Para =
g_apGame_Para_Styles, // m_apStyles
false, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"para", // m_szName
NUM_PARA_BUTTONS, // m_iButtonsPerController
@@ -1538,7 +1516,6 @@ static const Style g_Style_DS3DDX_Single =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1569,6 +1546,7 @@ static const Game g_Game_DS3DDX =
g_apGame_DS3DDX_Styles, // m_apStyles
false, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"ds3ddx", // m_szName
NUM_DS3DDX_BUTTONS, // m_iButtonsPerController
@@ -1638,7 +1616,6 @@ static const Style g_Style_Beat_Single5 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1678,7 +1655,6 @@ static const Style g_Style_Beat_Versus5 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1730,7 +1706,6 @@ static const Style g_Style_Beat_Double5 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7,8,9,10,11
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1774,7 +1749,6 @@ static const Style g_Style_Beat_Single7 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1818,7 +1792,6 @@ static const Style g_Style_Beat_Versus7 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1879,7 +1852,6 @@ static const Style g_Style_Beat_Double7 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -1915,6 +1887,7 @@ static const Game g_Game_Beat =
g_apGame_Beat_Styles, // m_apStyles
true, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"beat", // m_szName
NUM_BEAT_BUTTONS, // m_iButtonsPerController
@@ -1982,7 +1955,6 @@ static const Style g_Style_Maniax_Single =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2018,7 +1990,6 @@ static const Style g_Style_Maniax_Versus =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2062,7 +2033,6 @@ static const Style g_Style_Maniax_Double =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2095,6 +2065,7 @@ static const Game g_Game_Maniax =
g_apGame_Maniax_Styles, // m_apStyles
false, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"maniax", // m_szName
NUM_MANIAX_BUTTONS, // m_iButtonsPerController
@@ -2124,7 +2095,6 @@ static const Game g_Game_Maniax =
//ThemeMetric TECHNO_COL_SPACING ("ColumnSpacing","Techno");
static const int TECHNO_COL_SPACING = 56;
//ThemeMetric TECHNO_VERSUS_COL_SPACING ("ColumnSpacing","TechnoVersus");
-static const int TECHNO_VERSUS_COL_SPACING = 33;
static const Style g_Style_Techno_Single4 =
{ // STYLE_TECHNO_SINGLE4
true, // m_bUsedForGameplay
@@ -2156,7 +2126,6 @@ static const Style g_Style_Techno_Single4 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2196,7 +2165,6 @@ static const Style g_Style_Techno_Single5 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2240,7 +2208,6 @@ static const Style g_Style_Techno_Single8 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- true, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2276,7 +2243,6 @@ static const Style g_Style_Techno_Versus4 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2316,7 +2282,6 @@ static const Style g_Style_Techno_Versus5 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2333,24 +2298,24 @@ static const Style g_Style_Techno_Versus8 =
8, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
- { TRACK_1, -TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
- { TRACK_2, -TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_3, -TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_4, -TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_5, +TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_6, +TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_7, +TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_8, +TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
+ { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL },
+ { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL },
},
{ // PLAYER_2
- { TRACK_1, -TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
- { TRACK_2, -TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_3, -TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_4, -TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_5, +TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_6, +TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_7, +TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_8, +TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
+ { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL },
+ { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL },
},
},
{ // m_iInputColumn[NUM_GameController][NUM_GameButton]
@@ -2362,7 +2327,6 @@ static const Style g_Style_Techno_Versus8 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- true, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2406,7 +2370,6 @@ static const Style g_Style_Techno_Double4 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2466,7 +2429,6 @@ static const Style g_Style_Techno_Double5 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7,8,9
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2483,40 +2445,40 @@ static const Style g_Style_Techno_Double8 =
16, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
- { TRACK_1, -TECHNO_VERSUS_COL_SPACING*7.5f, NULL },
- { TRACK_2, -TECHNO_VERSUS_COL_SPACING*6.5f, NULL },
- { TRACK_3, -TECHNO_VERSUS_COL_SPACING*5.5f, NULL },
- { TRACK_4, -TECHNO_VERSUS_COL_SPACING*4.5f, NULL },
- { TRACK_5, -TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
- { TRACK_6, -TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_7, -TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_8, -TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_9, +TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_10, +TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_11, +TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_12, +TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
- { TRACK_13, +TECHNO_VERSUS_COL_SPACING*4.5f, NULL },
- { TRACK_14, +TECHNO_VERSUS_COL_SPACING*5.5f, NULL },
- { TRACK_15, +TECHNO_VERSUS_COL_SPACING*6.5f, NULL },
- { TRACK_16, +TECHNO_VERSUS_COL_SPACING*7.5f, NULL },
+ { TRACK_1, -TECHNO_COL_SPACING*7.5f, NULL },
+ { TRACK_2, -TECHNO_COL_SPACING*6.5f, NULL },
+ { TRACK_3, -TECHNO_COL_SPACING*5.5f, NULL },
+ { TRACK_4, -TECHNO_COL_SPACING*4.5f, NULL },
+ { TRACK_5, -TECHNO_COL_SPACING*3.5f, NULL },
+ { TRACK_6, -TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_7, -TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_8, -TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_9, +TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_10, +TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_11, +TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_12, +TECHNO_COL_SPACING*3.5f, NULL },
+ { TRACK_13, +TECHNO_COL_SPACING*4.5f, NULL },
+ { TRACK_14, +TECHNO_COL_SPACING*5.5f, NULL },
+ { TRACK_15, +TECHNO_COL_SPACING*6.5f, NULL },
+ { TRACK_16, +TECHNO_COL_SPACING*7.5f, NULL },
},
{ // PLAYER_2
- { TRACK_1, -TECHNO_VERSUS_COL_SPACING*7.5f, NULL },
- { TRACK_2, -TECHNO_VERSUS_COL_SPACING*6.5f, NULL },
- { TRACK_3, -TECHNO_VERSUS_COL_SPACING*5.5f, NULL },
- { TRACK_4, -TECHNO_VERSUS_COL_SPACING*4.5f, NULL },
- { TRACK_5, -TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
- { TRACK_6, -TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_7, -TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_8, -TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_9, +TECHNO_VERSUS_COL_SPACING*0.5f, NULL },
- { TRACK_10, +TECHNO_VERSUS_COL_SPACING*1.5f, NULL },
- { TRACK_11, +TECHNO_VERSUS_COL_SPACING*2.5f, NULL },
- { TRACK_12, +TECHNO_VERSUS_COL_SPACING*3.5f, NULL },
- { TRACK_13, +TECHNO_VERSUS_COL_SPACING*4.5f, NULL },
- { TRACK_14, +TECHNO_VERSUS_COL_SPACING*5.5f, NULL },
- { TRACK_15, +TECHNO_VERSUS_COL_SPACING*6.5f, NULL },
- { TRACK_16, +TECHNO_VERSUS_COL_SPACING*7.5f, NULL },
+ { TRACK_1, -TECHNO_COL_SPACING*7.5f, NULL },
+ { TRACK_2, -TECHNO_COL_SPACING*6.5f, NULL },
+ { TRACK_3, -TECHNO_COL_SPACING*5.5f, NULL },
+ { TRACK_4, -TECHNO_COL_SPACING*4.5f, NULL },
+ { TRACK_5, -TECHNO_COL_SPACING*3.5f, NULL },
+ { TRACK_6, -TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_7, -TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_8, -TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_9, +TECHNO_COL_SPACING*0.5f, NULL },
+ { TRACK_10, +TECHNO_COL_SPACING*1.5f, NULL },
+ { TRACK_11, +TECHNO_COL_SPACING*2.5f, NULL },
+ { TRACK_12, +TECHNO_COL_SPACING*3.5f, NULL },
+ { TRACK_13, +TECHNO_COL_SPACING*4.5f, NULL },
+ { TRACK_14, +TECHNO_COL_SPACING*5.5f, NULL },
+ { TRACK_15, +TECHNO_COL_SPACING*6.5f, NULL },
+ { TRACK_16, +TECHNO_COL_SPACING*7.5f, NULL },
},
},
{ // m_iInputColumn[NUM_GameController][NUM_GameButton]
@@ -2526,7 +2488,6 @@ static const Style g_Style_Techno_Double8 =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2575,6 +2536,7 @@ static const Game g_Game_Techno =
g_apGame_Techno_Styles, // m_apStyles
false, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"techno", // m_szName
NUM_TECHNO_BUTTONS, // m_iButtonsPerController
@@ -2647,7 +2609,6 @@ static const Style g_Style_Popn_Five =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2693,7 +2654,6 @@ static const Style g_Style_Popn_Nine =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7,8
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2726,6 +2686,7 @@ static const Game g_Game_Popn =
g_apGame_Popn_Styles, // m_apStyles
true, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"popn", // m_szName
NUM_POPN_BUTTONS, // m_iButtonsPerController
@@ -2815,7 +2776,6 @@ static const Style g_Style_Lights_Cabinet =
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4,5,6,7
},
- false, // m_bNeedsZoomOutWith2Players
false, // m_bCanUseBeginnerHelper
false, // m_bLockDifficulties
};
@@ -2832,6 +2792,7 @@ static const Game g_Game_Lights =
g_apGame_Lights_Styles, // m_apStyles
false, // m_bCountNotesSeparately
false, // m_bTickHolds
+ false, // m_PlayersHaveSeparateStyles
{ // m_InputScheme
"lights", // m_szName
NUM_LIGHTS_BUTTONS, // m_iButtonsPerController
@@ -2897,14 +2858,14 @@ static const int KICKBOX_COL_SPACING= 64;
static const Style g_Style_Kickbox_Human=
{
- true, // Used for gameplay
- true, // Used for edit
- true, // Used for demonstration
- true, // Used for how to play
- "human", // name
- StepsType_kickbox_human, // stepstype
- StyleType_OnePlayerOneSide, // styletype
- 4, // cols per player
+ true, // m_bUsedForGameplay
+ true, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ true, // m_bUsedForHowToPlay
+ "human", // m_szName
+ StepsType_kickbox_human, // m_StepsType
+ StyleType_OnePlayerOneSide, // m_StyleType
+ 4, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL },
@@ -2926,21 +2887,20 @@ static const Style g_Style_Kickbox_Human=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style g_Style_Kickbox_Human_Versus=
{
- true, // Used for gameplay
- false, // Used for edit
- true, // Used for demonstration
- false, // Used for how to play
- "hversus", // name
- StepsType_kickbox_human, // stepstype
- StyleType_TwoPlayersTwoSides, // styletype
- 4, // cols per player
+ true, // m_bUsedForGameplay
+ false, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ false, // m_bUsedForHowToPlay
+ "hversus", // m_szName
+ StepsType_kickbox_human, // m_StepsType
+ StyleType_TwoPlayersTwoSides, // m_StyleType
+ 4, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL },
@@ -2962,21 +2922,20 @@ static const Style g_Style_Kickbox_Human_Versus=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style g_Style_Kickbox_Quadarm=
{
- true, // Used for gameplay
- true, // Used for edit
- true, // Used for demonstration
- true, // Used for how to play
- "quadarm", // name
- StepsType_kickbox_quadarm, // stepstype
- StyleType_OnePlayerOneSide, // styletype
- 4, // cols per player
+ true, // m_bUsedForGameplay
+ true, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ true, // m_bUsedForHowToPlay
+ "quadarm", // m_szName
+ StepsType_kickbox_quadarm, // m_StepsType
+ StyleType_OnePlayerOneSide, // m_StyleType
+ 4, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL },
@@ -2998,21 +2957,20 @@ static const Style g_Style_Kickbox_Quadarm=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style g_Style_Kickbox_Quadarm_Versus=
{
- true, // Used for gameplay
- false, // Used for edit
- true, // Used for demonstration
- false, // Used for how to play
- "qversus", // name
- StepsType_kickbox_quadarm, // stepstype
- StyleType_TwoPlayersTwoSides, // styletype
- 4, // cols per player
+ true, // m_bUsedForGameplay
+ false, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ false, // m_bUsedForHowToPlay
+ "qversus", // m_szName
+ StepsType_kickbox_quadarm, // m_StepsType
+ StyleType_TwoPlayersTwoSides, // m_StyleType
+ 4, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL },
@@ -3034,21 +2992,20 @@ static const Style g_Style_Kickbox_Quadarm_Versus=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3
},
- false, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style g_Style_Kickbox_Insect=
{
- true, // Used for gameplay
- true, // Used for edit
- true, // Used for demonstration
- true, // Used for how to play
- "insect", // name
- StepsType_kickbox_insect, // stepstype
- StyleType_OnePlayerOneSide, // styletype
- 6, // cols per player
+ true, // m_bUsedForGameplay
+ true, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ true, // m_bUsedForHowToPlay
+ "insect", // m_szName
+ StepsType_kickbox_insect, // m_StepsType
+ StyleType_OnePlayerOneSide, // m_StyleType
+ 6, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*2.5f, NULL },
@@ -3074,21 +3031,20 @@ static const Style g_Style_Kickbox_Insect=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3, 4, 5
},
- false, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style g_Style_Kickbox_Insect_Versus=
{
- true, // Used for gameplay
- false, // Used for edit
- true, // Used for demonstration
- false, // Used for how to play
- "iversus", // name
- StepsType_kickbox_insect, // stepstype
- StyleType_TwoPlayersTwoSides, // styletype
- 6, // cols per player
+ true, // m_bUsedForGameplay
+ false, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ false, // m_bUsedForHowToPlay
+ "iversus", // m_szName
+ StepsType_kickbox_insect, // m_StepsType
+ StyleType_TwoPlayersTwoSides, // m_StyleType
+ 6, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*2.5f, NULL },
@@ -3114,21 +3070,20 @@ static const Style g_Style_Kickbox_Insect_Versus=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3, 4, 5
},
- false, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style g_Style_Kickbox_Arachnid=
{
- true, // Used for gameplay
- true, // Used for edit
- true, // Used for demonstration
- true, // Used for how to play
- "arachnid", // name
- StepsType_kickbox_arachnid, // stepstype
- StyleType_OnePlayerOneSide, // styletype
- 8, // cols per player
+ true, // m_bUsedForGameplay
+ true, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ true, // m_bUsedForHowToPlay
+ "arachnid", // m_szName
+ StepsType_kickbox_arachnid, // m_StepsType
+ StyleType_OnePlayerOneSide, // m_StyleType
+ 8, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*3.5f, NULL },
@@ -3158,21 +3113,20 @@ static const Style g_Style_Kickbox_Arachnid=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3, 4, 5, 6, 7
},
- false, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style g_Style_Kickbox_Arachnid_Versus=
{
- true, // Used for gameplay
- false, // Used for edit
- true, // Used for demonstration
- false, // Used for how to play
- "aversus", // name
- StepsType_kickbox_arachnid, // stepstype
- StyleType_TwoPlayersTwoSides, // styletype
- 8, // cols per player
+ true, // m_bUsedForGameplay
+ false, // m_bUsedForEdit
+ true, // m_bUsedForDemonstration
+ false, // m_bUsedForHowToPlay
+ "aversus", // m_szName
+ StepsType_kickbox_arachnid, // m_StepsType
+ StyleType_TwoPlayersTwoSides, // m_StyleType
+ 8, // m_iColsPerPlayer
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
{ // PLAYER_1
{ TRACK_1, -KICKBOX_COL_SPACING*3.5f, NULL },
@@ -3202,9 +3156,8 @@ static const Style g_Style_Kickbox_Arachnid_Versus=
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0, 1, 2, 3, 4, 5, 6, 7
},
- true, // needs zoom out with 2 players
- false, // can use beginner helper
- false, // lock difficulties
+ false, // m_bCanUseBeginnerHelper
+ false, // m_bLockDifficulties
};
static const Style* g_apGame_Kickbox_Styles[] =
@@ -3222,14 +3175,15 @@ static const Style* g_apGame_Kickbox_Styles[] =
static const Game g_Game_Kickbox =
{
- "kickbox", // name
- g_apGame_Kickbox_Styles, // styles
- true, // count notes separately
- false, // tick holds
- { // input scheme
- "kickbox",
- NUM_KICKBOX_BUTTONS, // buttons per controller
- { // button names
+ "kickbox", // m_szName
+ g_apGame_Kickbox_Styles, // m_apStyles
+ true, // m_bCountNotesSeparately
+ false, // m_bTickHolds
+ true, // m_PlayersHaveSeparateStyles
+ { // m_InputScheme
+ "kickbox", // m_szName
+ NUM_KICKBOX_BUTTONS, // m_iButtonsPerController
+ { // m_szButtonNames
{ "DownLeftFoot", GameButton_Invalid },
{ "UpLeftFoot", GameButton_Invalid },
{ "UpLeftFist", GAME_BUTTON_LEFT },
diff --git a/src/GameState.cpp b/src/GameState.cpp
index 8444616d4a..cac1631f9a 100644
--- a/src/GameState.cpp
+++ b/src/GameState.cpp
@@ -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 &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::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::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::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