expand Boo window in MercifulBeginner. If step is early and stepped in Boo window, show judgment but don't grade.

This commit is contained in:
Chris Danford
2005-05-23 05:21:40 +00:00
parent 7114ef6227
commit e99a874161
+94 -52
View File
@@ -45,11 +45,44 @@ CString ATTACK_DISPLAY_X_NAME( size_t p, size_t both_sides ){ return "AttackDisp
/* Distance to search for a note in Step(), in seconds. */
static const float StepSearchDistance = 1.0f;
#define ADJUSTED_WINDOW_HOLD( judge ) ( \
(PREFSMAN->m_fJudgeWindowSeconds##judge * PREFSMAN->m_fJudgeWindowScale) + \
PREFSMAN->m_fJudgeWindowAdd )
enum HoldWindow { HW_OK, HW_Roll };
enum TapWindow { TW_Marvelous, TW_Perfect, TW_Great, TW_Good, TW_Boo, TW_Mine, TW_Attack };
float ADJUSTED_WINDOW_HOLD( HoldWindow hw )
{
float fSecs = 0;
switch( hw )
{
case HW_OK: fSecs = PREFSMAN->m_fJudgeWindowSecondsOK; break;
case HW_Roll: fSecs = PREFSMAN->m_fJudgeWindowSecondsRoll; break;
default: ASSERT(0);
}
fSecs *= PREFSMAN->m_fJudgeWindowScale;
fSecs += PREFSMAN->m_fJudgeWindowAdd;
return fSecs;
}
float ADJUSTED_WINDOW_TAP( TapWindow tw )
{
float fSecs = 0;
switch( tw )
{
case TW_Marvelous: fSecs = PREFSMAN->m_fJudgeWindowSecondsMarvelous; break;
case TW_Perfect: fSecs = PREFSMAN->m_fJudgeWindowSecondsPerfect; break;
case TW_Great: fSecs = PREFSMAN->m_fJudgeWindowSecondsGreat; break;
case TW_Good: fSecs = PREFSMAN->m_fJudgeWindowSecondsGood; break;
case TW_Boo: fSecs = PREFSMAN->m_fJudgeWindowSecondsBoo; break;
case TW_Mine: fSecs = PREFSMAN->m_fJudgeWindowSecondsMine; break;
case TW_Attack: fSecs = PREFSMAN->m_fJudgeWindowSecondsAttack; break;
default: ASSERT(0);
}
fSecs *= PREFSMAN->m_fJudgeWindowScale;
fSecs += PREFSMAN->m_fJudgeWindowAdd;
if( PREFSMAN->m_bMercifulBeginner && tw==TW_Boo )
fSecs += 0.5f;
return fSecs;
}
#define ADJUSTED_WINDOW_TAP( judge, tns ) (ADJUSTED_WINDOW_HOLD(judge))
Player::Player()
{
@@ -468,7 +501,7 @@ void Player::Update( float fDeltaTime )
else
{
// Decrease life
fLife -= fDeltaTime/ADJUSTED_WINDOW_HOLD(OK);
fLife -= fDeltaTime/ADJUSTED_WINDOW_HOLD(HW_OK);
fLife = max( fLife, 0 ); // clamp
}
break;
@@ -479,7 +512,7 @@ void Player::Update( float fDeltaTime )
// give positive life in Step(), not here.
// Decrease life
fLife -= fDeltaTime/ADJUSTED_WINDOW_HOLD(Roll);
fLife -= fDeltaTime/ADJUSTED_WINDOW_HOLD(HW_Roll);
fLife = max( fLife, 0 ); // clamp
break;
default:
@@ -856,20 +889,20 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld )
{
case TapNote::mine:
// stepped too close to mine?
if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(Mine,TNS_HIT_MINE) )
if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(TW_Mine) )
score = TNS_HIT_MINE;
break;
case TapNote::attack:
if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(Attack,TNS_NONE) && !tn.result.bHidden )
if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(TW_Attack) && !tn.result.bHidden )
score = TNS_PERFECT; /* sentinel */
break;
default:
if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(Marvelous, TNS_MARVELOUS) ) score = TNS_MARVELOUS;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(Perfect, TNS_PERFECT) ) score = TNS_PERFECT;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(Great, TNS_GREAT) ) score = TNS_GREAT;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(Good, TNS_GOOD) ) score = TNS_GOOD;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(Boo, TNS_BOO) ) score = TNS_BOO;
if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(TW_Marvelous) ) score = TNS_MARVELOUS;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(TW_Perfect) ) score = TNS_PERFECT;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(TW_Great) ) score = TNS_GREAT;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(TW_Good) ) score = TNS_GOOD;
else if( fSecondsFromPerfect <= ADJUSTED_WINDOW_TAP(TW_Boo) ) score = TNS_BOO;
else score = TNS_NONE;
break;
}
@@ -990,48 +1023,57 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld )
if( score == TNS_MARVELOUS && !GAMESTATE->ShowMarvelous() )
score = TNS_PERFECT;
if( score != TNS_NONE && score != TNS_MISS )
bool bSteppedEarly = -fNoteOffset < 0;
bool bScoreThis = true;
if( PREFSMAN->m_bMercifulBeginner && score==TNS_BOO && bSteppedEarly )
{
int ms_error = (int) roundf( fSecondsFromPerfect * 1000 );
ms_error = min( ms_error, MAX_PRO_TIMING_ERROR.GetValue() );
if( m_pPlayerStageStats )
m_pPlayerStageStats->iTotalError += ms_error;
m_Judgment.SetJudgment( score, bSteppedEarly );
}
//LOG->Trace("XXX: %i col %i, at %f, music at %f, step was at %f, off by %f",
// score, col, fStepSeconds, fCurrentMusicSeconds, fMusicSeconds, fNoteOffset );
// LOG->Trace("Note offset: %f (fSecondsFromPerfect = %f), Score: %i", fNoteOffset, fSecondsFromPerfect, score);
tn.result.tns = score;
if( score != TNS_NONE )
tn.result.fTapNoteOffset = -fNoteOffset;
m_NoteData.SetTapNote( col, iIndexOverlappingNote, tn );
// TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
// Keep this here so we get the same data as Autosync
NSMAN->ReportTiming( fNoteOffset,pn );
if( m_pPrimaryScoreKeeper )
m_pPrimaryScoreKeeper->HandleTapScore( score );
if( m_pSecondaryScoreKeeper )
m_pSecondaryScoreKeeper->HandleTapScore( score );
switch( tn.type )
else
{
case TapNote::tap:
case TapNote::hold_head:
// don't judge the row if this note is a mine or tap attack
if( NoteDataWithScoring::IsRowCompletelyJudged( m_NoteData, iIndexOverlappingNote ) )
OnRowCompletelyJudged( iIndexOverlappingNote );
}
tn.result.tns = score;
m_LastTapNoteScore = score;
if( score != TNS_NONE )
tn.result.fTapNoteOffset = -fNoteOffset;
if( score != TNS_NONE && score != TNS_MISS )
{
int ms_error = (int) roundf( fSecondsFromPerfect * 1000 );
ms_error = min( ms_error, MAX_PRO_TIMING_ERROR.GetValue() );
if( m_pPlayerStageStats )
m_pPlayerStageStats->iTotalError += ms_error;
}
//LOG->Trace("XXX: %i col %i, at %f, music at %f, step was at %f, off by %f",
// score, col, fStepSeconds, fCurrentMusicSeconds, fMusicSeconds, fNoteOffset );
// LOG->Trace("Note offset: %f (fSecondsFromPerfect = %f), Score: %i", fNoteOffset, fSecondsFromPerfect, score);
m_NoteData.SetTapNote( col, iIndexOverlappingNote, tn );
// TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
// Keep this here so we get the same data as Autosync
NSMAN->ReportTiming( fNoteOffset,pn );
if( m_pPrimaryScoreKeeper )
m_pPrimaryScoreKeeper->HandleTapScore( score );
if( m_pSecondaryScoreKeeper )
m_pSecondaryScoreKeeper->HandleTapScore( score );
switch( tn.type )
{
case TapNote::tap:
case TapNote::hold_head:
// don't judge the row if this note is a mine or tap attack
if( NoteDataWithScoring::IsRowCompletelyJudged( m_NoteData, iIndexOverlappingNote ) )
OnRowCompletelyJudged( iIndexOverlappingNote );
}
m_LastTapNoteScore = score;
}
}
if( m_pNoteField )
@@ -1622,7 +1664,7 @@ void Player::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScore )
float Player::GetMaxStepDistanceSeconds()
{
return GAMESTATE->m_SongOptions.m_fMusicRate * ADJUSTED_WINDOW_TAP(Boo,TNS_BOO);
return GAMESTATE->m_SongOptions.m_fMusicRate * ADJUSTED_WINDOW_TAP(TW_Boo);
}
void Player::FadeToFail()