separate fail types per player. Now FailType adjustments based on Difficulty only affect the relevant players.

This commit is contained in:
Chris Danford
2005-04-05 08:30:57 +00:00
parent af231d1a63
commit 218be32879
19 changed files with 175 additions and 150 deletions
+6 -22
View File
@@ -597,10 +597,10 @@ void Background::Update( float fDeltaTime )
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
if( IsDangerPlayerVisible(p) ) if( GAMESTATE->IsPlayerInDanger(p) )
m_DangerPlayer[p].Update( fDeltaTime ); m_DangerPlayer[p].Update( fDeltaTime );
if( IsDeadPlayerVisible(p) ) if( GAMESTATE->IsPlayerDead(p) )
m_DeadPlayer[p].Update( fDeltaTime ); m_DeadPlayer[p].Update( fDeltaTime );
} }
@@ -652,9 +652,9 @@ void Background::DrawPrimitives()
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
if( IsDangerPlayerVisible(p) ) if( GAMESTATE->IsPlayerInDanger(p) )
m_DangerPlayer[p].Draw(); m_DangerPlayer[p].Draw();
if( IsDeadPlayerVisible(p) ) if( GAMESTATE->IsPlayerDead(p) )
m_DeadPlayer[p].Draw(); m_DeadPlayer[p].Draw();
} }
} }
@@ -667,7 +667,8 @@ void Background::DrawPrimitives()
bool Background::IsDangerAllVisible() bool Background::IsDangerAllVisible()
{ {
if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF ) FOREACH_PlayerNumber( p )
if( GAMESTATE->GetPlayerFailType(p) == SongOptions::FAIL_OFF )
return false; return false;
if( !PREFSMAN->m_bShowDanger ) if( !PREFSMAN->m_bShowDanger )
return false; return false;
@@ -686,23 +687,6 @@ bool Background::IsDangerAllVisible()
return true; return true;
} }
bool Background::IsDangerPlayerVisible( PlayerNumber pn )
{
if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF )
return false;
if( !PREFSMAN->m_bShowDanger )
return false;
return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DANGER;
}
bool Background::IsDeadPlayerVisible( PlayerNumber pn )
{
if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF )
return false;
return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DEAD;
}
BrightnessOverlay::BrightnessOverlay() BrightnessOverlay::BrightnessOverlay()
{ {
float fQuadWidth = (RIGHT_EDGE-LEFT_EDGE)/2; float fQuadWidth = (RIGHT_EDGE-LEFT_EDGE)/2;
-2
View File
@@ -51,9 +51,7 @@ protected:
void LoadFromRandom( float fFirstBeat, float fLastBeat, const TimingData &timing, CString sPreferredSubDir ); void LoadFromRandom( float fFirstBeat, float fLastBeat, const TimingData &timing, CString sPreferredSubDir );
int FindBGSegmentForBeat( float fBeat ) const; int FindBGSegmentForBeat( float fBeat ) const;
bool IsDangerPlayerVisible( PlayerNumber pn );
bool IsDangerAllVisible(); bool IsDangerAllVisible();
bool IsDeadPlayerVisible( PlayerNumber pn );
void UpdateCurBGChange( float fCurrentTime ); void UpdateCurBGChange( float fCurrentTime );
bool m_bInitted; bool m_bInitted;
+59 -38
View File
@@ -145,7 +145,7 @@ void GameState::Reset()
m_MasterPlayerNumber = PLAYER_INVALID; m_MasterPlayerNumber = PLAYER_INVALID;
m_mapEnv.clear(); m_mapEnv.clear();
m_sPreferredSongGroup = GROUP_ALL_MUSIC; m_sPreferredSongGroup = GROUP_ALL_MUSIC;
m_bChangedFailType = false; m_bChangedFailTypeOnScreenSongOptions = false;
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
m_PreferredDifficulty[p].Set( DIFFICULTY_INVALID ); m_PreferredDifficulty[p].Set( DIFFICULTY_INVALID );
@@ -475,7 +475,7 @@ void GameState::FinishStage()
if( m_bDemonstrationOrJukebox ) if( m_bDemonstrationOrJukebox )
return; return;
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
{ {
const int iSaveProfileEvery = 3; const int iSaveProfileEvery = 3;
if( iOldStageIndex/iSaveProfileEvery < m_iCurrentStageIndex/iSaveProfileEvery ) if( iOldStageIndex/iSaveProfileEvery < m_iCurrentStageIndex/iSaveProfileEvery )
@@ -688,14 +688,14 @@ int GameState::GetNumStagesLeft() const
{ {
if( IsExtraStage() || IsExtraStage2() ) if( IsExtraStage() || IsExtraStage2() )
return 1; return 1;
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
return 999; return 999;
return PREFSMAN->m_iNumArcadeStages - m_iCurrentStageIndex; return PREFSMAN->m_iNumArcadeStages - m_iCurrentStageIndex;
} }
bool GameState::IsFinalStage() const bool GameState::IsFinalStage() const
{ {
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
return false; return false;
if( this->IsCourseMode() ) if( this->IsCourseMode() )
@@ -710,14 +710,14 @@ bool GameState::IsFinalStage() const
bool GameState::IsExtraStage() const bool GameState::IsExtraStage() const
{ {
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
return false; return false;
return m_iCurrentStageIndex == PREFSMAN->m_iNumArcadeStages; return m_iCurrentStageIndex == PREFSMAN->m_iNumArcadeStages;
} }
bool GameState::IsExtraStage2() const bool GameState::IsExtraStage2() const
{ {
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
return false; return false;
return m_iCurrentStageIndex == PREFSMAN->m_iNumArcadeStages+1; return m_iCurrentStageIndex == PREFSMAN->m_iNumArcadeStages+1;
} }
@@ -726,7 +726,7 @@ CString GameState::GetStageText() const
{ {
if( m_bDemonstrationOrJukebox ) return "demo"; if( m_bDemonstrationOrJukebox ) return "demo";
// "event" has precedence // "event" has precedence
else if( GAMESTATE->GetEventMode() ) return "event"; else if( GAMESTATE->IsEventMode() ) return "event";
else if( m_PlayMode == PLAY_MODE_ONI ) return "oni"; else if( m_PlayMode == PLAY_MODE_ONI ) return "oni";
else if( m_PlayMode == PLAY_MODE_NONSTOP ) return "nonstop"; else if( m_PlayMode == PLAY_MODE_NONSTOP ) return "nonstop";
else if( m_PlayMode == PLAY_MODE_ENDLESS ) return "endless"; else if( m_PlayMode == PLAY_MODE_ENDLESS ) return "endless";
@@ -931,7 +931,7 @@ bool GameState::IsBattleMode() const
bool GameState::HasEarnedExtraStage() const bool GameState::HasEarnedExtraStage() const
{ {
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
return false; return false;
if( !PREFSMAN->m_bAllowExtraStage ) if( !PREFSMAN->m_bAllowExtraStage )
@@ -1005,13 +1005,8 @@ StageResult GameState::GetStageResult( PlayerNumber pn ) const
void GameState::ApplyModifiers( PlayerNumber pn, CString sModifiers ) void GameState::ApplyModifiers( PlayerNumber pn, CString sModifiers )
{ {
const SongOptions::FailType ft = this->m_SongOptions.m_FailType;
m_pPlayerState[pn]->m_PlayerOptions.FromString( sModifiers ); m_pPlayerState[pn]->m_PlayerOptions.FromString( sModifiers );
m_SongOptions.FromString( sModifiers ); m_SongOptions.FromString( sModifiers );
if( ft != this->m_SongOptions.m_FailType )
this->m_bChangedFailType = true;
} }
/* Store the player's preferred options. This is called at the very beginning /* Store the player's preferred options. This is called at the very beginning
@@ -1277,38 +1272,44 @@ void setmax( T &a, const T &b )
a = max(a, b); a = max(a, b);
} }
/* Adjust the fail mode based on the chosen difficulty. This must be called SongOptions::FailType GameState::GetPlayerFailType( PlayerNumber pn ) const
* after the difficulty has been finalized (usually in ScreenSelectMusic or
* ScreenPlayerOptions), and before the fail mode is displayed or used (usually
* in ScreenSongOptions). */
void GameState::AdjustFailType()
{ {
/* Single song mode only. */ SongOptions::FailType ft = m_SongOptions.m_FailType;
if( this->IsCourseMode() )
return;
/* If the player changed the fail mode explicitly, leave it alone. */ /* If the player changed the fail mode explicitly, leave it alone. */
if( this->m_bChangedFailType ) if( this->m_bChangedFailTypeOnScreenSongOptions )
return; return ft;
/* Find the easiest difficulty notes selected by either player. */ if( this->IsCourseMode() )
const Difficulty dc = GetEasiestNotesDifficulty(); {
if( PREFSMAN->m_bMinimum1FullSongInCourses && GAMESTATE->IsCourseMode() && GAMESTATE->GetCourseSongIndex()==0 )
ft = max( ft, SongOptions::FAIL_COMBO_OF_30_MISSES ); // take the least harsh of the two FailTypes
}
else
{
Difficulty dc = DIFFICULTY_INVALID;
if( m_pCurSteps[pn] )
dc = m_pCurSteps[pn]->GetDifficulty();
/* Reset the fail type to the default. */ bool bFirstStage = !GAMESTATE->IsEventMode() && m_iCurrentStageIndex == 0;
SongOptions so;
so.FromString( PREFSMAN->m_sDefaultModifiers );
this->m_SongOptions.m_FailType = so.m_FailType;
/* Easy and beginner are never harder than FAIL_END_OF_SONG. */ /* Easy and beginner are never harder than FAIL_END_OF_SONG. */
if( dc <= DIFFICULTY_EASY ) if( dc <= DIFFICULTY_EASY )
setmax(this->m_SongOptions.m_FailType, SongOptions::FAIL_END_OF_SONG); setmax( ft, SongOptions::FAIL_END_OF_SONG );
if( dc <= DIFFICULTY_EASY && bFirstStage && PREFSMAN->m_bFailOffForFirstStageEasy )
setmax( ft, SongOptions::FAIL_OFF );
/* If beginner's steps were chosen, and this is the first stage, /* If beginner's steps were chosen, and this is the first stage,
* turn off failure completely--always give a second try. */ * turn off failure completely. */
if(dc == DIFFICULTY_BEGINNER && if( dc == DIFFICULTY_BEGINNER && bFirstStage )
GAMESTATE->GetEventMode() && /* stage index is meaningless in event mode */ setmax( ft, SongOptions::FAIL_OFF );
this->m_iCurrentStageIndex == 0)
setmax(this->m_SongOptions.m_FailType, SongOptions::FAIL_OFF); if( dc == DIFFICULTY_BEGINNER && PREFSMAN->m_bFailOffInBeginner )
setmax( ft, SongOptions::FAIL_OFF );
}
return ft;
} }
bool GameState::ShowMarvelous() const bool GameState::ShowMarvelous() const
@@ -1788,14 +1789,14 @@ Difficulty GameState::GetEasiestNotesDifficulty() const
return dc; return dc;
} }
bool GameState::GetEventMode() bool GameState::IsEventMode() const
{ {
return m_bTemporaryEventMode || PREFSMAN->m_bEventMode; return m_bTemporaryEventMode || PREFSMAN->m_bEventMode;
} }
CoinMode GameState::GetCoinMode() CoinMode GameState::GetCoinMode()
{ {
if( GetEventMode() && PREFSMAN->m_CoinMode == COIN_PAY ) if( IsEventMode() && PREFSMAN->m_CoinMode == COIN_PAY )
return COIN_FREE; return COIN_FREE;
else else
return PREFSMAN->m_CoinMode; return PREFSMAN->m_CoinMode;
@@ -1803,12 +1804,32 @@ CoinMode GameState::GetCoinMode()
Premium GameState::GetPremium() Premium GameState::GetPremium()
{ {
if( GetEventMode() ) if( IsEventMode() )
return PREMIUM_NONE; return PREMIUM_NONE;
else else
return PREFSMAN->m_Premium; return PREFSMAN->m_Premium;
} }
bool GameState::IsPlayerHot( PlayerNumber pn ) const
{
return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::HOT;
}
bool GameState::IsPlayerInDanger( PlayerNumber pn ) const
{
if( GAMESTATE->GetPlayerFailType(pn) == SongOptions::FAIL_OFF )
return false;
if( !PREFSMAN->m_bShowDanger )
return false;
return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DANGER;
}
bool GameState::IsPlayerDead( PlayerNumber pn ) const
{
if( GAMESTATE->GetPlayerFailType(pn) == SongOptions::FAIL_OFF )
return false;
return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DEAD;
}
+7 -3
View File
@@ -10,6 +10,7 @@
#include "RageTimer.h" #include "RageTimer.h"
#include "Difficulty.h" #include "Difficulty.h"
#include "MessageManager.h" #include "MessageManager.h"
#include "SongOptions.h"
#include <map> #include <map>
#include <deque> #include <deque>
@@ -101,7 +102,7 @@ public:
CString m_sLoadingMessage; // used in loading screen CString m_sLoadingMessage; // used in loading screen
CString m_sPreferredSongGroup; // GROUP_ALL_MUSIC denotes no preferred group CString m_sPreferredSongGroup; // GROUP_ALL_MUSIC denotes no preferred group
bool m_bChangedFailType; // true if FailType was changed in the song options screen bool m_bChangedFailTypeOnScreenSongOptions; // true if FailType was changed in the song options screen
BroadcastOnChange1D<Difficulty,NUM_PLAYERS> m_PreferredDifficulty; BroadcastOnChange1D<Difficulty,NUM_PLAYERS> m_PreferredDifficulty;
SortOrder m_PreferredSortOrder; // used by MusicWheel SortOrder m_PreferredSortOrder; // used by MusicWheel
bool m_bEditing; // NoteField does special stuff when this is true bool m_bEditing; // NoteField does special stuff when this is true
@@ -165,6 +166,9 @@ public:
void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp = RageZeroTimer ); void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp = RageZeroTimer );
float GetSongPercent( float beat ) const; float GetSongPercent( float beat ) const;
bool IsPlayerHot( PlayerNumber pn ) const;
bool IsPlayerInDanger( PlayerNumber pn ) const;
bool IsPlayerDead( PlayerNumber pn ) const;
bool AllAreInDangerOrWorse() const; bool AllAreInDangerOrWorse() const;
bool AllAreDead() const; bool AllAreDead() const;
bool AllHaveComboOf30OrMoreMisses() const; bool AllHaveComboOf30OrMoreMisses() const;
@@ -209,7 +213,7 @@ public:
bool IsDisqualified( PlayerNumber pn ); bool IsDisqualified( PlayerNumber pn );
void AdjustFailType(); SongOptions::FailType GetPlayerFailType( PlayerNumber pn ) const;
// character stuff // character stuff
private: private:
@@ -275,7 +279,7 @@ public:
// These options have weird interactions depending on m_bEventMode, // These options have weird interactions depending on m_bEventMode,
// so wrap them // so wrap them
bool m_bTemporaryEventMode; bool m_bTemporaryEventMode;
bool GetEventMode(); bool IsEventMode() const;
CoinMode GetCoinMode(); CoinMode GetCoinMode();
Premium GetPremium(); Premium GetPremium();
+9 -6
View File
@@ -291,7 +291,7 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
default: default:
ASSERT(0); ASSERT(0);
} }
if( IsHot() && score < TNS_GOOD ) if( GAMESTATE->IsPlayerHot(m_PlayerNumber) && score < TNS_GOOD )
fDeltaLife = -0.10f; // make it take a while to get back to "doing great" fDeltaLife = -0.10f; // make it take a while to get back to "doing great"
break; break;
case SongOptions::DRAIN_NO_RECOVER: case SongOptions::DRAIN_NO_RECOVER:
@@ -347,7 +347,7 @@ void LifeMeterBar::ChangeLife( HoldNoteScore score, TapNoteScore tscore )
default: default:
ASSERT(0); ASSERT(0);
} }
if( IsHot() && score == HNS_NG ) if( GAMESTATE->IsPlayerHot(m_PlayerNumber) && score == HNS_NG )
fDeltaLife = -0.10f; // make it take a while to get back to "doing great" fDeltaLife = -0.10f; // make it take a while to get back to "doing great"
break; break;
case SongOptions::DRAIN_NO_RECOVER: case SongOptions::DRAIN_NO_RECOVER:
@@ -477,13 +477,16 @@ void LifeMeterBar::Update( float fDeltaTime )
// HACK: Tweaking these values is very difficulty. Update the // HACK: Tweaking these values is very difficulty. Update the
// "physics" many times so that the spring motion appears faster // "physics" many times so that the spring motion appears faster
bool bIsDead = GAMESTATE->IsPlayerDead(m_PlayerNumber);
bool bIsHot = GAMESTATE->IsPlayerHot(m_PlayerNumber);
for( int i=0; i<10; i++ ) for( int i=0; i<10; i++ )
{ {
const float fDelta = m_fLifePercentage - m_fTrailingLifePercentage; const float fDelta = m_fLifePercentage - m_fTrailingLifePercentage;
// Don't apply spring and viscous forces if we're full or empty. // Don't apply spring and viscous forces if we're full or empty.
// Just move straight to either full or empty. // Just move straight to either full or empty.
if( IsFailing() || IsHot() ) if( bIsDead || bIsHot )
{ {
m_fLifeVelocity = (fDelta / fabsf(fDelta)) * 4; m_fLifeVelocity = (fDelta / fabsf(fDelta)) * 4;
} }
@@ -508,10 +511,10 @@ void LifeMeterBar::Update( float fDeltaTime )
m_fPassingAlpha += IsPastPassmark() ? +fDeltaTime*2 : -fDeltaTime*2; m_fPassingAlpha += IsPastPassmark() ? +fDeltaTime*2 : -fDeltaTime*2;
CLAMP( m_fPassingAlpha, 0, 1 ); CLAMP( m_fPassingAlpha, 0, 1 );
m_fHotAlpha += IsHot() ? + fDeltaTime*2 : -fDeltaTime*2; m_fHotAlpha += bIsHot ? + fDeltaTime*2 : -fDeltaTime*2;
CLAMP( m_fHotAlpha, 0, 1 ); CLAMP( m_fHotAlpha, 0, 1 );
if( IsHot() ) if( bIsHot )
m_fLifeVelocity = max( 0, m_fLifeVelocity ); m_fLifeVelocity = max( 0, m_fLifeVelocity );
} }
@@ -523,7 +526,7 @@ void LifeMeterBar::DrawPrimitives()
m_pStream->m_fHotAlpha = m_fHotAlpha; m_pStream->m_fHotAlpha = m_fHotAlpha;
float fPercentRed = 0; float fPercentRed = 0;
if( IsFailing() ) if( GAMESTATE->IsPlayerDead(m_PlayerNumber) )
fPercentRed = 0; fPercentRed = 0;
else if( m_fTrailingLifePercentage<DANGER_THRESHOLD ) else if( m_fTrailingLifePercentage<DANGER_THRESHOLD )
fPercentRed = RageFastSin( RageTimer::GetTimeSinceStartFast()*PI*4 )/2+0.5f; fPercentRed = RageFastSin( RageTimer::GetTimeSinceStartFast()*PI*4 )/2+0.5f;
+2 -2
View File
@@ -251,7 +251,7 @@ void MusicWheel::Load( CString sType )
// but someone mentioned it does it sometimes. // but someone mentioned it does it sometimes.
if( GAMESTATE->m_pCurSong != NULL && if( GAMESTATE->m_pCurSong != NULL &&
SongManager::GetNumStagesForSong( GAMESTATE->m_pCurSong ) + GAMESTATE->m_iCurrentStageIndex > PREFSMAN->m_iNumArcadeStages SongManager::GetNumStagesForSong( GAMESTATE->m_pCurSong ) + GAMESTATE->m_iCurrentStageIndex > PREFSMAN->m_iNumArcadeStages
&& !GAMESTATE->GetEventMode() && !GAMESTATE->IsEventMode()
&& !GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2() ) && !GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2() )
{ {
GAMESTATE->m_pCurSong.Set( NULL ); GAMESTATE->m_pCurSong.Set( NULL );
@@ -498,7 +498,7 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
case SORT_ONI_COURSES: case SORT_ONI_COURSES:
case SORT_ENDLESS_COURSES: case SORT_ENDLESS_COURSES:
/* Don't display course modes after the first stage. */ /* Don't display course modes after the first stage. */
if( !GAMESTATE->GetEventMode() && GAMESTATE->m_iCurrentStageIndex ) if( !GAMESTATE->IsEventMode() && GAMESTATE->m_iCurrentStageIndex )
continue; continue;
} }
+6
View File
@@ -150,6 +150,8 @@ void PrefsManager::Init()
m_bTwoPlayerRecovery = true; m_bTwoPlayerRecovery = true;
m_bMercifulDrain = true; m_bMercifulDrain = true;
m_bMinimum1FullSongInCourses = false; m_bMinimum1FullSongInCourses = false;
m_bFailOffInBeginner = false;
m_bFailOffForFirstStageEasy = false;
m_iPercentScoreWeightMarvelous = 3; m_iPercentScoreWeightMarvelous = 3;
m_iPercentScoreWeightPerfect = 2; m_iPercentScoreWeightPerfect = 2;
@@ -383,6 +385,8 @@ void PrefsManager::ReadGlobalPrefsFromIni( const IniFile &ini )
ini.GetValue( "Options", "TwoPlayerRecovery", m_bTwoPlayerRecovery ); ini.GetValue( "Options", "TwoPlayerRecovery", m_bTwoPlayerRecovery );
ini.GetValue( "Options", "MercifulDrain", m_bMercifulDrain ); ini.GetValue( "Options", "MercifulDrain", m_bMercifulDrain );
ini.GetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses ); ini.GetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses );
ini.GetValue( "Options", "FailOffInBeginner", m_bFailOffInBeginner );
ini.GetValue( "Options", "FailOffForFirstStageEasy", m_bFailOffForFirstStageEasy );
ini.GetValue( "Options", "PercentScoreWeightMarvelous", m_iPercentScoreWeightMarvelous ); ini.GetValue( "Options", "PercentScoreWeightMarvelous", m_iPercentScoreWeightMarvelous );
ini.GetValue( "Options", "PercentScoreWeightPerfect", m_iPercentScoreWeightPerfect ); ini.GetValue( "Options", "PercentScoreWeightPerfect", m_iPercentScoreWeightPerfect );
@@ -600,6 +604,8 @@ void PrefsManager::SaveGlobalPrefsToIni( IniFile &ini ) const
ini.SetValue( "Options", "TwoPlayerRecovery", m_bTwoPlayerRecovery ); ini.SetValue( "Options", "TwoPlayerRecovery", m_bTwoPlayerRecovery );
ini.SetValue( "Options", "MercifulDrain", m_bMercifulDrain ); ini.SetValue( "Options", "MercifulDrain", m_bMercifulDrain );
ini.SetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses ); ini.SetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses );
ini.SetValue( "Options", "FailOffInBeginner", m_bFailOffInBeginner );
ini.SetValue( "Options", "FailOffForFirstStageEasy", m_bFailOffForFirstStageEasy );
ini.SetValue( "Options", "PercentScoreWeightMarvelous", m_iPercentScoreWeightMarvelous ); ini.SetValue( "Options", "PercentScoreWeightMarvelous", m_iPercentScoreWeightMarvelous );
ini.SetValue( "Options", "PercentScoreWeightPerfect", m_iPercentScoreWeightPerfect ); ini.SetValue( "Options", "PercentScoreWeightPerfect", m_iPercentScoreWeightPerfect );
+2
View File
@@ -96,6 +96,8 @@ public:
bool m_bTwoPlayerRecovery; bool m_bTwoPlayerRecovery;
bool m_bMercifulDrain; // negative life deltas are scaled by the players life percentage bool m_bMercifulDrain; // negative life deltas are scaled by the players life percentage
bool m_bMinimum1FullSongInCourses; // FEoS for 1st song, FailImmediate thereafter bool m_bMinimum1FullSongInCourses; // FEoS for 1st song, FailImmediate thereafter
bool m_bFailOffInBeginner;
bool m_bFailOffForFirstStageEasy;
// percent score (the number that is shown on the screen and saved to memory card) // percent score (the number that is shown on the screen and saved to memory card)
int m_iPercentScoreWeightMarvelous; int m_iPercentScoreWeightMarvelous;
+2 -2
View File
@@ -379,7 +379,7 @@ void ProfileManager::AddStepsScore( const Song* pSong, const Steps* pSteps, Play
// In event mode, set the score's name immediately to the Profile's last // In event mode, set the score's name immediately to the Profile's last
// used name. If no profile last used name exists, use "EVNT". // used name. If no profile last used name exists, use "EVNT".
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
{ {
Profile* pProfile = PROFILEMAN->GetProfile(pn); Profile* pProfile = PROFILEMAN->GetProfile(pn);
if( pProfile && !pProfile->m_sLastUsedHighScoreName.empty() ) if( pProfile && !pProfile->m_sLastUsedHighScoreName.empty() )
@@ -448,7 +448,7 @@ void ProfileManager::AddCourseScore( const Course* pCourse, const Trail* pTrail,
// In event mode, set the score's name immediately to the Profile's last // In event mode, set the score's name immediately to the Profile's last
// used name. If no profile last used name exists, use "EVNT". // used name. If no profile last used name exists, use "EVNT".
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
{ {
Profile* pProfile = PROFILEMAN->GetProfile(pn); Profile* pProfile = PROFILEMAN->GetProfile(pn);
if( pProfile && !pProfile->m_sLastUsedHighScoreName.empty() ) if( pProfile && !pProfile->m_sLastUsedHighScoreName.empty() )
+2 -2
View File
@@ -1355,7 +1355,7 @@ void ScreenEvaluation::HandleScreenMessage( const ScreenMessage SM )
} }
else if( SM == SM_GoToNextScreen ) else if( SM == SM_GoToNextScreen )
{ {
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
{ {
SCREENMAN->SetNewScreen( NEXT_SCREEN ); SCREENMAN->SetNewScreen( NEXT_SCREEN );
} }
@@ -1460,7 +1460,7 @@ void ScreenEvaluation::EndScreen()
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
m_Grades[p].SettleImmediately(); m_Grades[p].SettleImmediately();
if( !GAMESTATE->GetEventMode() ) if( !GAMESTATE->IsEventMode() )
{ {
switch( m_Type ) switch( m_Type )
{ {
+29 -29
View File
@@ -133,10 +133,6 @@ void ScreenGameplay::Init()
if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL ) if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL )
return; // ScreenDemonstration will move us to the next screen. We just need to survive for one update without crashing. return; // ScreenDemonstration will move us to the next screen. We just need to survive for one update without crashing.
/* This is usually done already, but we might have come here without going through
* ScreenSelectMusic or the options menus at all. */
GAMESTATE->AdjustFailType();
/* Save selected options before we change them. */ /* Save selected options before we change them. */
GAMESTATE->StoreSelectedOptions(); GAMESTATE->StoreSelectedOptions();
@@ -905,7 +901,10 @@ void ScreenGameplay::LoadNextSong()
if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BATTERY && STATSMAN->m_CurStageStats.m_player[p].bFailed ) // already failed if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BATTERY && STATSMAN->m_CurStageStats.m_player[p].bFailed ) // already failed
ShowOniGameOver(p); ShowOniGameOver(p);
if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BAR && GAMESTATE->m_PlayMode == PLAY_MODE_REGULAR && !GAMESTATE->GetEventMode() && !GAMESTATE->m_bDemonstrationOrJukebox) if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BAR &&
GAMESTATE->m_PlayMode == PLAY_MODE_REGULAR &&
!GAMESTATE->IsEventMode() &&
!GAMESTATE->m_bDemonstrationOrJukebox )
{ {
m_pLifeMeter[p]->UpdateNonstopLifebar( m_pLifeMeter[p]->UpdateNonstopLifebar(
GAMESTATE->GetStageIndex(), GAMESTATE->GetStageIndex(),
@@ -1333,15 +1332,13 @@ void ScreenGameplay::Update( float fDeltaTime )
case STATE_DANCING: case STATE_DANCING:
/* Set STATSMAN->m_CurStageStats.bFailed for failed players. In, FAIL_IMMEDIATE, send /* Set STATSMAN->m_CurStageStats.bFailed for failed players. In, FAIL_IMMEDIATE, send
* SM_BeginFailed if all players failed, and kill dead Oni players. */ * SM_BeginFailed if all players failed, and kill dead Oni players. */
switch( GAMESTATE->m_SongOptions.m_FailType )
{
case SongOptions::FAIL_OFF:
// don't allow fail
break;
default:
// check for individual fail
FOREACH_EnabledPlayer( pn ) FOREACH_EnabledPlayer( pn )
{ {
SongOptions::FailType ft = GAMESTATE->GetPlayerFailType(pn);
if( ft == SongOptions::FAIL_OFF )
continue;
// check for individual fail
if( (m_pLifeMeter[pn] && !m_pLifeMeter[pn]->IsFailing()) || if( (m_pLifeMeter[pn] && !m_pLifeMeter[pn]->IsFailing()) ||
(m_pCombinedLifeMeter && !m_pCombinedLifeMeter->IsFailing(pn)) ) (m_pCombinedLifeMeter && !m_pCombinedLifeMeter->IsFailing(pn)) )
continue; /* isn't failing */ continue; /* isn't failing */
@@ -1357,8 +1354,8 @@ void ScreenGameplay::Update( float fDeltaTime )
LOG->Trace("Player %d failed", (int)pn); LOG->Trace("Player %d failed", (int)pn);
STATSMAN->m_CurStageStats.m_player[pn].bFailed = true; // fail STATSMAN->m_CurStageStats.m_player[pn].bFailed = true; // fail
if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && if( ft == SongOptions::LIFE_BATTERY &&
GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_IMMEDIATE ) ft == SongOptions::FAIL_IMMEDIATE )
{ {
if( !STATSMAN->m_CurStageStats.AllFailedEarlier() ) // if not the last one to fail if( !STATSMAN->m_CurStageStats.AllFailedEarlier() ) // if not the last one to fail
{ {
@@ -1370,30 +1367,33 @@ void ScreenGameplay::Update( float fDeltaTime )
} }
} }
} }
break;
}
/* If FAIL_IMMEDIATE and everyone is failing, start SM_BeginFailed. */ bool bAllFailed = true;
bool bBeginFailed = false; FOREACH_EnabledPlayer( pn )
SongOptions::FailType ft = GAMESTATE->m_SongOptions.m_FailType;
if( PREFSMAN->m_bMinimum1FullSongInCourses && GAMESTATE->IsCourseMode() && GAMESTATE->GetCourseSongIndex()==0 )
{ {
// take the least harsh of the two FailTypes SongOptions::FailType ft = GAMESTATE->GetPlayerFailType(pn);
ft = max( ft, SongOptions::FAIL_COMBO_OF_30_MISSES );
}
switch( ft ) switch( ft )
{ {
case SongOptions::FAIL_IMMEDIATE: case SongOptions::FAIL_IMMEDIATE:
if( GAMESTATE->AllAreDead() ) if( GAMESTATE->m_pPlayerState[pn]->m_HealthState < PlayerState::DEAD )
bBeginFailed = true; bAllFailed = false;
break; break;
case SongOptions::FAIL_COMBO_OF_30_MISSES: case SongOptions::FAIL_COMBO_OF_30_MISSES:
if( GAMESTATE->AllHaveComboOf30OrMoreMisses() ) if( STATSMAN->m_CurStageStats.m_player[pn].iCurMissCombo < 30 )
bBeginFailed = true; bAllFailed = false;
break; break;
case SongOptions::FAIL_END_OF_SONG:
bAllFailed = false; // wait until the end of the song to fail.
break;
case SongOptions::FAIL_OFF:
bAllFailed = false; // never fail.
break;
default:
ASSERT(0);
}
} }
if( bBeginFailed ) if( bAllFailed )
SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 ); SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 );
// //
@@ -2106,7 +2106,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
} }
/* Mark failure. This hasn't been done yet if m_bTwoPlayerRecovery is set. */ /* Mark failure. This hasn't been done yet if m_bTwoPlayerRecovery is set. */
if( GAMESTATE->m_SongOptions.m_FailType != SongOptions::FAIL_OFF && if( GAMESTATE->GetPlayerFailType(p) != SongOptions::FAIL_OFF &&
(m_pLifeMeter[p] && m_pLifeMeter[p]->IsFailing()) || (m_pLifeMeter[p] && m_pLifeMeter[p]->IsFailing()) ||
(m_pCombinedLifeMeter && m_pCombinedLifeMeter->IsFailing(p)) ) (m_pCombinedLifeMeter && m_pCombinedLifeMeter->IsFailing(p)) )
STATSMAN->m_CurStageStats.m_player[p].bFailed = true; STATSMAN->m_CurStageStats.m_player[p].bFailed = true;
@@ -64,10 +64,6 @@ void ScreenGameplayMultiplayer::Init()
if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL ) 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. return; // ScreenDemonstration will move us to the next scren. We just need to survive for one update without crashing.
/* This is usually done already, but we might have come here without going through
* ScreenSelectMusic or the options menus at all. */
GAMESTATE->AdjustFailType();
/* Save selected options before we change them. */ /* Save selected options before we change them. */
GAMESTATE->StoreSelectedOptions(); GAMESTATE->StoreSelectedOptions();
+3 -1
View File
@@ -398,7 +398,9 @@ static void DefaultFailType( int &sel, bool ToSel, const ConfOption *pConfOption
SongOptions so; SongOptions so;
so.FromString( PREFSMAN->m_sDefaultModifiers ); so.FromString( PREFSMAN->m_sDefaultModifiers );
sel = so.m_FailType; sel = so.m_FailType;
} else { }
else
{
PlayerOptions po; PlayerOptions po;
SongOptions so; SongOptions so;
GetDefaultModifiers( po, so ); GetDefaultModifiers( po, so );
-2
View File
@@ -95,8 +95,6 @@ void ScreenPlayerOptions::GoToNextScreen()
} }
else else
{ {
GAMESTATE->AdjustFailType();
if( m_bGoToOptions ) if( m_bGoToOptions )
SCREENMAN->SetNewScreen( NEXT_SCREEN ); SCREENMAN->SetNewScreen( NEXT_SCREEN );
else else
+1 -2
View File
@@ -1113,7 +1113,6 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
} }
else else
{ {
GAMESTATE->AdjustFailType();
SOUND->StopMusic(); SOUND->StopMusic();
SCREENMAN->SetNewScreen( NEXT_SCREEN ); SCREENMAN->SetNewScreen( NEXT_SCREEN );
} }
@@ -1170,7 +1169,7 @@ void ScreenSelectMusic::MenuStart( PlayerNumber pn )
/* See if this song is a repeat. If we're in event mode, only check the last five songs. */ /* See if this song is a repeat. If we're in event mode, only check the last five songs. */
bool bIsRepeat = false; bool bIsRepeat = false;
int i = 0; int i = 0;
if( GAMESTATE->GetEventMode() ) if( GAMESTATE->IsEventMode() )
i = max( 0, int(STATSMAN->m_vPlayedStageStats.size())-5 ); i = max( 0, int(STATSMAN->m_vPlayedStageStats.size())-5 );
for( ; i < (int)STATSMAN->m_vPlayedStageStats.size(); ++i ) for( ; i < (int)STATSMAN->m_vPlayedStageStats.size(); ++i )
if( STATSMAN->m_vPlayedStageStats[i].vpSongs.back() == m_MusicWheel.GetSelectedSong() ) if( STATSMAN->m_vPlayedStageStats[i].vpSongs.back() == m_MusicWheel.GetSelectedSong() )
+10
View File
@@ -36,6 +36,16 @@ void ScreenSongOptions::Init()
} }
} }
void ScreenSongOptions::ExportOptions( int row, const vector<PlayerNumber> &vpns )
{
const SongOptions::FailType ft = GAMESTATE->m_SongOptions.m_FailType;
ScreenOptionsMaster::ExportOptions( row, vpns );
if( ft != GAMESTATE->m_SongOptions.m_FailType )
GAMESTATE->m_bChangedFailTypeOnScreenSongOptions = true;
}
void ScreenSongOptions::GoToPrevScreen() void ScreenSongOptions::GoToPrevScreen()
{ {
if( GAMESTATE->m_bEditing ) if( GAMESTATE->m_bEditing )
+2
View File
@@ -13,6 +13,8 @@ public:
static CString GetNextScreen(); static CString GetNextScreen();
private: private:
virtual void ExportOptions( int row, const vector<PlayerNumber> &vpns );
void GoToNextScreen(); void GoToNextScreen();
void GoToPrevScreen(); void GoToPrevScreen();
}; };
+1 -1
View File
@@ -82,7 +82,7 @@ void ScreenTitleMenu::Init()
m_textMaxStages.LoadFromFont( THEME->GetPathF(m_sName,"MaxStages") ); m_textMaxStages.LoadFromFont( THEME->GetPathF(m_sName,"MaxStages") );
m_textMaxStages.SetName( "MaxStages" ); m_textMaxStages.SetName( "MaxStages" );
CString sText = CString sText =
GAMESTATE->GetEventMode() ? GAMESTATE->IsEventMode() ?
CString("event mode") : CString("event mode") :
ssprintf( "%d %s%s max", PREFSMAN->m_iNumArcadeStages.Value(), MAX_STAGES_TEXT.c_str(), (PREFSMAN->m_iNumArcadeStages>1)?"s":"" ); ssprintf( "%d %s%s max", PREFSMAN->m_iNumArcadeStages.Value(), MAX_STAGES_TEXT.c_str(), (PREFSMAN->m_iNumArcadeStages>1)?"s":"" );
m_textMaxStages.SetText( sText ); m_textMaxStages.SetText( sText );
+1 -1
View File
@@ -1453,7 +1453,7 @@ static void HandleInputEvents(float fDeltaTime)
continue; // skip continue; // skip
// check back in event mode // check back in event mode
if( GAMESTATE->GetEventMode() && if( GAMESTATE->IsEventMode() &&
CodeDetector::EnteredCode(GameI.controller,CodeDetector::CODE_BACK_IN_EVENT_MODE) ) CodeDetector::EnteredCode(GameI.controller,CodeDetector::CODE_BACK_IN_EVENT_MODE) )
{ {
MenuI.player = PLAYER_1; MenuI.player = PLAYER_1;