diff --git a/stepmania/NoteSkins/dance/default/metrics.ini b/stepmania/NoteSkins/dance/default/metrics.ini index f88589de5b..b9890bebfa 100644 --- a/stepmania/NoteSkins/dance/default/metrics.ini +++ b/stepmania/NoteSkins/dance/default/metrics.ini @@ -21,3 +21,4 @@ HoldTailAnimationIsNoteColor=0 StartDrawingHoldBodyOffsetFromHead=0 StopDrawingHoldBodyOffsetFromTail=-32 // top of tail HoldNGGrayPercent=0.25 +UseLighting=0 \ No newline at end of file diff --git a/stepmania/src/EnemyFace.cpp b/stepmania/src/EnemyFace.cpp new file mode 100644 index 0000000000..06b0909bd0 --- /dev/null +++ b/stepmania/src/EnemyFace.cpp @@ -0,0 +1,62 @@ +#include "global.h" +/* +----------------------------------------------------------------------------- + Class: EnemyFace + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "EnemyFace.h" +#include "RageUtil.h" +#include "GameConstantsAndTypes.h" +#include "MusicWheel.h" +#include "EnemyFace.h" +#include "RageTimer.h" +#include +#include "ThemeManager.h" +#include "GameState.h" + + +const float SECONDS_TO_SHOW_FACE = 1.5f; + + +EnemyFace::EnemyFace() +{ + Load( THEME->GetPathToG("EnemyFace 2x3") ); + ASSERT( this->GetNumStates() >= NUM_FACES ); + StopAnimating(); + SetFace( normal ); +} + +void EnemyFace::Update( float fDelta ) +{ + if( m_fSecondsUntilReturnToNormal > 0 ) + { + m_fSecondsUntilReturnToNormal -= fDelta; + + if( m_fSecondsUntilReturnToNormal < 0 ) + { + m_fSecondsUntilReturnToNormal = 0; + this->SetState( normal ); + } + } + + if( GAMESTATE->m_fOpponentHealthPercent == 0 ) + this->SetState( defeated ); + + Sprite::Update( fDelta ); +} + +void EnemyFace::SetFace( Face face ) +{ + if( GAMESTATE->m_fOpponentHealthPercent == 0 ) + return; + + this->SetState( face ); + m_fSecondsUntilReturnToNormal = SECONDS_TO_SHOW_FACE; +} + diff --git a/stepmania/src/EnemyFace.h b/stepmania/src/EnemyFace.h new file mode 100644 index 0000000000..6e1be1caf7 --- /dev/null +++ b/stepmania/src/EnemyFace.h @@ -0,0 +1,32 @@ +#ifndef EnemyFace_H +#define EnemyFace_H +/* +----------------------------------------------------------------------------- + Class: EnemyFace + + Desc: A little graphic to the left of the song's text banner in the MusicWheel. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +#include "Sprite.h" + + +class EnemyFace : public Sprite +{ +public: + EnemyFace(); + + virtual void Update( float fDelta ); + + enum Face { normal=0, taunt, attack, damage, defeated, NUM_FACES }; + void SetFace( Face face ); + +protected: + float m_fSecondsUntilReturnToNormal; +}; + +#endif diff --git a/stepmania/src/EnemyHealth.cpp b/stepmania/src/EnemyHealth.cpp new file mode 100644 index 0000000000..3a1c113a36 --- /dev/null +++ b/stepmania/src/EnemyHealth.cpp @@ -0,0 +1,36 @@ +#include "global.h" +/* +----------------------------------------------------------------------------- + Class: EnemyHealth + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "EnemyHealth.h" +#include "ThemeManager.h" +#include "GameState.h" + + +EnemyHealth::EnemyHealth() : +MeterDisplay( + THEME->GetPathToG("EnemyHealth stream"), + THEME->GetPathToG("EnemyHealth frame"), + 464 ) +{ + m_fLastSeenHealthPercent = -1; +} + +void EnemyHealth::Update( float fDelta ) +{ + if( m_fLastSeenHealthPercent != GAMESTATE->m_fOpponentHealthPercent ) + { + this->SetPercent( GAMESTATE->m_fOpponentHealthPercent ); + m_fLastSeenHealthPercent = GAMESTATE->m_fOpponentHealthPercent; + } + + MeterDisplay::Update( fDelta ); +} diff --git a/stepmania/src/EnemyHealth.h b/stepmania/src/EnemyHealth.h new file mode 100644 index 0000000000..969193362b --- /dev/null +++ b/stepmania/src/EnemyHealth.h @@ -0,0 +1,29 @@ +#ifndef EnemyHealth_H +#define EnemyHealth_H +/* +----------------------------------------------------------------------------- + Class: EnemyHealth + + Desc: A little graphic to the left of the song's text banner in the MusicWheel. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +#include "MeterDisplay.h" + + +class EnemyHealth : public MeterDisplay +{ +public: + EnemyHealth(); + + virtual void Update( float fDelta ); + +protected: + float m_fLastSeenHealthPercent; +}; + +#endif diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index a59f13de0d..97614010dd 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -122,33 +122,6 @@ void GameState::Update( float fDelta ) if( m_bActiveAttackEndedThisUpdate[p] ) RebuildPlayerOptionsFromActiveAttacks( (PlayerNumber)p ); - -/* if( m_PlayerOptions[p].m_bUseScrollBPM && m_pCurSong ) - { - float fTargetBPM = m_PlayerOptions[p].m_fScrollBPM; - float fConstBPS = fTargetBPM/60.f; - - // Optimization opportunity: take fewer samples where the weight is less - - const int iNumBPSSamples = 100; - const float fSampleStep = 0.08f; // sample over the next 8 beats - float fSumBPS = 0; - int iSumWeight = 0; - for( int i=0; iGetBPMAtBeat( m_fSongBeat+fBeatsAheadToSample )/60.f; - // Don't allow super low bps values, or else the scroll speed goes crazy at a stop - CLAMP( fBPS, 60.f/60.f, 10000 ); - fSumBPS += fBPS * iWeight; - iSumWeight += iWeight; - } - float fAvgBPS = fSumBPS / iSumWeight; - - m_PlayerOptions[p].m_fScrollSpeed = fConstBPS / fAvgBPS; - } -*/ } } @@ -170,6 +143,8 @@ void GameState::ResetMusicStatistics() m_fCurBPS = 10; m_bFreeze = false; m_bPastHereWeGo = false; + + m_fOpponentHealthPercent = 1; } void GameState::UpdateSongPosition(float fPositionSeconds) @@ -376,10 +351,18 @@ PlayerNumber GameState::GetWinner() BattleResult GameState::GetBattleResult( PlayerNumber pn ) { - PlayerNumber winner = GetWinner(); - if( winner == PLAYER_INVALID ) - return RESULT_DRAW; - return (winner==pn) ? RESULT_WIN : RESULT_LOSE; +// PlayerNumber winner = GetWinner(); +// if( winner == PLAYER_INVALID ) +// return RESULT_DRAW; +// return (winner==pn) ? RESULT_WIN : RESULT_LOSE; + switch( GAMESTATE->m_PlayMode ) + { + case PLAY_MODE_BATTLE: + return (m_fOpponentHealthPercent==0)?RESULT_WIN:RESULT_LOSE; + default: + ASSERT(0); + return RESULT_WIN; + } } void GameState::GetFinalEvalStatsAndSongs( StageStats& statsOut, vector& vSongsOut ) @@ -446,6 +429,7 @@ void GameState::LaunchAttack( PlayerNumber target, Attack a ) if( m_ActiveAttacks[target][s].fSecsRemaining <= 0 ) { m_ActiveAttacks[target][s] = a; + GAMESTATE->RebuildPlayerOptionsFromActiveAttacks( target ); return; } } diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index fc36d43666..bbdc05a025 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -175,6 +175,7 @@ public: // used in PLAY_MODE_BATTLE Attack m_Inventory[NUM_PLAYERS][NUM_INVENTORY_SLOTS]; + float m_fOpponentHealthPercent; bool m_bActiveAttackEndedThisUpdate[NUM_PLAYERS]; // flag for other objects to watch (play sounds) void LaunchAttack( PlayerNumber target, Attack aa ); diff --git a/stepmania/src/Inventory.cpp b/stepmania/src/Inventory.cpp index c1b64de24a..f04c28e062 100644 --- a/stepmania/src/Inventory.cpp +++ b/stepmania/src/Inventory.cpp @@ -17,6 +17,8 @@ #include "RageTimer.h" #include "PrefsManager.h" #include "song.h" +#include "ScreenManager.h" +#include "ScreenGameplay.h" #define NUM_ITEM_TYPES THEME->GetMetricF("Inventory","NumItemTypes") @@ -56,6 +58,13 @@ Inventory::Inventory() { } +Inventory::~Inventory() +{ + for( unsigned i=0; im_PlayMode == PLAY_MODE_BATTLE ) { - for( int p=0; pGetPathToS("Inventory aquire item") ); + for( unsigned i=0; iGetPathToS("Inventory aquire item") ); - m_soundUseItem.Load( THEME->GetPathToS("Inventory use item") ); - m_soundItemEnding.Load( THEME->GetPathToS("Inventory item ending") ); + RageSound* pSound = new RageSound; + CString sPath = THEME->GetPathToS( ssprintf("Inventory use item %u",i+1) ); + pSound->Load( sPath ); + m_vpSoundUseItem.push_back( pSound ); } + m_soundItemEnding.Load( THEME->GetPathToS("Inventory item ending") ); } } @@ -172,10 +184,17 @@ void Inventory::UseItem( int iSlot ) PlayerNumber pnToAttack = OPPOSITE_PLAYER[m_PlayerNumber]; GameState::Attack a = asInventory[iSlot]; - GAMESTATE->LaunchAttack( pnToAttack, a ); - GAMESTATE->RebuildPlayerOptionsFromActiveAttacks( pnToAttack ); +// GAMESTATE->LaunchAttack( pnToAttack, a ); +// GAMESTATE->RebuildPlayerOptionsFromActiveAttacks( pnToAttack ); + + float fPercentHealthToDrain = (a.level+1) / 10.f; + ASSERT( fPercentHealthToDrain > 0 ); + GAMESTATE->m_fOpponentHealthPercent -= fPercentHealthToDrain; + CLAMP( GAMESTATE->m_fOpponentHealthPercent, 0.f, 1.f ); // remove the item asInventory[iSlot].MakeBlank(); - m_soundUseItem.Play(); + m_vpSoundUseItem[a.level]->Play(); + + SCREENMAN->SendMessageToTopScreen( (ScreenMessage)(SM_BattleDamageLevel1+a.level) ); } diff --git a/stepmania/src/Inventory.h b/stepmania/src/Inventory.h index 7255358a6f..0db8bb3f83 100644 --- a/stepmania/src/Inventory.h +++ b/stepmania/src/Inventory.h @@ -20,6 +20,7 @@ class Inventory : public Actor { public: Inventory(); + ~Inventory(); void Load( PlayerNumber pn ); virtual void Update( float fDelta ); @@ -34,7 +35,7 @@ protected: int m_iLastSeenCombo; RageSound m_soundAcquireItem; - RageSound m_soundUseItem; + vector m_vpSoundUseItem; RageSound m_soundItemEnding; }; diff --git a/stepmania/src/MeterDisplay.cpp b/stepmania/src/MeterDisplay.cpp new file mode 100644 index 0000000000..8a2996e878 --- /dev/null +++ b/stepmania/src/MeterDisplay.cpp @@ -0,0 +1,68 @@ +#include "global.h" +/* +----------------------------------------------------------------------------- + File: MeterDisplay.h + + Desc: The song's MeterDisplay displayed in SelectSong. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "MeterDisplay.h" + + +MeterDisplay::MeterDisplay( + CString sSteamPath, + CString sFramePath, + float fStreamWidth ) +{ + m_fStreamWidth = fStreamWidth; + + m_sprStream.Load( sSteamPath ); + m_sprStream.SetZoomX( fStreamWidth / m_sprStream.GetUnzoomedWidth() ); + + m_quad.SetZoomY( m_sprStream.GetUnzoomedHeight() ); + m_quad.SetX( m_fStreamWidth/2 ); + m_quad.SetHorizAlign( Actor::align_right ); + m_quad.SetDiffuse( RageColor(0,0,0,1) ); + + m_sprFrame.Load( sFramePath ); + + m_fTrailingPercent = 0; + + SetPercent( 0.5f ); +} + +MeterDisplay::~MeterDisplay() +{ +} + +void MeterDisplay::Update( float fDelta ) +{ + fapproach( m_fTrailingPercent, m_fPercent, 0.2f*fDelta ); + m_quad.SetZoomX( m_fStreamWidth * (1-m_fTrailingPercent) ); + + m_sprStream.Update( fDelta ); + m_quad.Update( fDelta ); + m_sprFrame.Update( fDelta ); + + Actor::Update( fDelta ); +} + +void MeterDisplay::DrawPrimitives() +{ + m_sprStream.Draw(); + m_quad.Draw(); + m_sprFrame.Draw(); +} + +void MeterDisplay::SetPercent( float fPercent ) +{ + ASSERT( fPercent >= 0 && fPercent <= 1 ); + + m_fPercent = fPercent; + + m_sprFrame.Command( "glow,1,1,1,1;linear,0.5;glow,1,1,1,0" ); + m_sprStream.Command( "glow,1,1,1,1;linear,0.5;glow,1,1,1,0" ); +} diff --git a/stepmania/src/MeterDisplay.h b/stepmania/src/MeterDisplay.h new file mode 100644 index 0000000000..1b8ff4276d --- /dev/null +++ b/stepmania/src/MeterDisplay.h @@ -0,0 +1,42 @@ +#ifndef MeterDisplay_H +#define MeterDisplay_H +/* +----------------------------------------------------------------------------- + File: MeterDisplay.h + + Desc: + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Actor.h" +#include "Sprite.h" +#include "Quad.h" + + +class MeterDisplay : public Actor +{ +public: + MeterDisplay( + CString sSteamPath, + CString sFramePath, + float fStreamWidth ); + virtual ~MeterDisplay(); + virtual void Update( float fDelta ); + virtual void DrawPrimitives(); + + void SetPercent( float fPercent ); + +protected: + + float m_fStreamWidth; + float m_fPercent; + float m_fTrailingPercent; + Sprite m_sprStream; + Quad m_quad; + Sprite m_sprFrame; +}; + +#endif diff --git a/stepmania/src/NoteDisplay.cpp b/stepmania/src/NoteDisplay.cpp index ef7c386be0..cb33ed37d2 100644 --- a/stepmania/src/NoteDisplay.cpp +++ b/stepmania/src/NoteDisplay.cpp @@ -65,6 +65,7 @@ Actor* MakeModelOrSprite( CString sFile ) #define START_DRAWING_HOLD_BODY_OFFSET_FROM_HEAD NOTESKIN->GetMetricI(pn,name,"StartDrawingHoldBodyOffsetFromHead") #define STOP_DRAWING_HOLD_BODY_OFFSET_FROM_TAIL NOTESKIN->GetMetricI(pn,name,"StopDrawingHoldBodyOffsetFromTail") #define HOLD_NG_GRAY_PERCENT NOTESKIN->GetMetricF(pn,name,"HoldNGGrayPercent") +#define USE_LIGHTING NOTESKIN->GetMetricB(pn,name,"UseLighting") // cache struct NoteMetricCache_t { @@ -90,6 +91,7 @@ struct NoteMetricCache_t { int m_iStartDrawingHoldBodyOffsetFromHead; int m_iStopDrawingHoldBodyOffsetFromTail; float m_fHoldNGGrayPercent; + bool m_bUseLighting; void Load(PlayerNumber pn, const CString &name); } *NoteMetricCache; @@ -118,6 +120,7 @@ void NoteMetricCache_t::Load(PlayerNumber pn, const CString &name) m_iStartDrawingHoldBodyOffsetFromHead = START_DRAWING_HOLD_BODY_OFFSET_FROM_HEAD; m_iStopDrawingHoldBodyOffsetFromTail = STOP_DRAWING_HOLD_BODY_OFFSET_FROM_TAIL; m_fHoldNGGrayPercent = HOLD_NG_GRAY_PERCENT; + m_bUseLighting = USE_LIGHTING; } NoteDisplay::NoteDisplay() @@ -700,19 +703,24 @@ void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bOnSame pActor->SetDiffuse( diffuse ); pActor->SetGlow( glow ); - - DISPLAY->EnableLighting( true ); - DISPLAY->SetLightDirectional( - 0, - RageColor(0.0f,0.0f,0.0f,1), - RageColor(1,1,1,1), - RageColor(1,1,1,1), - RageVector3(1, 0, +1) ); + if( cache->m_bUseLighting ) + { + DISPLAY->EnableLighting( true ); + DISPLAY->SetLightDirectional( + 0, + RageColor(0.0f,0.0f,0.0f,1), + RageColor(1,1,1,1), + RageColor(1,1,1,1), + RageVector3(1, 0, +1) ); + } pActor->Draw(); - DISPLAY->SetLightOff( 0 ); - DISPLAY->EnableLighting( false ); + if( cache->m_bUseLighting ) + { + DISPLAY->SetLightOff( 0 ); + DISPLAY->EnableLighting( false ); + } } diff --git a/stepmania/src/RageSound.cpp b/stepmania/src/RageSound.cpp index 12d98ca3d6..f85239a0aa 100644 --- a/stepmania/src/RageSound.cpp +++ b/stepmania/src/RageSound.cpp @@ -173,7 +173,7 @@ bool RageSound::Load(CString sSoundFilePath, int precache) SoundReader_SDL_Sound *NewSample = new SoundReader_SDL_Sound; if(!NewSample->Open(sSoundFilePath.c_str())) - RageException::Throw( "RageSoundManager::RageSoundManager: error opening sound %s: %s", + RageException::Throw( "RageSoundManager::RageSoundManager: error opening sound '%s': '%s'", sSoundFilePath.c_str(), NewSample->GetError().c_str()); Sample = NewSample; diff --git a/stepmania/src/RandomSample.cpp b/stepmania/src/RandomSample.cpp index 9d9bec6a1d..789336b7b4 100644 --- a/stepmania/src/RandomSample.cpp +++ b/stepmania/src/RandomSample.cpp @@ -68,6 +68,7 @@ bool RandomSample::LoadSoundDir( CString sDir, int iMaxToLoad ) GetDirListing( sDir + "*.ogg", arraySoundFiles ); GetDirListing( sDir + "*.wav", arraySoundFiles ); + random_shuffle( arraySoundFiles.begin(), arraySoundFiles.end() ); arraySoundFiles.resize( min( arraySoundFiles.size(), (unsigned)iMaxToLoad ) ); for( unsigned i=0; iLaunchAttack( pnToAttack, a ); - GAMESTATE->RebuildPlayerOptionsFromActiveAttacks( pnToAttack ); m_soundLaunchAttack.Play(); } diff --git a/stepmania/src/ScreenCredits.cpp b/stepmania/src/ScreenCredits.cpp index b860cb1ba6..8ecd6793ad 100644 --- a/stepmania/src/ScreenCredits.cpp +++ b/stepmania/src/ScreenCredits.cpp @@ -71,6 +71,7 @@ const CreditLine CREDIT_LINES[] = {0,"Mauro Panichella"}, {0,"Griever (Julian)"}, {0,"Miguel Moore"}, + {0,"Dj 'AeON ExOdus' Washington"}, {0,""}, {0,""}, {0,""}, diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 309dfc6ec9..4670be6986 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -664,7 +664,21 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName, Type type ) : Screen(sCl switch( m_Type ) { case stage: - SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("evaluation "+GradeToString(max_grade)) ); + switch( GAMESTATE->m_PlayMode ) + { + case PLAY_MODE_BATTLE: + { + bool bWon = GAMESTATE->GetBattleResult(GAMESTATE->m_MasterPlayerNumber) == RESULT_WIN; + if( bWon ) + SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("evaluation win") ); + else + SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("evaluation lose") ); + } + break; + default: + SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("evaluation "+GradeToString(max_grade)) ); + break; + } break; case course: case summary: diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 7c78f8df04..97d9ce928c 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -37,7 +37,8 @@ #include "ActorUtil.h" #include "NoteSkinManager.h" #include "RageTextureManager.h" - +#include "EnemyHealth.h" +#include "EnemyFace.h" // // Defines @@ -242,6 +243,19 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration ) : Screen("ScreenGameplay") this->AddChild( &m_sprOniGameOver[p] ); } + if( GAMESTATE->m_PlayMode == PLAY_MODE_BATTLE ) + { + m_pEnemyFace = new EnemyFace; + m_pEnemyFace->SetName( "EnemyFace" ); + this->AddChild( m_pEnemyFace ); + SET_XY( *m_pEnemyFace ); + + m_pEnemyHealth = new EnemyHealth; + m_pEnemyHealth->SetName( "EnemyHealth" ); + this->AddChild( m_pEnemyHealth ); + SET_XY( *m_pEnemyHealth ); + } + this->AddChild(&m_TimingAssist); this->AddChild( &m_NextSongIn ); @@ -530,6 +544,19 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration ) : Screen("ScreenGameplay") m_announcer1000Combo.Load( ANNOUNCER->GetPathTo("gameplay 1000 combo") ); m_announcerComboStopped.Load( ANNOUNCER->GetPathTo("gameplay combo stopped") ); m_soundAssistTick.Load( THEME->GetPathToS("ScreenGameplay assist tick") ); + + if( GAMESTATE->m_PlayMode == PLAY_MODE_BATTLE ) + { + m_announcerBattleTrickLevel1.Load( ANNOUNCER->GetPathTo("gameplay battle trick level1") ); + m_announcerBattleTrickLevel2.Load( ANNOUNCER->GetPathTo("gameplay battle trick level2") ); + m_announcerBattleTrickLevel3.Load( ANNOUNCER->GetPathTo("gameplay battle trick level3") ); + m_soundBattleTrickLevel1.Load( THEME->GetPathToS("ScreenGameplay battle trick level1") ); + m_soundBattleTrickLevel2.Load( THEME->GetPathToS("ScreenGameplay battle trick level2") ); + m_soundBattleTrickLevel3.Load( THEME->GetPathToS("ScreenGameplay battle trick level3") ); + m_announcerBattleDamageLevel1.Load( ANNOUNCER->GetPathTo("gameplay battle damage level1") ); + m_announcerBattleDamageLevel2.Load( ANNOUNCER->GetPathTo("gameplay battle damage level2") ); + m_announcerBattleDamageLevel3.Load( ANNOUNCER->GetPathTo("gameplay battle damage level3") ); + } } // Get the transitions rolling on the first update. @@ -548,6 +575,9 @@ ScreenGameplay::~ScreenGameplay() SAFE_DELETE( m_pScoreKeeper[p] ); } + delete m_pEnemyHealth; + delete m_pEnemyFace; + m_soundMusic.StopPlaying(); } @@ -956,6 +986,8 @@ void ScreenGameplay::Update( float fDeltaTime ) if( OneIsHot() ) m_announcerHot.PlayRandom(); else if( AllAreInDanger() ) m_announcerDanger.PlayRandom(); else m_announcerGood.PlayRandom(); + if( m_pEnemyFace ) + m_pEnemyFace->SetFace( EnemyFace::taunt ); break; case PLAY_MODE_NONSTOP: case PLAY_MODE_ONI: @@ -994,6 +1026,67 @@ void ScreenGameplay::Update( float fDeltaTime ) if( GAMESTATE->m_SongOptions.m_bAssistTick && IsTimeToPlayTicks()) m_soundAssistTick.Play(); + + + // launch battle attacks + + if( GAMESTATE->m_PlayMode == PLAY_MODE_BATTLE ) + { +#define CROSSED_SONG_SECONDS( s ) ((GAMESTATE->m_fMusicSeconds-fDeltaTime) < s && (GAMESTATE->m_fMusicSeconds) >= s ) + + static const CString sPossibleModifiers[NUM_ATTACK_LEVELS][3] = + { + { + "1.5x", + "dizzy", + "drunk" + }, + { + "sudden", + "hidden", + "wave", + }, + { + "expand", + "tornado", + "flip" + } + }; + + if( CROSSED_SONG_SECONDS(20) || CROSSED_SONG_SECONDS(40) ) + { + GameState::Attack a; + a.fSecsRemaining = 10; + a.level = ATTACK_LEVEL_1; + a.sModifier = sPossibleModifiers[a.level][rand()%3]; + for( int p=0; pIsPlayerEnabled(p) ) + GAMESTATE->LaunchAttack( (PlayerNumber)p, a ); + this->HandleScreenMessage( SM_BattleTrickLevel1 ); + } + if( CROSSED_SONG_SECONDS(60) || CROSSED_SONG_SECONDS(80) ) + { + GameState::Attack a; + a.fSecsRemaining = 10; + a.level = ATTACK_LEVEL_2; + a.sModifier = sPossibleModifiers[a.level][rand()%3]; + for( int p=0; pIsPlayerEnabled(p) ) + GAMESTATE->LaunchAttack( (PlayerNumber)p, a ); + this->HandleScreenMessage( SM_BattleTrickLevel2 ); + } + if( CROSSED_SONG_SECONDS(100) ) + { + GameState::Attack a; + a.fSecsRemaining = 10; + a.level = ATTACK_LEVEL_3; + a.sModifier = sPossibleModifiers[a.level][rand()%3]; + for( int p=0; pIsPlayerEnabled(p) ) + GAMESTATE->LaunchAttack( (PlayerNumber)p, a ); + this->HandleScreenMessage( SM_BattleTrickLevel3 ); + } + } } @@ -1408,84 +1501,138 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) m_Toasty.StartTransitioning(); break; +#define SECS_SINCE_LAST_COMMENT (SECONDS_BETWEEN_COMMENTS-m_fTimeLeftBeforeDancingComment) case SM_100Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer100Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_200Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer200Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_300Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer300Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_400Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer400Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_500Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer500Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_600Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer600Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_700Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer700Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_800Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer800Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_900Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer900Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_1000Combo: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcer1000Combo.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; case SM_ComboStopped: - if( m_fTimeLeftBeforeDancingComment < 12 ) + if( SECS_SINCE_LAST_COMMENT > 10 ) { m_announcerComboStopped.PlayRandom(); m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; } break; + case SM_BattleTrickLevel1: + if( SECS_SINCE_LAST_COMMENT > 5 ) + { + m_announcerBattleTrickLevel1.PlayRandom(); + m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; + } + m_soundBattleTrickLevel1.PlayRandom(); + m_pEnemyFace->SetFace( EnemyFace::attack ); + break; + case SM_BattleTrickLevel2: + if( SECS_SINCE_LAST_COMMENT > 5 ) + { + m_announcerBattleTrickLevel2.PlayRandom(); + m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; + } + m_soundBattleTrickLevel2.PlayRandom(); + m_pEnemyFace->SetFace( EnemyFace::attack ); + break; + case SM_BattleTrickLevel3: + if( SECS_SINCE_LAST_COMMENT > 5 ) + { + m_announcerBattleTrickLevel3.PlayRandom(); + m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; + } + m_soundBattleTrickLevel3.PlayRandom(); + m_pEnemyFace->SetFace( EnemyFace::attack ); + break; + + case SM_BattleDamageLevel1: + if( SECS_SINCE_LAST_COMMENT > 5 ) + { + m_announcerBattleDamageLevel1.PlayRandom(); + m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; + } + m_pEnemyFace->SetFace( EnemyFace::damage ); + break; + case SM_BattleDamageLevel2: + if( SECS_SINCE_LAST_COMMENT > 5 ) + { + m_announcerBattleDamageLevel2.PlayRandom(); + m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; + } + m_pEnemyFace->SetFace( EnemyFace::damage ); + break; + case SM_BattleDamageLevel3: + if( SECS_SINCE_LAST_COMMENT > 5 ) + { + m_announcerBattleDamageLevel3.PlayRandom(); + m_fTimeLeftBeforeDancingComment = SECONDS_BETWEEN_COMMENTS; + } + m_pEnemyFace->SetFace( EnemyFace::damage ); + break; + case SM_SaveChangedBeforeGoingBack: if( m_bChangedOffsetOrBPM ) { @@ -1595,6 +1742,10 @@ void ScreenGameplay::TweenOnScreen() ON_COMMAND( m_textPlayerOptions[p] ); ON_COMMAND( m_DifficultyIcon[p] ); } + if( m_pEnemyFace ) + ON_COMMAND( *m_pEnemyFace ); + if( m_pEnemyHealth ) + ON_COMMAND( *m_pEnemyHealth ); } void ScreenGameplay::TweenOffScreen() @@ -1613,6 +1764,10 @@ void ScreenGameplay::TweenOffScreen() OFF_COMMAND( m_textPlayerOptions[p] ); OFF_COMMAND( m_DifficultyIcon[p] ); } + if( m_pEnemyFace ) + OFF_COMMAND( *m_pEnemyFace ); + if( m_pEnemyHealth ) + OFF_COMMAND( *m_pEnemyHealth ); if(m_textDebug.GetTweenTimeLeft() > 1/8.f) { diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index 04791b8094..484351a04a 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -30,6 +30,8 @@ //#include "BeginnerHelper.h" // uncomment once it's checked in #include "LyricDisplay.h" #include "TimingAssist.h" +class EnemyHealth; +class EnemyFace; // messages sent by Combo @@ -47,6 +49,13 @@ const ScreenMessage SM_900Combo = ScreenMessage(SM_User+208); const ScreenMessage SM_1000Combo = ScreenMessage(SM_User+209); const ScreenMessage SM_ComboStopped = ScreenMessage(SM_User+210); +const ScreenMessage SM_BattleTrickLevel1 = ScreenMessage(SM_User+300); +const ScreenMessage SM_BattleTrickLevel2 = ScreenMessage(SM_User+301); +const ScreenMessage SM_BattleTrickLevel3 = ScreenMessage(SM_User+302); +const ScreenMessage SM_BattleDamageLevel1 = ScreenMessage(SM_User+303); +const ScreenMessage SM_BattleDamageLevel2 = ScreenMessage(SM_User+304); +const ScreenMessage SM_BattleDamageLevel3 = ScreenMessage(SM_User+305); + class LyricsLoader; class ScreenGameplay : public Screen { @@ -139,6 +148,8 @@ protected: // used in PLAY_MODE_BATTLE Inventory m_Inventory[NUM_PLAYERS]; ActiveItemList m_ActiveItemList[NUM_PLAYERS]; + EnemyHealth* m_pEnemyHealth; + EnemyFace* m_pEnemyFace; // used in PLAY_MODE_RAVE RaveHelper m_RaveHelper[NUM_PLAYERS]; @@ -169,6 +180,15 @@ protected: RandomSample m_announcer900Combo; RandomSample m_announcer1000Combo; RandomSample m_announcerComboStopped; + RandomSample m_announcerBattleTrickLevel1; + RandomSample m_announcerBattleTrickLevel2; + RandomSample m_announcerBattleTrickLevel3; + RandomSample m_soundBattleTrickLevel1; + RandomSample m_soundBattleTrickLevel2; + RandomSample m_soundBattleTrickLevel3; + RandomSample m_announcerBattleDamageLevel1; + RandomSample m_announcerBattleDamageLevel2; + RandomSample m_announcerBattleDamageLevel3; bool m_bZeroDeltaOnNextUpdate; bool m_bDemonstration; diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index bac920e0cd..67a6d233b9 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -1096,6 +1096,14 @@ SOURCE=.\FadingBanner.h # End Source File # Begin Source File +SOURCE=.\MeterDisplay.cpp +# End Source File +# Begin Source File + +SOURCE=.\MeterDisplay.h +# End Source File +# Begin Source File + SOURCE=.\Transition.cpp # End Source File # Begin Source File @@ -1148,6 +1156,22 @@ SOURCE=.\DancingCharacters.h # End Source File # Begin Source File +SOURCE=.\EnemyFace.cpp +# End Source File +# Begin Source File + +SOURCE=.\EnemyFace.h +# End Source File +# Begin Source File + +SOURCE=.\EnemyHealth.cpp +# End Source File +# Begin Source File + +SOURCE=.\EnemyHealth.h +# End Source File +# Begin Source File + SOURCE=.\GhostArrow.cpp # End Source File # Begin Source File