From ade8308aa1d450baf64ff2836ae1e767df48a03c Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 7 Dec 2003 20:29:42 +0000 Subject: [PATCH] add per-player danger and per-player dead animations --- stepmania/Themes/default/metrics.ini | 1 + stepmania/src/BGAnimationLayer.cpp | 39 +++++++++--- stepmania/src/Background.cpp | 90 ++++++++++++++++++++++++---- stepmania/src/Background.h | 16 +++-- stepmania/src/GameState.cpp | 82 ++++++++++++++++++++----- stepmania/src/GameState.h | 5 ++ stepmania/src/ProfileManager.cpp | 28 +++++++-- stepmania/src/ScreenGameplay.cpp | 90 +++++++++++++--------------- stepmania/src/ScreenGameplay.h | 3 - stepmania/src/ScreenTitleMenu.cpp | 8 --- 10 files changed, 254 insertions(+), 108 deletions(-) diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 542d910208..560b3ce385 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -1933,6 +1933,7 @@ LeftEdge=20 TopEdge=20 RightEdge=620 BottomEdge=460 +BlinkDangerAll=1 [Judgment] BooOddCommand= diff --git a/stepmania/src/BGAnimationLayer.cpp b/stepmania/src/BGAnimationLayer.cpp index 6d19d30f7b..91763b3d6c 100644 --- a/stepmania/src/BGAnimationLayer.cpp +++ b/stepmania/src/BGAnimationLayer.cpp @@ -507,7 +507,7 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) bool Stretch = false; { - CString type; + CString type = "sprite"; ini.GetValue( sLayer, "Type", type ); type.MakeLower(); @@ -515,13 +515,38 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) * and "stretch=1". "type=1" is for backwards-compatibility. */ ini.GetValue( sLayer, "Stretch", Stretch ); - if( atoi(type) == 0 || type == "sprite" ) m_Type = TYPE_SPRITE; - else if( atoi(type) == 1 ) { m_Type = TYPE_SPRITE; Stretch = true; } - else if( atoi(type) == 2 || type == "particles" ) m_Type = TYPE_PARTICLES; - else if( atoi(type) == 3 || type == "tiles" ) m_Type = TYPE_TILES; + // Check for string match first, then do integer match. + // "if(atoi(type)==0)" was matching against all string matches. + // -Chris + if( stricmp(type,"sprite")==0 ) + { + m_Type = TYPE_SPRITE; + } + else if( stricmp(type,"particles")==0 ) + { + m_Type = TYPE_PARTICLES; + } + else if( stricmp(type,"tiles")==0 ) + { + m_Type = TYPE_TILES; + } + else if( atoi(type) == 1 ) + { + m_Type = TYPE_SPRITE; + Stretch = true; + } + else if( atoi(type) == 2 ) + { + m_Type = TYPE_PARTICLES; + } + else if( atoi(type) == 3 ) + { + m_Type = TYPE_TILES; + } else - RageException::Throw("Unknown %s::type in %s: \"%s\"", - sLayer.c_str(), sAniDir.c_str(), type.c_str() ); + { + m_Type = TYPE_SPRITE; + } } { diff --git a/stepmania/src/Background.cpp b/stepmania/src/Background.cpp index ecc9ce748b..5f06528b3a 100644 --- a/stepmania/src/Background.cpp +++ b/stepmania/src/Background.cpp @@ -35,6 +35,7 @@ const float FADE_SECONDS = 1.0f; #define TOP_EDGE THEME->GetMetricI("Background","TopEdge") #define RIGHT_EDGE THEME->GetMetricI("Background","RightEdge") #define BOTTOM_EDGE THEME->GetMetricI("Background","BottomEdge") +CachedThemeMetricB BLINK_DANGER_ALL("Background","BlinkDangerAll"); #define RECT_BACKGROUND RectI(LEFT_EDGE,TOP_EDGE,RIGHT_EDGE,BOTTOM_EDGE) @@ -45,14 +46,20 @@ CString RandomBackground(int num) { return ssprintf("__random%i", num); } Background::Background() { - m_bInDanger = false; + BLINK_DANGER_ALL.Refresh(); + + int p; m_iCurBGChangeIndex = -1; m_pCurrentBGA = NULL; m_pFadingBGA = NULL; m_fSecsLeftInFade = 0; - m_BGADanger.LoadFromAniDir( THEME->GetPathToB("ScreenGameplay danger") ); + m_DangerAll.LoadFromAniDir( THEME->GetPathToB("ScreenGameplay danger all") ); + for( p=0; pGetPathToB(ssprintf("ScreenGameplay danger p%d",p+1)) ); + for( p=0; pGetPathToB(ssprintf("ScreenGameplay dead p%d",p+1)) ); m_quadBGBrightness.StretchTo( RECT_BACKGROUND ); m_quadBGBrightness.SetDiffuse( RageColor(0,0,0,1-PREFSMAN->m_fBGBrightness) ); @@ -68,7 +75,7 @@ Background::Background() bool bOneOrMoreChars = false; bool bShowingBeginnerHelper = false; - for( int p=0; pIsHumanPlayer(p) ) continue; @@ -374,9 +381,20 @@ void Background::LoadFromSong( Song* pSong ) iter->second->SetZoomY( fYZoom ); } - m_BGADanger.SetXY( (float)LEFT_EDGE, (float)TOP_EDGE ); - m_BGADanger.SetZoomX( fXZoom ); - m_BGADanger.SetZoomY( fYZoom ); + m_DangerAll.SetXY( (float)LEFT_EDGE, (float)TOP_EDGE ); + m_DangerAll.SetZoomX( fXZoom ); + m_DangerAll.SetZoomY( fYZoom ); + + for( int p=0; pEnableOddDimensionWarning(); @@ -433,12 +451,21 @@ void Background::Update( float fDeltaTime ) { ActorFrame::Update( fDeltaTime ); - if( IsDangerVisible() ) + if( IsDangerAllVisible() ) { - m_BGADanger.Update( fDeltaTime ); + m_DangerAll.Update( fDeltaTime ); } - /* Always update the current background, even when m_BGADanger is being displayed. + for( int p=0; pm_bDrawDangerLight = true; - m_BGADanger.Draw(); + m_DangerAll.Draw(); } else { @@ -484,6 +511,14 @@ void Background::DrawPrimitives() m_pCurrentBGA->Draw(); if( m_pFadingBGA ) m_pFadingBGA->Draw(); + + for( int p=0; pm_bShowDanger && (RageTimer::GetTimeSinceStart() - (int)RageTimer::GetTimeSinceStart()) < 0.5f; + if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF ) + return false; + if( !PREFSMAN->m_bShowDanger ) + return false; + + if( GAMESTATE->AllAreInDangerOrWorse() ) + { + if( BLINK_DANGER_ALL ) + return (RageTimer::GetTimeSinceStart() - (int)RageTimer::GetTimeSinceStart()) < 0.5f; + else + return true; + } + else + return false; +} + +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_HealthState[pn] == GameState::DANGER; +} + +bool Background::IsDeadPlayerVisible( PlayerNumber pn ) +{ + if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF ) + return false; + return GAMESTATE->m_HealthState[pn] == GameState::DEAD; } diff --git a/stepmania/src/Background.h b/stepmania/src/Background.h index aa0a4c011d..85f0c71abe 100644 --- a/stepmania/src/Background.h +++ b/stepmania/src/Background.h @@ -36,20 +36,20 @@ public: void FadeIn(); void FadeOut(); - virtual void TurnDangerOn() { m_bInDanger = true; }; - virtual void TurnDangerOff() { m_bInDanger = false; }; - - virtual bool IsInDanger() { return m_bInDanger; }; - DancingCharacters* GetDancingCharacters() { return m_pDancingCharacters; }; protected: - bool IsDangerVisible(); + bool IsDangerPlayerVisible( PlayerNumber pn ); + bool IsDangerAllVisible(); + bool IsDeadPlayerVisible( PlayerNumber pn ); void UpdateCurBGChange(); DancingCharacters* m_pDancingCharacters; - BGAnimation m_BGADanger; + BGAnimation m_DangerPlayer[NUM_PLAYERS]; + BGAnimation m_DangerAll; + + BGAnimation m_DeadPlayer[NUM_PLAYERS]; BGAnimation* CreateSongBGA(const Song *pSong, CString sBGName) const; BGAnimation* CreateRandomBGA() const; @@ -63,8 +63,6 @@ protected: Quad m_quadBGBrightness; Quad m_quadBorder[4]; // l, t, r, b - cover up the edge of animations that might hang outside of the background rectangle - - bool m_bInDanger; }; diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 907e819c51..0f56877dec 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -33,6 +33,7 @@ #include "ThemeManager.h" #include "LightsManager.h" #include "RageFile.h" +#include "Bookkeeper.h" #define DEFAULT_MODIFIERS THEME->GetMetric( "Common","DefaultModifiers" ) @@ -143,6 +144,10 @@ void GameState::Reset() } LIGHTSMAN->SetLightMode( LIGHTMODE_ATTRACT ); + + // HACK: save stats intermitently in case of crash + BOOKKEEPER->WriteToDisk(); + PROFILEMAN->SaveMachineScoresToDisk(); } void GameState::Update( float fDelta ) @@ -259,7 +264,10 @@ void GameState::ResetStageStatistics() m_fOpponentHealthPercent = 1; m_fTugLifePercentP1 = 0.5f; for( int p=0; p &asFeatsO GetFinalEvalStatsAndSongs( stats, vSongs ); - for( int mc=0; mc &vHighScores = PROFILEMAN->m_CategoryDatas[MEMORY_CARD_MACHINE][nt][i].vHighScores; + for( unsigned j=0; j &vHighScores = PROFILEMAN->m_CategoryDatas[mc][nt][i].vHighScores; - for( unsigned j=0; j &vHighScores = PROFILEMAN->m_CategoryDatas[pn][nt][i].vHighScores; + for( unsigned j=0; jIsPlayerEnabled(p) ) + if( m_HealthState[p] < DANGER ) + return false; + return true; +} + +bool GameState::AllAreDead() const +{ + for( int p=0; pIsPlayerEnabled(p) ) + if( m_HealthState[p] < DEAD ) + return false; + return true; +} + +bool GameState::OneIsHot() const +{ + for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) + if( m_HealthState[p] == HOT ) + return true; + return false; +} diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index d190fa5170..f0a9daf4e8 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -161,6 +161,11 @@ public: // Nonstop/Oni/Endless: for current course (which usually contains multiple songs) // StageStats m_CurStageStats; // current stage (not necessarily passed if Extra Stage) + enum HealthState { HOT, ALIVE, DANGER, DEAD }; + HealthState m_HealthState[NUM_PLAYERS]; + bool AllAreInDangerOrWorse() const; + bool AllAreDead() const; + bool OneIsHot() const; // used in PLAY_MODE_BATTLE and PLAY_MODE_RAVE AttackArray m_ActiveAttacks[NUM_PLAYERS]; diff --git a/stepmania/src/ProfileManager.cpp b/stepmania/src/ProfileManager.cpp index fc9e61f645..1a6e371f24 100644 --- a/stepmania/src/ProfileManager.cpp +++ b/stepmania/src/ProfileManager.cpp @@ -425,7 +425,10 @@ void ProfileManager::ReadSongScoresFromFile( CString fn, MemoryCard mc ) { RageFile f; if( !f.Open(fn, RageFile::READ) ) + { + LOG->Warn( "Couldn't open file '%s'", fn.c_str() ); return; + } int version; if( !FileRead(f, version) ) @@ -520,7 +523,10 @@ void ProfileManager::ReadCategoryScoresFromFile( CString fn, MemoryCard mc ) { RageFile f; if( !f.Open(fn, RageFile::READ) ) + { + LOG->Warn( "Couldn't open file '%s'", fn.c_str() ); return; + } int version; if( !FileRead(f, version) ) @@ -552,7 +558,10 @@ void ProfileManager::ReadCourseScoresFromFile( CString fn, MemoryCard mc ) { RageFile f; if( !f.Open(fn, RageFile::READ) ) + { + LOG->Warn( "Couldn't open file '%s'", fn.c_str() ); return; + } int version; if( !FileRead(f, version) ) @@ -633,12 +642,11 @@ void ProfileManager::InitMachineScoresFromDisk() void ProfileManager::ReadSM300NoteScores() { + if( !DoesFileExist(SM_300_STATISTICS_FILE) ) + return; + IniFile ini; ini.SetPath( SM_300_STATISTICS_FILE ); - if( !ini.ReadFile() ) { - LOG->Trace( "WARNING: Could not read SM 3.0 final statistics '%s'.", SM_300_STATISTICS_FILE ); - return; // load nothing - } // load song statistics const IniFile::key* pKey = ini.GetKey( "Statistics" ); @@ -707,7 +715,10 @@ void ProfileManager::SaveCategoryScoresToFile( CString fn, MemoryCard mc ) RageFile f; if( !f.Open(fn, RageFile::WRITE) ) + { + LOG->Warn( "Couldn't open file '%s'", fn.c_str() ); return; + } FileWrite( f, CATEGORY_RANKING_VERSION ); @@ -735,7 +746,10 @@ void ProfileManager::SaveCourseScoresToFile( CString fn, MemoryCard mc ) RageFile f; if( !f.Open(fn, RageFile::WRITE) ) + { + LOG->Warn( "Couldn't open file '%s'", fn.c_str() ); return; + } FileWrite( f, COURSE_SCORES_VERSION ); @@ -791,7 +805,10 @@ void ProfileManager::SaveSongScoresToFile( CString fn, MemoryCard mc ) RageFile f; if( !f.Open(fn, RageFile::WRITE) ) + { + LOG->Warn( "Couldn't open file '%s'", fn.c_str() ); return; + } FileWrite( f, STEPS_SCORES_VERSION ); @@ -892,7 +909,10 @@ void ProfileManager::SaveStatsWebPageToFile( CString fn, MemoryCard mc ) { RageFile f; if( !f.Open( fn, RageFile::WRITE ) ) + { + LOG->Warn( "Couldn't open file '%s'", fn.c_str() ); return; + } f.PutLine( "" ); f.PutLine( "" ); diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index d4c16d0729..cde669e102 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -958,37 +958,6 @@ float ScreenGameplay::StartPlayingSong(float MinTimeToNotes, float MinTimeToMusi return fFirstSecond - fStartSecond; } -bool ScreenGameplay::OneIsHot() const -{ - for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) - if( (m_pLifeMeter[p] && m_pLifeMeter[p]->IsHot()) || - (m_pCombinedLifeMeter && m_pCombinedLifeMeter->IsHot((PlayerNumber)p)) ) - return true; - return false; -} - -bool ScreenGameplay::AllAreInDanger() const -{ - for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) - if( (m_pLifeMeter[p] && !m_pLifeMeter[p]->IsInDanger()) || - (m_pCombinedLifeMeter && !m_pCombinedLifeMeter->IsInDanger((PlayerNumber)p)) ) - return false; - return true; -} - -bool ScreenGameplay::AllAreFailing() const -{ - for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) - if( (m_pLifeMeter[p] && !m_pLifeMeter[p]->IsFailing()) || - (m_pCombinedLifeMeter && !m_pCombinedLifeMeter->IsFailing((PlayerNumber)p)) ) - return false; - - return true; -} - bool ScreenGameplay::AllFailedEarlier() const { for( int p=0; pIsPlayerEnabled(p) ) + { + if( + (m_pLifeMeter[p] && m_pLifeMeter[p]->IsHot()) || + (m_pCombinedLifeMeter && m_pCombinedLifeMeter->IsHot((PlayerNumber)p)) ) + { + GAMESTATE->m_HealthState[p] = GameState::HOT; + } + else if( + (m_pLifeMeter[p] && m_pLifeMeter[p]->IsFailing()) || + (m_pCombinedLifeMeter && m_pCombinedLifeMeter->IsFailing((PlayerNumber)p)) ) + { + GAMESTATE->m_HealthState[p] = GameState::DEAD; + } + else if( + (m_pLifeMeter[p] && m_pLifeMeter[p]->IsInDanger()) || + (m_pCombinedLifeMeter && m_pCombinedLifeMeter->IsInDanger((PlayerNumber)p)) ) + { + GAMESTATE->m_HealthState[p] = GameState::DANGER; + } + else + { + GAMESTATE->m_HealthState[p] = GameState::ALIVE; + } + } + } + + switch( m_DancingState ) { case STATE_DANCING: @@ -1124,19 +1126,6 @@ void ScreenGameplay::Update( float fDeltaTime ) if( GAMESTATE->m_fMusicSeconds > fSecondsToStop && !m_NextSongOut.IsTransitioning() ) this->PostScreenMessage( SM_NotesEnded, 0 ); - // - // Handle the background danger graphic. Never show it in FAIL_OFF. Don't - // show it if everyone is already failing: it's already too late and it's - // annoying for it to show for the entire duration of a song. - // - if( GAMESTATE->m_SongOptions.m_FailType != SongOptions::FAIL_OFF ) - { - if( AllAreInDanger() && !AllAreFailing() ) - m_Background.TurnDangerOn(); - else - m_Background.TurnDangerOff(); - } - // // check for fail // @@ -1221,9 +1210,12 @@ void ScreenGameplay::Update( float fDeltaTime ) case PLAY_MODE_ARCADE: case PLAY_MODE_BATTLE: case PLAY_MODE_RAVE: - if( OneIsHot() ) m_announcerHot.PlayRandom(); - else if( AllAreInDanger() ) m_announcerDanger.PlayRandom(); - else m_announcerGood.PlayRandom(); + if( GAMESTATE->OneIsHot() ) + m_announcerHot.PlayRandom(); + else if( GAMESTATE->AllAreInDangerOrWorse() ) + m_announcerDanger.PlayRandom(); + else + m_announcerGood.PlayRandom(); if( m_pCombinedLifeMeter ) m_pCombinedLifeMeter->OnTaunt(); break; @@ -1301,7 +1293,7 @@ void ScreenGameplay::UpdateCheckFail() /* If recovery is enabled, only set fail if both are failing. * There's no way to recover mid-song in battery mode. */ if( GAMESTATE->m_SongOptions.m_LifeType != SongOptions::LIFE_BATTERY && - PREFSMAN->m_bTwoPlayerRecovery && !AllAreFailing() ) + PREFSMAN->m_bTwoPlayerRecovery && !GAMESTATE->AllAreDead() ) continue; LOG->Trace("Player %d failed", (int)pn); @@ -1323,7 +1315,7 @@ void ScreenGameplay::UpdateCheckFail() /* If FAIL_ARCADE and everyone is failing, start SM_BeginFailed. */ if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_ARCADE && - AllAreFailing() ) + GAMESTATE->AllAreDead() ) SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 ); } diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index dac7d86ac6..32c0f8ecf7 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -76,9 +76,6 @@ protected: float StartPlayingSong(float MinTimeToNotes, float MinTimeToMusic); void ShowSavePrompt( ScreenMessage SM_SendWhenDone ); - bool OneIsHot() const; - bool AllAreInDanger() const; - bool AllAreFailing() const; bool AllFailedEarlier() const; bool IsTimeToPlayTicks() const; void UpdateLyrics( float fDeltaTime ); diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp index 5cd3cd821a..52d33a5331 100644 --- a/stepmania/src/ScreenTitleMenu.cpp +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -30,8 +30,6 @@ #include "UnlockSystem.h" #include "ProductInfo.h" #include "LightsManager.h" -#include "Bookkeeper.h" -#include "ProfileManager.h" #define LOGO_ON_COMMAND THEME->GetMetric("ScreenTitleMenu","LogoOnCommand") @@ -73,12 +71,6 @@ ScreenTitleMenu::ScreenTitleMenu( CString sClassName ) : ScreenSelect( sClassNam return; } - - // HACK: save stats intermitently in case of crash - BOOKKEEPER->WriteToDisk(); - PROFILEMAN->SaveMachineScoresToDisk(); - - /* XXX We really need two common calls: 1, something run when exiting from gameplay * (to do this reset), and 2, something run when entering gameplay, to apply default * options. Having special cases in attract screens and the title menu to reset