modified haste mechanics

This commit is contained in:
Glenn Maynard
2007-04-26 00:56:37 +00:00
parent 0036068bd5
commit 74a17abe9b
8 changed files with 70 additions and 17 deletions
+3
View File
@@ -795,6 +795,9 @@ void GameState::ResetStageStatistics()
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
m_pPlayerState[p]->RemoveAllInventory(); m_pPlayerState[p]->RemoveAllInventory();
m_fOpponentHealthPercent = 1; m_fOpponentHealthPercent = 1;
m_fHasteRate = 0;
m_fLastHasteUpdateMusicSeconds = 0;
m_fAccumulatedHasteSeconds = 0;
m_fTugLifePercentP1 = 0.5f; m_fTugLifePercentP1 = 0.5f;
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
+7
View File
@@ -193,6 +193,13 @@ public:
bool AllAreInDangerOrWorse() const; bool AllAreInDangerOrWorse() const;
bool OneIsHot() const; bool OneIsHot() const;
//
// Haste
//
float m_fHasteRate; // [-1,+1]; 0 = normal speed
float m_fLastHasteUpdateMusicSeconds;
float m_fAccumulatedHasteSeconds;
// used in PLAY_MODE_BATTLE // used in PLAY_MODE_BATTLE
float m_fOpponentHealthPercent; float m_fOpponentHealthPercent;
+13
View File
@@ -1091,6 +1091,19 @@ void Player::ChangeLife( TapNoteScore tns )
m_pCombinedLifeMeter->ChangeLife( pn, tns ); m_pCombinedLifeMeter->ChangeLife( pn, tns );
ChangeLifeRecord(); ChangeLifeRecord();
switch( tns )
{
case TNS_None:
case TNS_Miss:
case TNS_CheckpointMiss:
case TNS_HitMine:
++m_pPlayerState->m_iTapsMissedSinceLastHasteUpdate;
break;
default:
++m_pPlayerState->m_iTapsHitSinceLastHasteUpdate;
break;
}
} }
void Player::ChangeLife( HoldNoteScore hns, TapNoteScore tns ) void Player::ChangeLife( HoldNoteScore hns, TapNoteScore tns )
+3
View File
@@ -33,6 +33,9 @@ void PlayerState::Reset()
m_ActiveAttacks.clear(); m_ActiveAttacks.clear();
m_ModsToApply.clear(); m_ModsToApply.clear();
m_iTapsHitSinceLastHasteUpdate = 0;
m_iTapsMissedSinceLastHasteUpdate = 0;
m_fSuperMeter = 0; // between 0 and NUM_ATTACK_LEVELS m_fSuperMeter = 0; // between 0 and NUM_ATTACK_LEVELS
m_fSuperMeterGrowthScale = 1; m_fSuperMeterGrowthScale = 1;
+6
View File
@@ -68,6 +68,12 @@ public:
AttackArray m_ActiveAttacks; AttackArray m_ActiveAttacks;
vector<Attack> m_ModsToApply; vector<Attack> m_ModsToApply;
//
// Haste
//
int m_iTapsHitSinceLastHasteUpdate;
int m_iTapsMissedSinceLastHasteUpdate;
// //
// Used in Rave // Used in Rave
// //
+38 -14
View File
@@ -1613,7 +1613,7 @@ void ScreenGameplay::Update( float fDeltaTime )
if( GAMESTATE->m_SongOptions.GetCurrent().m_fHaste != 0.0f ) if( GAMESTATE->m_SongOptions.GetCurrent().m_fHaste != 0.0f )
{ {
float fHasteRate = GetHasteRate(); float fHasteRate = GetHasteRate();
STATSMAN->m_CurStageStats.m_fAccumulatedHaste += (fUnscaledDeltaTime * fHasteRate) - fUnscaledDeltaTime; GAMESTATE->m_fAccumulatedHasteSeconds += (fUnscaledDeltaTime * fHasteRate) - fUnscaledDeltaTime;
} }
} }
@@ -1775,33 +1775,57 @@ void ScreenGameplay::Update( float fDeltaTime )
float ScreenGameplay::GetHasteRate() float ScreenGameplay::GetHasteRate()
{ {
float fLife = 0; if( GAMESTATE->m_fMusicSeconds < GAMESTATE->m_fLastHasteUpdateMusicSeconds || // new song
GAMESTATE->m_fMusicSeconds > GAMESTATE->m_fLastHasteUpdateMusicSeconds + 4 )
{
bool bAnyPlayerHitAllNotes = false;
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{
if( !GAMESTATE->IsHumanPlayer(pi->m_pn) )
continue;
PlayerState *pPS = pi->GetPlayerState();
if( pPS->m_iTapsHitSinceLastHasteUpdate > 0 &&
pPS->m_iTapsMissedSinceLastHasteUpdate == 0 )
bAnyPlayerHitAllNotes = true;
pPS->m_iTapsHitSinceLastHasteUpdate = 0;
pPS->m_iTapsMissedSinceLastHasteUpdate = 0;
}
if( bAnyPlayerHitAllNotes )
GAMESTATE->m_fHasteRate += 0.05f;
CLAMP( GAMESTATE->m_fHasteRate, -1.0f, +2.0f );
GAMESTATE->m_fLastHasteUpdateMusicSeconds = GAMESTATE->m_fMusicSeconds;
}
/* If the life meter is less than half full, push the haste rate down to let
* the player use his accumulated haste time. */
float fMaxLife = 0;
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{ {
if( !GAMESTATE->IsHumanPlayer(pi->m_pn) ) if( !GAMESTATE->IsHumanPlayer(pi->m_pn) )
continue; continue;
fLife = max( fLife, pi->m_pLifeMeter->GetLife() ); fMaxLife = max( fMaxLife, pi->m_pLifeMeter->GetLife() );
} }
if( fMaxLife < 0.5f )
GAMESTATE->m_fHasteRate = SCALE( fMaxLife, 0.0f, 0.5f, -1.0f, 0.0f );
/* Scale the music nonlinearly. Stick at 1x up to 0.5, so we start at 1x
* if the life meter defaults to 0.5. Increase gradually up to 0.9.
* Accelerate sharply above 0.9. */
float fSpeed = 1.0f; float fSpeed = 1.0f;
if( fLife < 0.50f ) if( GAMESTATE->m_fHasteRate < 0 )
fSpeed = SCALE( fLife, 0.0f, 0.50f, 0.5f, 1.0f ); fSpeed = SCALE( GAMESTATE->m_fHasteRate, -1.0f, 0.0f, 0.5f, 1.0f );
else if( fLife > 0.5f && fLife < 0.9f ) else
fSpeed = SCALE( fLife, 0.5f, 0.9f, 1.0f, 1.25f ); fSpeed = SCALE( GAMESTATE->m_fHasteRate, 0.0f, 1.0f, 1.0f, 1.6f );
else if( fLife >= 0.9f )
fSpeed = SCALE( fLife, 0.9f, 1.0f, 1.25f, 2.0f );
fSpeed *= GAMESTATE->m_SongOptions.GetCurrent().m_fHaste; fSpeed *= GAMESTATE->m_SongOptions.GetCurrent().m_fHaste;
if( STATSMAN->m_CurStageStats.m_fAccumulatedHaste <= 1 ) if( GAMESTATE->m_fAccumulatedHasteSeconds <= 1 )
{ {
/* Only allow slowing down the song while the players have accumulated /* Only allow slowing down the song while the players have accumulated
* haste. This prevents dragging on the song by keeping the life meter * haste. This prevents dragging on the song by keeping the life meter
* nearly empty. */ * nearly empty. */
float fClamped = max( 1.0f, fSpeed ); float fClamped = max( 1.0f, fSpeed );
fSpeed = lerp( STATSMAN->m_CurStageStats.m_fAccumulatedHaste, fClamped, fSpeed ); fSpeed = lerp( GAMESTATE->m_fAccumulatedHasteSeconds, fClamped, fSpeed );
} }
return fSpeed; return fSpeed;
} }
-1
View File
@@ -29,7 +29,6 @@ StageStats::StageStats()
m_fGameplaySeconds = 0; m_fGameplaySeconds = 0;
m_fStepsSeconds = 0; m_fStepsSeconds = 0;
m_fMusicRate = 1; m_fMusicRate = 1;
m_fAccumulatedHaste = 0;
} }
void StageStats::Init() void StageStats::Init()
-2
View File
@@ -42,8 +42,6 @@ public:
float m_fStepsSeconds; // this is <= fGameplaySeconds unless the song has steps past the end float m_fStepsSeconds; // this is <= fGameplaySeconds unless the song has steps past the end
float m_fMusicRate; float m_fMusicRate;
float m_fAccumulatedHaste;
// Total number of seconds between first beat and last beat for every song. // Total number of seconds between first beat and last beat for every song.
float GetTotalPossibleStepsSeconds() const; float GetTotalPossibleStepsSeconds() const;