Jumps count as only 1 in TapNoteScore totals

This commit is contained in:
Chris Danford
2003-03-16 18:57:34 +00:00
parent 7192afab51
commit 6ccb255719
13 changed files with 141 additions and 100 deletions
-21
View File
@@ -11,29 +11,8 @@
*/
#include "GameConstantsAndTypes.h"
#include "PrefsManager.h"
#include "GameState.h"
/* XXX: Should this be in GAMESTATE? It's not really a constant anymore. */
int TapNoteScoreToDancePoints( TapNoteScore tns )
{
const bool bOni = GAMESTATE->IsCourseMode();
if(!PREFSMAN->m_bMarvelousTiming && tns == TNS_MARVELOUS)
tns = TNS_PERFECT;
switch( tns )
{
case TNS_MARVELOUS: return bOni ? +3 : +2;
case TNS_PERFECT: return +2;
case TNS_GREAT: return +1;
case TNS_GOOD: return +0;
case TNS_BOO: return bOni ? 0 : -4;
case TNS_MISS: return bOni ? 0 : -8;
case TNS_NONE: return 0;
default: ASSERT(0); return 0;
}
}
CString DifficultyToString( Difficulty dc )
{
-12
View File
@@ -124,7 +124,6 @@ enum TapNoteScore {
NUM_TAP_NOTE_SCORES
};
int TapNoteScoreToDancePoints( TapNoteScore tns );
//enum TapNoteTiming {
// TNT_NONE,
@@ -142,17 +141,6 @@ enum HoldNoteScore
};
inline int HoldNoteScoreToDancePoints( HoldNoteScore hns )
{
switch( hns )
{
case HNS_OK: return +6;
case HNS_NG: return +0;
default: ASSERT(0); return 0;
}
}
//
// MemCard stuff
//
+16 -29
View File
@@ -176,22 +176,15 @@ void NoteData::RemoveHoldNote( int iHoldIndex )
m_HoldNotes.erase(m_HoldNotes.begin()+iHoldIndex, m_HoldNotes.begin()+iHoldIndex+1);
}
bool NoteData::IsThereANoteAtRow( int iRow ) const
bool NoteData::IsThereATapAtRow( int iRow ) const
{
for( int t=0; t<m_iNumTracks; t++ )
if( GetTapNote(t, iRow) != TAP_EMPTY )
return true;
// There is a tap note at the beginning of every HoldNote start
//
// for( int i=0; i<GetNumHoldNotes(); i++ ) // for each HoldNote
// if( GetHoldNote(i).m_iStartIndex == NoteRowToBeatRow(iRow) )
// return true;
return false;
}
int NoteData::GetFirstRow() const
{
return BeatToNoteRow( GetFirstBeat() );
@@ -274,6 +267,21 @@ int NoteData::GetNumTapNotes( float fStartBeat, float fEndBeat ) const
return iNumNotes;
}
int NoteData::GetNumRowsWithTaps( float fStartBeat, float fEndBeat ) const
{
int iNumNotes = 0;
if(fEndBeat == -1) fEndBeat = GetMaxBeat();
int iStartIndex = BeatToNoteRow( fStartBeat );
int iEndIndex = BeatToNoteRow( fEndBeat );
for( int i=iStartIndex; i<=iEndIndex; i++ )
if( IsThereATapAtRow(i) )
iNumNotes++;
return iNumNotes;
}
int NoteData::GetNumDoubles( float fStartBeat, float fEndBeat ) const
{
int iNumDoubles = 0;
@@ -311,27 +319,6 @@ int NoteData::GetNumHoldNotes( float fStartBeat, float fEndBeat ) const
return iNumHolds;
}
int NoteData::GetPossibleDancePoints()
{
//Each song has a certain number of "Dance Points" assigned to it. For regular arrows, this is 2 per arrow. For freeze arrows, it is 6 per arrow. When you add this all up, you get the maximum number of possible "Dance Points".
//
//Your "Dance Points" are calculated as follows:
//
//A "Marvelous" is worth 3 points, but oniy when in oni mode
//A "Perfect" is worth 2 points
//A "Great" is worth 1 points
//A "Good" is worth 0 points
//A "Boo" will subtract 4 points
//A "Miss" will subtract 8 points
//An "OK" (Successful Freeze step) will add 6 points
//A "NG" (Unsuccessful Freeze step) is worth 0 points
/* Note that, if Marvelous timing is disabled or not active (not course mode),
* PERFECT will be used instead. */
return GetNumTapNotes()*TapNoteScoreToDancePoints(TNS_MARVELOUS)+
GetNumHoldNotes()*HoldNoteScoreToDancePoints(HNS_OK);
}
void NoteData::Convert2sAnd3sToHoldNotes()
{
// Any note will end a hold (not just a TAP_HOLD_TAIL). This makes parsing DWIs much easier.
+2 -3
View File
@@ -105,7 +105,7 @@ public:
const HoldNote &GetHoldNote( int index ) const { return m_HoldNotes[index]; }
// statistics
bool IsThereANoteAtRow( int iRow ) const;
bool IsThereATapAtRow( int iRow ) const;
/* Return the highest beat/row that might contain notes. (Use GetLastBeat if you need
* accuracy.) */
@@ -117,13 +117,12 @@ public:
float GetLastBeat() const; // return the beat number of the last note
int GetLastRow() const;
int GetNumTapNotes( const float fStartBeat = 0, const float fEndBeat = -1 ) const;
int GetNumRowsWithTaps( const float fStartBeat = 0, const float fEndBeat = -1 ) const;
int GetNumDoubles( const float fStartBeat = 0, const float fEndBeat = -1 ) const;
/* optimization: for the default of start to end, use the second (faster) */
int GetNumHoldNotes( const float fStartBeat, const float fEndBeat = -1 ) const;
int GetNumHoldNotes() const { return m_HoldNotes.size(); }
int GetPossibleDancePoints();
// Transformations
void LoadTransformed( NoteData* pOriginal, int iNewNumTracks, const int iOriginalTrackToTakeFrom[] ); // -1 for iOriginalTracksToTakeFrom means no track
void LoadTransformedSlidingWindow( NoteData* pOriginal, int iNewNumTracks ); // used by autogen
+3 -7
View File
@@ -68,10 +68,9 @@ int Player::GetPlayersMaxCombo()
Player::~Player()
{
delete m_pScoreKeeper;
}
void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore, Inventory* pInventory )
void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore, Inventory* pInventory, ScoreKeeper* pScoreKeeper )
{
//LOG->Trace( "Player::Load()", );
@@ -79,6 +78,7 @@ void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDi
m_pLifeMeter = pLM;
m_pScore = pScore;
m_pInventory = pInventory;
m_pScoreKeeper = pScoreKeeper;
const StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
@@ -98,9 +98,6 @@ void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDi
m_Combo.Init( pn );
m_Judgment.Reset();
if(m_pScoreKeeper) delete m_pScoreKeeper;
m_pScoreKeeper = new ScoreKeeperMAX2(GAMESTATE->m_pCurNotes[m_PlayerNumber], *this, pn);
if( m_pScore )
m_pScore->Init( pn );
@@ -603,9 +600,8 @@ void Player::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScore )
return;
#endif //DEBUG
if(m_pScoreKeeper) {
if(m_pScoreKeeper)
m_pScoreKeeper->HandleHoldScore(holdScore, tapScore);
}
if (m_pScore)
m_pScore->SetScore(GAMESTATE->m_CurStageStats.fScore[m_PlayerNumber]);
+1 -1
View File
@@ -45,7 +45,7 @@ public:
virtual void DrawPrimitives();
~Player();
void Load( PlayerNumber player_no, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore, Inventory* pInventory );
void Load( PlayerNumber player_no, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore, Inventory* pInventory, ScoreKeeper* pScoreKeeper );
void CrossedRow( int iNoteRow );
void Step( int col );
int GetPlayersMaxCombo();
+6 -1
View File
@@ -20,7 +20,8 @@
#include "Actor.h"
#include "PlayerNumber.h"
#include "GameConstantsAndTypes.h"
#include "GameConstantsAndTypes.h" // for TapNoteScore and HoldNoteScore
class NoteData;
class ScoreKeeper: public Actor
{
@@ -39,6 +40,10 @@ public:
virtual void HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTapsInRow ) = 0;
virtual void HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScore ) = 0;
virtual int TapNoteScoreToDancePoints( TapNoteScore tns ) = 0;
virtual int HoldNoteScoreToDancePoints( HoldNoteScore hns ) = 0;
virtual int GetPossibleDancePoints( const NoteData* pNoteData ) = 0;
};
#endif
+80 -10
View File
@@ -1,20 +1,33 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
Class: ScoreKeeperMAX2
Desc:
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ScoreKeeperMAX2.h"
#include "GameState.h"
#include "PrefsManager.h"
#include "Notes.h"
ScoreKeeperMAX2::ScoreKeeperMAX2(Notes *notes, NoteDataWithScoring &data, PlayerNumber pn_):
ScoreKeeperMAX2::ScoreKeeperMAX2(Notes *notes, PlayerNumber pn_):
ScoreKeeper(pn_)
{
// Stats_DoublesCount = true;
NoteData noteData;
notes->GetNoteData( &noteData );
int Meter = notes? notes->GetMeter() : 5;
Meter = min(Meter, 10);
/* Hold notes count as two tap notes. However, hold notes already count
* as 1 in GetNumTapNotes(), so only add 1*GetNumHoldNotes, not 2. */
int iNumTapNotes = data.GetNumTapNotes() + data.GetNumHoldNotes();
int N = noteData.GetNumRowsWithTaps() + noteData.GetNumHoldNotes();
int sum = (iNumTapNotes * (iNumTapNotes + 1)) / 2;
int sum = (N * (N + 1)) / 2;
if(sum)
m_fScoreMultiplier = float(Meter * 1000000) / sum;
@@ -50,9 +63,9 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
{
ASSERT( iNumTapsInRow >= 1 );
// update dance points for Oni lifemeter
GAMESTATE->m_CurStageStats.iActualDancePoints[m_PlayerNumber] += iNumTapsInRow * TapNoteScoreToDancePoints( scoreOfLastTap );
GAMESTATE->m_CurStageStats.iTapNoteScores[m_PlayerNumber][scoreOfLastTap] += iNumTapsInRow;
// update dance points
GAMESTATE->m_CurStageStats.iActualDancePoints[m_PlayerNumber] += TapNoteScoreToDancePoints( scoreOfLastTap );
GAMESTATE->m_CurStageStats.iTapNoteScores[m_PlayerNumber][scoreOfLastTap] += 1;
/*
A single step's points are calculated as follows:
@@ -91,8 +104,8 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
keeping these seperate for as long as possible improves accuracy.
*/
for( int i=0; i<iNumTapsInRow; i++ )
AddScore( scoreOfLastTap );
// for( int i=0; i<iNumTapsInRow; i++ )
AddScore( scoreOfLastTap ); // only score once per row
}
@@ -105,3 +118,60 @@ void ScoreKeeperMAX2::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tap
if( holdScore == HNS_OK )
AddScore( TNS_PERFECT );
}
int ScoreKeeperMAX2::GetPossibleDancePoints( const NoteData* pNoteData )
{
//Each song has a certain number of "Dance Points" assigned to it. For regular arrows, this is 2 per arrow. For freeze arrows, it is 6 per arrow. When you add this all up, you get the maximum number of possible "Dance Points".
//
//Your "Dance Points" are calculated as follows:
//
//A "Marvelous" is worth 3 points, but oniy when in oni mode
//A "Perfect" is worth 2 points
//A "Great" is worth 1 points
//A "Good" is worth 0 points
//A "Boo" will subtract 4 points
//A "Miss" will subtract 8 points
//An "OK" (Successful Freeze step) will add 6 points
//A "NG" (Unsuccessful Freeze step) is worth 0 points
/* Note that, if Marvelous timing is disabled or not active (not course mode),
* PERFECT will be used instead. */
TapNoteScore maxPossibleTapScore = PREFSMAN->m_bMarvelousTiming ? TNS_MARVELOUS : TNS_PERFECT;
return pNoteData->GetNumRowsWithTaps()*TapNoteScoreToDancePoints(maxPossibleTapScore)+
pNoteData->GetNumHoldNotes()*HoldNoteScoreToDancePoints(HNS_OK);
}
int ScoreKeeperMAX2::TapNoteScoreToDancePoints( TapNoteScore tns )
{
const bool bOni = GAMESTATE->IsCourseMode();
if(!PREFSMAN->m_bMarvelousTiming && tns == TNS_MARVELOUS)
tns = TNS_PERFECT;
switch( tns )
{
case TNS_MARVELOUS: return bOni ? +3 : +2;
case TNS_PERFECT: return +2;
case TNS_GREAT: return +1;
case TNS_GOOD: return +0;
case TNS_BOO: return bOni ? 0 : -4;
case TNS_MISS: return bOni ? 0 : -8;
case TNS_NONE: return 0;
default: ASSERT(0); return 0;
}
}
int ScoreKeeperMAX2::HoldNoteScoreToDancePoints( HoldNoteScore hns )
{
switch( hns )
{
case HNS_OK: return +6;
case HNS_NG: return +0;
default: ASSERT(0); return 0;
}
}
+6 -2
View File
@@ -13,8 +13,8 @@
*/
#include "ScoreKeeper.h"
#include "Notes.h"
#include "NoteDataWithScoring.h"
struct Notes;
class ScoreKeeperMAX2: public ScoreKeeper
{
@@ -25,10 +25,14 @@ class ScoreKeeperMAX2: public ScoreKeeper
void AddScore( TapNoteScore score );
public:
ScoreKeeperMAX2(Notes *notes, NoteDataWithScoring &data, PlayerNumber pn);
ScoreKeeperMAX2(Notes *notes, PlayerNumber pn);
void HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTapsInRow );
void HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScore );
int TapNoteScoreToDancePoints( TapNoteScore tns );
int HoldNoteScoreToDancePoints( HoldNoteScore hns );
int GetPossibleDancePoints( const NoteData* pNoteData );
};
#endif
+3 -3
View File
@@ -267,7 +267,7 @@ ScreenEdit::ScreenEdit()
NOTESKIN->SwitchNoteSkin( PLAYER_1, "default" ); // change noteskin back to default before loading player
m_Player.Load( PLAYER_1, &noteData, NULL, NULL, NULL );
m_Player.Load( PLAYER_1, &noteData, NULL, NULL, NULL, NULL );
m_Player.SetXY( PLAYER_X, PLAYER_Y );
m_Fade.SetClosed();
@@ -336,7 +336,7 @@ bool ScreenEdit::PlayTicks() const
bool bAnyoneHasANote = false; // set this to true if any player has a note at one of the indicies we crossed
for( int r=iRowLastCrossed+1; r<=iRowNow; r++ ) // for each index we crossed since the last update
bAnyoneHasANote |= m_Player.IsThereANoteAtRow( r );
bAnyoneHasANote |= m_Player.IsThereATapAtRow( r );
iRowLastCrossed = iRowNow;
@@ -1400,7 +1400,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
m_EditMode = MODE_PLAYING;
m_Player.Load( PLAYER_1, (NoteData*)&m_NoteFieldEdit, NULL, NULL, NULL );
m_Player.Load( PLAYER_1, (NoteData*)&m_NoteFieldEdit, NULL, NULL, NULL, NULL );
m_rectRecordBack.StopTweening();
m_rectRecordBack.BeginTweening( 0.5f );
+19 -7
View File
@@ -29,8 +29,8 @@
#include "GrooveRadar.h"
#include "NotesLoaderSM.h"
#include "ThemeManager.h"
#include "RageTimer.h"
#include "ScoreKeeperMAX2.h"
//
// Defines
@@ -104,7 +104,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
{
LOG->Trace( "ScreenGameplay::ScreenGameplay()" );
m_bDemonstration = bDemonstration;
m_bDemonstration = bDemonstration;
SECONDS_BETWEEN_COMMENTS.Refresh();
G_TICK_EARLY_SECONDS.Refresh();
@@ -127,12 +127,23 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
{
m_pLifeMeter[p] = NULL;
m_pScoreDisplay[p] = NULL;
m_pScoreKeeper[p] = NULL;
}
}
GAMESTATE->m_CurStageStats = StageStats(); // clear values
int p;
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(p) )
continue; // skip
m_pScoreKeeper[p] = new ScoreKeeperMAX2(GAMESTATE->m_pCurNotes[p], (PlayerNumber)p);
}
// Fill in m_CurStageStats
NoteData notedata;
switch( GAMESTATE->m_PlayMode )
@@ -147,7 +158,8 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
continue; // skip
GAMESTATE->m_CurStageStats.iMeter[p] = GAMESTATE->m_pCurNotes[p]->GetMeter();
GAMESTATE->m_pCurNotes[p]->GetNoteData( &notedata );
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
// TODO: Make this more elegant
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = m_pScoreKeeper[p]->GetPossibleDancePoints( &notedata );
}
}
break;
@@ -164,7 +176,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
{
iTotalMeter += m_apCourseNotes[i]->GetMeter();
m_apCourseNotes[i]->GetNoteData( &notedata );
iTotalPossibleDancePoints += notedata.GetPossibleDancePoints();
iTotalPossibleDancePoints += m_pScoreKeeper[p]->GetPossibleDancePoints( &notedata );
}
GAMESTATE->m_CurStageStats.pSong = NULL;
@@ -214,7 +226,6 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
m_Background.SetDiffuse( RageColor(0.4f,0.4f,0.4f,1) );
this->AddChild( &m_Background );
int p;
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
@@ -510,6 +521,7 @@ ScreenGameplay::~ScreenGameplay()
{
SAFE_DELETE( m_pLifeMeter[p] );
SAFE_DELETE( m_pScoreDisplay[p] );
SAFE_DELETE( m_pScoreKeeper[p] );
}
m_soundMusic.StopPlaying();
@@ -608,7 +620,7 @@ void ScreenGameplay::LoadNextSong()
NoteData pNewNoteData;
pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, &pOriginalNoteData, &pNewNoteData );
m_Player[p].Load( (PlayerNumber)p, &pNewNoteData, m_pLifeMeter[p], m_pScoreDisplay[p], &m_Inventory );
m_Player[p].Load( (PlayerNumber)p, &pNewNoteData, m_pLifeMeter[p], m_pScoreDisplay[p], &m_Inventory, m_pScoreKeeper[p] );
}
/* Set up song-specific graphics. */
@@ -724,7 +736,7 @@ bool ScreenGameplay::IsTimeToPlayTicks() const
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
bAnyoneHasANote |= m_Player[p].IsThereANoteAtRow( r );
bAnyoneHasANote |= m_Player[p].IsThereATapAtRow( r );
break; // this will only play the tick for the first player that is joined
}
}
+1
View File
@@ -105,6 +105,7 @@ protected:
Sprite m_sprScoreFrame;
ScoreDisplay* m_pScoreDisplay[NUM_PLAYERS];
ScoreKeeper* m_pScoreKeeper[NUM_PLAYERS];
BitmapText m_textPlayerOptions[NUM_PLAYERS];
BitmapText m_textSongOptions;
+4 -4
View File
@@ -57,10 +57,10 @@ LINK32=link.exe
# SUBTRACT LINK32 /verbose /pdb:none
# Begin Special Build Tool
IntDir=.\../Release6
TargetDir=\temp\stepmania
TargetDir=\stepmania\stepmania
TargetName=StepMania
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -92,10 +92,10 @@ LINK32=link.exe
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
# Begin Special Build Tool
IntDir=.\../Debug6
TargetDir=\temp\stepmania
TargetDir=\stepmania\stepmania
TargetName=StepMania-debug
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool