Files
itgmania212121/stepmania/src/Player.cpp
T

516 lines
15 KiB
C++
Raw Normal View History

2001-11-03 10:52:42 +00:00
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
File: Player.cpp
2001-11-03 10:52:42 +00:00
Desc: Object that accepts pad input, knocks down ColorArrows that were stepped on,
and keeps score for the player.
2001-11-03 10:52:42 +00:00
Copyright (c) 2001 Chris Danford. All rights reserved.
-----------------------------------------------------------------------------
*/
2001-11-03 10:52:42 +00:00
#include "ScreenDimensions.h"
#include "Math.h" // for fabs()
2001-11-03 10:52:42 +00:00
#include "Player.h"
#include "RageUtil.h"
2002-01-16 10:01:32 +00:00
#include "ThemeManager.h"
2002-02-24 10:31:20 +00:00
#include "GameTypes.h"
#include "ArrowEffects.h"
2001-11-03 10:52:42 +00:00
2002-02-24 01:43:11 +00:00
const float JUDGEMENT_Y = CENTER_Y;
const float ARROWS_Y = SCREEN_TOP + ARROW_SIZE * 1.5f;
const float HOLD_JUDGEMENT_Y = ARROWS_Y + 80;
const float LIFEMETER_Y = SCREEN_TOP + 30;
const float COMBO_Y = CENTER_Y + 60;
const float SCORE_Y = SCREEN_HEIGHT - 40;
2001-11-03 10:52:42 +00:00
const float HOLD_ARROW_NG_TIME = 0.27f;
2002-02-24 01:43:11 +00:00
2002-02-02 05:11:12 +00:00
Player::Player()
2001-11-03 10:52:42 +00:00
{
2002-02-24 01:43:11 +00:00
m_fSongBeat = 0;
m_PlayerNumber = PLAYER_NONE;
2001-11-20 11:49:10 +00:00
2002-02-24 01:43:11 +00:00
// init step elements
for( int i=0; i<MAX_TAP_STEP_ELEMENTS; i++ )
2001-12-19 01:50:57 +00:00
{
2002-02-24 01:43:11 +00:00
m_TapStepsOriginal[i] = STEP_NONE;
m_TapStepsRemaining[i] = STEP_NONE;
m_TapStepScores[i] = TSS_NONE;
2001-12-19 01:50:57 +00:00
}
2002-02-24 01:43:11 +00:00
m_iNumHoldSteps = 0;
2001-11-26 05:41:43 +00:00
2002-02-24 01:43:11 +00:00
this->AddActor( &m_GrayArrows );
this->AddActor( &m_ColorArrowField );
this->AddActor( &m_GhostArrows );
this->AddActor( &m_Judgement );
for( int c=0; c<MAX_NUM_COLUMNS; c++ )
this->AddActor( &m_HoldJudgement[c] );
this->AddActor( &m_Combo );
this->AddActor( &m_LifeMeter );
this->AddActor( &m_Score );
2001-11-03 10:52:42 +00:00
}
2002-02-24 01:43:11 +00:00
void Player::Load( const Style& style, PlayerNumber player_no, const Steps& steps, const PlayerOptions& po )
2002-02-02 05:11:12 +00:00
{
2002-02-24 01:43:11 +00:00
//RageLog( "Player::Load()", );
2002-02-02 05:11:12 +00:00
2002-02-24 01:43:11 +00:00
m_Style = style;
m_PlayerNumber = player_no;
2002-02-24 10:31:20 +00:00
m_PlayerOptions = po;
2002-02-02 05:11:12 +00:00
2002-02-24 01:43:11 +00:00
Steps steps2 = steps;
2001-11-03 10:52:42 +00:00
2002-02-24 01:43:11 +00:00
if( !po.m_bAllowFreezeArrows )
steps2.RemoveHoldSteps();
2002-02-24 01:43:11 +00:00
steps2.Turn( po.m_TurnType );
2001-12-20 12:37:38 +00:00
2002-02-24 01:43:11 +00:00
if( po.m_bLittle )
steps2.MakeLittle();
2001-11-30 19:08:44 +00:00
2002-02-24 01:43:11 +00:00
m_ColorArrowField.Load( style, steps2, po, 2, 10 );
2002-02-24 10:31:20 +00:00
m_GrayArrows.Load( po, style );
m_GhostArrows.Load( po, style );
2001-11-30 19:08:44 +00:00
2002-02-24 01:43:11 +00:00
// load step elements
for( int i=0; i<MAX_TAP_STEP_ELEMENTS; i++ )
2001-12-20 12:37:38 +00:00
{
2002-02-28 19:40:40 +00:00
m_TapStepsOriginal[i] = steps2.m_TapSteps[i];
m_TapStepsRemaining[i] = steps2.m_TapSteps[i];
2001-12-20 12:37:38 +00:00
}
2002-02-28 19:40:40 +00:00
for( i=0; i<steps2.m_iNumHoldSteps; i++ )
2001-12-19 01:50:57 +00:00
{
2002-02-28 19:40:40 +00:00
m_HoldSteps[i] = steps2.m_HoldSteps[i];
2001-12-20 12:37:38 +00:00
}
2002-02-28 19:40:40 +00:00
m_iNumHoldSteps = steps2.m_iNumHoldSteps;
2001-12-20 12:37:38 +00:00
2002-02-24 01:43:11 +00:00
m_Combo.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - COMBO_Y : COMBO_Y );
m_LifeMeter.SetY( LIFEMETER_Y );
m_Judgement.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - JUDGEMENT_Y : JUDGEMENT_Y );
for( int c=0; c<MAX_NUM_COLUMNS; c++ )
m_HoldJudgement[c].SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - HOLD_JUDGEMENT_Y : HOLD_JUDGEMENT_Y );
m_Score.SetY( SCORE_Y );
2001-12-28 10:15:59 +00:00
2002-02-24 01:43:11 +00:00
m_ColorArrowField.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GrayArrows.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GhostArrows.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
2001-12-28 10:15:59 +00:00
}
2001-11-03 10:52:42 +00:00
void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference )
{
//RageLog( "Player::Update(%f, %f, %f)", fDeltaTime, fSongBeat, fMaxBeatDifference );
2001-11-28 20:26:45 +00:00
2002-02-24 01:43:11 +00:00
//
// Check for TapStep misses
//
2001-12-19 01:50:57 +00:00
int iNumMisses = UpdateStepsMissedOlderThan( m_fSongBeat-fMaxBeatDifference );
2001-11-03 10:52:42 +00:00
if( iNumMisses > 0 )
{
2002-02-24 01:43:11 +00:00
m_Judgement.SetJudgement( TSS_MISS );
m_Combo.EndCombo();
for( int i=0; i<iNumMisses; i++ )
2002-02-24 01:43:11 +00:00
m_LifeMeter.ChangeLife( TSS_MISS );
2001-11-03 10:52:42 +00:00
}
2002-02-24 01:43:11 +00:00
//
// update HoldSteps logic
//
for( int i=0; i<m_iNumHoldSteps; i++ ) // for each HoldStep
2001-12-19 01:50:57 +00:00
{
HoldStep &hs = m_HoldSteps[i];
HoldStepScore &hss = m_HoldStepScores[i];
2002-02-24 01:43:11 +00:00
if( hss.m_Result != HSR_NONE ) // if this HoldStep already has a result
continue; // we don't need to update the logic for this one
float fStartBeat = StepIndexToBeat( (float)hs.m_iStartIndex );
float fEndBeat = StepIndexToBeat( (float)hs.m_iEndIndex );
2001-12-19 01:50:57 +00:00
2002-02-24 01:43:11 +00:00
// update the life
if( fStartBeat < m_fSongBeat && m_fSongBeat < fEndBeat ) // if the song beat is in the range of this hold
2001-12-19 01:50:57 +00:00
{
2002-02-28 19:40:40 +00:00
PlayerInput PlayerI( m_PlayerNumber, hs.m_TapStep );
bool bIsHoldingButton = PREFS->IsButtonDown( PlayerI );
2002-02-24 01:43:11 +00:00
if( bIsHoldingButton )
2001-12-19 01:50:57 +00:00
{
2002-02-24 01:43:11 +00:00
hss.m_fLife += fDeltaTime/HOLD_ARROW_NG_TIME;
hss.m_fLife = min( hss.m_fLife, 1 ); // clamp
int iCol = m_Style.TapStepToColumnNumber( hs.m_TapStep );
m_GhostArrows.HoldStep( iCol ); // update the "electric ghost" effect
2001-12-19 01:50:57 +00:00
}
2002-02-24 01:43:11 +00:00
else // !bIsHoldingButton
2001-12-19 01:50:57 +00:00
{
2002-02-24 01:43:11 +00:00
hss.m_fLife -= fDeltaTime/HOLD_ARROW_NG_TIME;
hss.m_fLife = max( hss.m_fLife, 0 ); // clamp
2001-12-19 01:50:57 +00:00
}
2002-02-24 01:43:11 +00:00
m_ColorArrowField.SetHoldStepLife( i, hss.m_fLife ); // update the ColorArrowField display
2001-12-19 01:50:57 +00:00
}
2002-02-24 01:43:11 +00:00
// check for NG
if( hss.m_fLife == 0 ) // the player has not pressed the button for a long time!
{
hss.m_Result = HSR_NG;
int iCol = m_Style.TapStepToColumnNumber( hs.m_TapStep );
m_HoldJudgement[iCol].SetHoldJudgement( HSR_NG );
}
2001-12-19 01:50:57 +00:00
2002-02-24 01:43:11 +00:00
// check for OK
if( m_fSongBeat > fEndBeat ) // if this HoldStep is in the past
2001-12-19 01:50:57 +00:00
{
2002-02-24 01:43:11 +00:00
// this implies that hss.m_fLife > 0, or else we would have marked it NG above
hss.m_fLife = 1;
hss.m_Result = HSR_OK;
int iCol = m_Style.TapStepToColumnNumber( hs.m_TapStep );
m_HoldJudgement[iCol].SetHoldJudgement( HSR_OK );
m_ColorArrowField.SetHoldStepLife( i, hss.m_fLife ); // update the ColorArrowField display
2001-12-19 01:50:57 +00:00
}
}
2002-02-24 01:43:11 +00:00
ActorFrame::Update( fDeltaTime );
m_LifeMeter.SetBeat( fSongBeat );
m_GrayArrows.Update( fDeltaTime, fSongBeat );
m_ColorArrowField.Update( fDeltaTime, fSongBeat );
m_GhostArrows.Update( fDeltaTime, fSongBeat );
m_fSongBeat = fSongBeat; // save song beat
2001-12-20 12:37:38 +00:00
2001-11-03 10:52:42 +00:00
}
2002-02-24 10:31:20 +00:00
void Player::RenderPrimitives()
{
D3DXMATRIX matOldView, matOldProj;
2002-02-28 19:40:40 +00:00
if( m_PlayerOptions.m_EffectType == PlayerOptions::EFFECT_SPACE )
2002-02-24 10:31:20 +00:00
{
// turn off Z Buffering
SCREEN->GetDevice()->SetRenderState( D3DRS_ZENABLE, FALSE );
SCREEN->GetDevice()->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
// save old view and projection
SCREEN->GetDevice()->GetTransform( D3DTS_VIEW, &matOldView );
SCREEN->GetDevice()->GetTransform( D3DTS_PROJECTION, &matOldProj );
// construct view and project matrix
D3DXMATRIX matNewView;
D3DXMatrixLookAtLH( &matNewView, &D3DXVECTOR3( CENTER_X, GetY()+800.0f, 300.0f ),
&D3DXVECTOR3( CENTER_X
, GetY()+400.0f, 0.0f ),
&D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) );
SCREEN->GetDevice()->SetTransform( D3DTS_VIEW, &matNewView );
D3DXMATRIX matNewProj;
D3DXMatrixPerspectiveFovLH( &matNewProj, D3DX_PI/4.0f, SCREEN_WIDTH/(float)SCREEN_HEIGHT, 0.0f, 1000.0f );
SCREEN->GetDevice()->SetTransform( D3DTS_PROJECTION, &matNewProj );
}
m_GrayArrows.Draw();
m_ColorArrowField.Draw();
m_GhostArrows.Draw();
2002-02-28 19:40:40 +00:00
if( m_PlayerOptions.m_EffectType == PlayerOptions::EFFECT_SPACE )
2002-02-24 10:31:20 +00:00
{
// restire old view and projection
SCREEN->GetDevice()->SetTransform( D3DTS_VIEW, &matOldView );
SCREEN->GetDevice()->SetTransform( D3DTS_PROJECTION, &matOldProj );
// turn Z Buffering back on
SCREEN->GetDevice()->SetRenderState( D3DRS_ZENABLE, TRUE );
SCREEN->GetDevice()->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
}
m_Judgement.Draw();
for( int c=0; c<m_Style.m_iNumColumns; c++ )
m_HoldJudgement[c].Draw();
m_Combo.Draw();
m_LifeMeter.Draw();
m_Score.Draw();
2001-12-28 10:15:59 +00:00
}
2002-02-24 01:43:11 +00:00
bool Player::IsThereANoteAtIndex( int iIndex )
2001-11-03 10:52:42 +00:00
{
2002-03-10 10:30:45 +00:00
if( m_TapStepsOriginal[iIndex] != STEP_NONE )
return true;
for( int i=0; i<m_iNumHoldSteps; i++ ) // for each HoldStep
{
if( m_HoldSteps[i].m_iStartIndex == iIndex )
return true;
}
return false;
}
2001-11-03 10:52:42 +00:00
2002-02-24 01:43:11 +00:00
void Player::HandlePlayerStep( float fSongBeat, TapStep player_step, float fMaxBeatDiff )
{
//RageLog( "Player::HandlePlayerStep()" );
2001-11-03 10:52:42 +00:00
2002-02-24 01:43:11 +00:00
int iColumnNum = m_Style.TapStepToColumnNumber( player_step );
2002-03-09 06:19:40 +00:00
if( iColumnNum == -1 ) // if this TapStep is not used in the current Style
return; // ignore the step
2002-02-24 01:43:11 +00:00
m_GrayArrows.Step( iColumnNum );
2001-11-03 10:52:42 +00:00
CheckForCompleteStep( fSongBeat, player_step, fMaxBeatDiff );
2001-12-19 01:50:57 +00:00
2002-02-24 01:43:11 +00:00
//
// check if we stepped on the TapStep part of a HoldStep
//
for( int i=0; i<m_iNumHoldSteps; i++ ) // for each HoldStep
2001-12-19 01:50:57 +00:00
{
2002-02-24 01:43:11 +00:00
HoldStep& hs = m_HoldSteps[i];
HoldStepScore& hss = m_HoldStepScores[i];
if( hss.m_Result != HSR_NONE ) // if this note already has a score
continue; // we don't need to update its logic
if( hss.m_TapStepScore != TSS_NONE ) // the TapStep already has a score
continue; // no need to continue;
if( player_step == m_HoldSteps[i].m_TapStep ) // the player's step is the same as this HoldStep
2001-12-19 01:50:57 +00:00
{
2002-02-24 01:43:11 +00:00
float fBeatDifference = fabsf( StepIndexToBeat(hs.m_iStartIndex) - fSongBeat );
2001-12-19 01:50:57 +00:00
2002-02-24 01:43:11 +00:00
if( fBeatDifference <= fMaxBeatDiff )
2001-12-28 10:15:59 +00:00
{
2002-02-24 01:43:11 +00:00
float fBeatsUntilStep = StepIndexToBeat( (float)hs.m_iStartIndex ) - fSongBeat;
float fPercentFromPerfect = fabsf( fBeatsUntilStep / fMaxBeatDiff );
2001-12-28 10:15:59 +00:00
//RageLog( "fBeatsUntilStep: %f, fPercentFromPerfect: %f",
// fBeatsUntilStep, fPercentFromPerfect );
// compute what the score should be for the note we stepped on
2002-02-24 01:43:11 +00:00
TapStepScore &score = hss.m_TapStepScore;
if( fPercentFromPerfect < 0.25f ) score = TSS_PERFECT;
else if( fPercentFromPerfect < 0.50f ) score = TSS_GREAT;
else if( fPercentFromPerfect < 0.75f ) score = TSS_GOOD;
else score = TSS_BOO;
2001-12-28 10:15:59 +00:00
// update the judgement, score, and life
2002-02-24 01:43:11 +00:00
m_Judgement.SetJudgement( score );
m_Score.AddToScore( score, m_Combo.GetCurrentCombo() );
m_LifeMeter.ChangeLife( score );
2001-12-28 10:15:59 +00:00
// show the gray arrow ghost
2002-02-24 01:43:11 +00:00
int iColNum = m_Style.TapStepToColumnNumber( player_step );
m_GhostArrows.TapStep( iColNum, score, m_Combo.GetCurrentCombo() > 100 );
2001-12-28 10:15:59 +00:00
// update the combo display
2002-02-24 01:43:11 +00:00
switch( score )
2001-12-28 10:15:59 +00:00
{
2002-02-24 01:43:11 +00:00
case TSS_PERFECT:
case TSS_GREAT:
m_Combo.ContinueCombo();
2001-12-28 10:15:59 +00:00
break;
2002-02-24 01:43:11 +00:00
case TSS_GOOD:
case TSS_BOO:
m_Combo.EndCombo();
2001-12-28 10:15:59 +00:00
break;
}
}
2001-12-19 01:50:57 +00:00
}
}
}
2001-11-03 10:52:42 +00:00
2002-02-24 01:43:11 +00:00
void Player::CheckForCompleteStep( float fSongBeat, TapStep player_step, float fMaxBeatDiff )
2001-11-03 10:52:42 +00:00
{
//RageLog( "Player::CheckForCompleteStep()" );
2001-11-03 10:52:42 +00:00
// look for the closest matching step
int iIndexStartLookingAt = BeatToStepIndex( fSongBeat );
int iNumElementsToExamine = BeatToStepIndex( fMaxBeatDiff ); // number of elements to examine on either end of iIndexStartLookingAt
2001-11-03 10:52:42 +00:00
//RageLog( "iIndexStartLookingAt = %d, iNumElementsToExamine = %d", iIndexStartLookingAt, iNumElementsToExamine );
2001-11-03 10:52:42 +00:00
// Start at iIndexStartLookingAt and search outward. The first one that overlaps the player's step is the closest match.
for( int delta=0; delta <= iNumElementsToExamine; delta++ )
{
int iCurrentIndexEarlier = iIndexStartLookingAt - delta;
int iCurrentIndexLater = iIndexStartLookingAt + delta;
// silly check to make sure we don't go out of bounds
2002-02-24 01:43:11 +00:00
iCurrentIndexEarlier = clamp( iCurrentIndexEarlier, 0, MAX_TAP_STEP_ELEMENTS-1 );
iCurrentIndexLater = clamp( iCurrentIndexLater, 0, MAX_TAP_STEP_ELEMENTS-1 );
////////////////////////////
// check the step to the left of iIndexStartLookingAt
////////////////////////////
//RageLog( "Checking steps[%d]", iCurrentIndexEarlier );
2002-02-24 01:43:11 +00:00
if( m_TapStepsRemaining[iCurrentIndexEarlier] & player_step ) // these steps overlap
{
2002-02-24 01:43:11 +00:00
m_TapStepsRemaining[iCurrentIndexEarlier] &= ~player_step; // subtract player_step
if( m_TapStepsRemaining[iCurrentIndexEarlier] == 0 ) { // did this complete the step?
OnCompleteStep( fSongBeat, player_step, fMaxBeatDiff, iCurrentIndexEarlier );
return;
}
}
2001-11-03 10:52:42 +00:00
////////////////////////////
// check the step to the right of iIndexStartLookingAt
////////////////////////////
//RageLog( "Checking steps[%d]", iCurrentIndexLater );
2002-02-24 01:43:11 +00:00
if( m_TapStepsRemaining[iCurrentIndexLater] & player_step ) // these steps overlap
{
2002-02-24 01:43:11 +00:00
m_TapStepsRemaining[iCurrentIndexLater] &= ~player_step; // subtract player_step
if( m_TapStepsRemaining[iCurrentIndexLater] == 0 ) { // did this complete the step?
OnCompleteStep( fSongBeat, player_step, fMaxBeatDiff, iCurrentIndexLater );
return;
}
}
}
}
2001-11-03 10:52:42 +00:00
2002-02-24 01:43:11 +00:00
void Player::OnCompleteStep( float fSongBeat, TapStep player_step, float fMaxBeatDiff, int iIndexThatWasSteppedOn )
{
2002-02-24 01:43:11 +00:00
float fStepBeat = StepIndexToBeat( (float)iIndexThatWasSteppedOn );
2001-11-30 09:38:35 +00:00
float fBeatsUntilStep = fStepBeat - fSongBeat;
2002-02-24 01:43:11 +00:00
float fPercentFromPerfect = fabsf( fBeatsUntilStep / fMaxBeatDiff );
2001-11-03 10:52:42 +00:00
//RageLog( "fBeatsUntilStep: %f, fPercentFromPerfect: %f",
// fBeatsUntilStep, fPercentFromPerfect );
2001-11-03 10:52:42 +00:00
// compute what the score should be for the note we stepped on
2002-02-24 01:43:11 +00:00
TapStepScore &score = m_TapStepScores[iIndexThatWasSteppedOn];
2001-11-03 10:52:42 +00:00
2002-02-24 01:43:11 +00:00
if( fPercentFromPerfect < 0.25f ) score = TSS_PERFECT;
else if( fPercentFromPerfect < 0.50f ) score = TSS_GREAT;
else if( fPercentFromPerfect < 0.75f ) score = TSS_GOOD;
else score = TSS_BOO;
// update the judgement, score, and life
2002-02-24 01:43:11 +00:00
m_Judgement.SetJudgement( score );
m_Score.AddToScore( score, m_Combo.GetCurrentCombo() );
m_LifeMeter.ChangeLife( score );
// remove this row from the ColorArrowField
m_ColorArrowField.RemoveTapStepRow( iIndexThatWasSteppedOn );
// check to see if this completes a row of notes
for( int c=0; c<m_Style.m_iNumColumns; c++ ) // for each column
{
if( m_TapStepsOriginal[iIndexThatWasSteppedOn] & m_Style.m_ColumnToTapStep[c] ) // if this colum was part of the original step
m_GhostArrows.TapStep( c, score, m_Combo.GetCurrentCombo()>100 ); // show the ghost arrow for this column
2001-12-01 23:46:09 +00:00
}
2001-11-03 10:52:42 +00:00
// update the combo display
2002-02-24 01:43:11 +00:00
switch( score )
2001-11-03 10:52:42 +00:00
{
2002-02-24 01:43:11 +00:00
case TSS_PERFECT:
case TSS_GREAT:
m_Combo.ContinueCombo();
2001-11-03 10:52:42 +00:00
break;
2002-02-24 01:43:11 +00:00
case TSS_GOOD:
case TSS_BOO:
m_Combo.EndCombo();
2001-11-03 10:52:42 +00:00
break;
}
}
2001-11-03 10:52:42 +00:00
ScoreSummary Player::GetScoreSummary()
{
ScoreSummary scoreSummary;
2002-02-24 01:43:11 +00:00
for( int i=0; i<MAX_TAP_STEP_ELEMENTS; i++ )
2001-11-03 10:52:42 +00:00
{
2002-02-24 01:43:11 +00:00
switch( m_TapStepScores[i] )
2001-11-03 10:52:42 +00:00
{
2002-02-24 01:43:11 +00:00
case TSS_PERFECT: scoreSummary.perfect++; break;
case TSS_GREAT: scoreSummary.great++; break;
case TSS_GOOD: scoreSummary.good++; break;
case TSS_BOO: scoreSummary.boo++; break;
case TSS_MISS: scoreSummary.miss++; break;
case TSS_NONE: break;
default: ASSERT( false );
2001-11-03 10:52:42 +00:00
}
}
2002-02-24 01:43:11 +00:00
for( i=0; i<m_iNumHoldSteps; i++ )
2001-12-28 10:15:59 +00:00
{
2002-02-24 01:43:11 +00:00
switch( m_HoldStepScores[i].m_TapStepScore )
2001-12-28 10:15:59 +00:00
{
2002-02-24 01:43:11 +00:00
case TSS_PERFECT: scoreSummary.perfect++; break;
case TSS_GREAT: scoreSummary.great++; break;
case TSS_GOOD: scoreSummary.good++; break;
case TSS_BOO: scoreSummary.boo++; break;
case TSS_MISS: scoreSummary.miss++; break;
case TSS_NONE: break;
default: ASSERT( false );
2001-12-28 10:15:59 +00:00
}
2002-02-24 01:43:11 +00:00
switch( m_HoldStepScores[i].m_Result )
2001-12-28 10:15:59 +00:00
{
2002-02-24 01:43:11 +00:00
case HSR_NG: scoreSummary.ng++; break;
case HSR_OK: scoreSummary.ok++; break;
case HSR_NONE: break;
default: ASSERT( false );
2001-12-28 10:15:59 +00:00
}
}
2002-02-24 01:43:11 +00:00
scoreSummary.max_combo = m_Combo.GetMaxCombo();
scoreSummary.score = m_Score.GetScore();
2001-11-03 10:52:42 +00:00
return scoreSummary;
}
2002-02-24 01:43:11 +00:00
int Player::UpdateStepsMissedOlderThan( float fMissIfOlderThanThisBeat )
{
2002-02-24 01:43:11 +00:00
//RageLog( "Steps::UpdateStepsMissedOlderThan(%f)", fMissIfOlderThanThisBeat );
2001-11-20 11:49:10 +00:00
2002-02-24 01:43:11 +00:00
int iMissIfOlderThanThisIndex = BeatToStepIndex( fMissIfOlderThanThisBeat );
2001-11-20 11:49:10 +00:00
2002-02-24 01:43:11 +00:00
int iNumMissesFound = 0;
// Since this is being called frame, let's not check the whole array every time.
// Instead, only check 10 elements back. Even 10 is overkill.
int iStartCheckingAt = max( 0, iMissIfOlderThanThisIndex-10 );
2001-12-19 01:50:57 +00:00
2002-02-24 01:43:11 +00:00
//RageLog( "iStartCheckingAt: %d iMissIfOlderThanThisIndex: %d", iStartCheckingAt, iMissIfOlderThanThisIndex );
for( int i=iStartCheckingAt; i<iMissIfOlderThanThisIndex; i++ )
2001-12-19 01:50:57 +00:00
{
2002-02-24 01:43:11 +00:00
//RageLog( "Checking for miss: %d: lefttostepon == %d, score == %d", i, m_LeftToStepOn[i], m_StepScore[i] );
if( m_TapStepsRemaining[i] != 0 && m_TapStepScores[i] != TSS_MISS )
{
2002-02-24 01:43:11 +00:00
m_TapStepScores[i] = TSS_MISS;
iNumMissesFound++;
m_LifeMeter.ChangeLife( TSS_MISS );
}
2001-12-19 01:50:57 +00:00
}
2002-02-24 01:43:11 +00:00
return iNumMissesFound;
}