add PerDifficulty and PeakCombo awards

This commit is contained in:
Chris Danford
2004-03-07 04:34:49 +00:00
parent 8c4eedf5e0
commit 7fe28a6dae
20 changed files with 683 additions and 47 deletions
+61
View File
@@ -13,6 +13,7 @@
#include "GameConstantsAndTypes.h"
#include "GameState.h"
#include "RageUtil.h"
#include "ThemeManager.h"
CString RadarCategoryToString( RadarCategory cat )
@@ -224,3 +225,63 @@ CString MemoryCardStateToString( MemoryCardState mcs )
}
}
#define XToString(X) \
CString X##ToString( X x ) \
{ \
ASSERT(x < ARRAYSIZE(X##Names)); \
return X##Names[x]; \
}
#define XToThemedString(X) \
CString X##ToThemedString( X x ) \
{ \
return THEME->GetMetric( #X, X##ToString(x) ); \
}
#define StringToX(X) \
X StringTo##X( CString s ) \
{ \
unsigned i; \
for( i = 0; i < ARRAYSIZE(X##Names); ++i ) \
if( !s.CompareNoCase(X##Names[i]) ) \
return (X)i; \
return (X)i; \
}
static const char *PerDifficultyAwardNames[NUM_PER_DIFFICULTY_AWARDS] = {
"FullComboGreats",
"FullComboPerfects",
"FullComboMarvelouses",
"SingleDigitGreats",
"SingleDigitPerfects",
"Greats80Percent",
"Greats90Percent",
"Greats100Percent",
};
XToString( PerDifficultyAward );
XToThemedString( PerDifficultyAward );
StringToX( PerDifficultyAward );
// The number is not at the front so that these strings can be used as XML entity names
// The number is not at the back so that "1000" and "10000" don't conflict when
// searching for theme elements.
static const char *PeakComboAwardNames[NUM_PEAK_COMBO_AWARDS] = {
"Peak1000Combo",
"Peak2000Combo",
"Peak3000Combo",
"Peak4000Combo",
"Peak5000Combo",
"Peak6000Combo",
"Peak7000Combo",
"Peak8000Combo",
"Peak9000Combo",
"Peak10000Combo",
};
XToString( PeakComboAward );
XToThemedString( PeakComboAward );
StringToX( PeakComboAward );
+44
View File
@@ -327,4 +327,48 @@ enum CoinMode { COIN_HOME, COIN_PAY, COIN_FREE, NUM_COIN_MODES };
CString CoinModeToString( CoinMode cm );
//
// Award stuff
//
enum PerDifficultyAward
{
AWARD_FULL_COMBO_GREATS,
AWARD_FULL_COMBO_PERFECTS,
AWARD_FULL_COMBO_MARVELOUSES,
AWARD_SINGLE_DIGIT_GREATS,
AWARD_SINGLE_DIGIT_PERFECTS,
AWARD_GREATS_80_PERCENT,
AWARD_GREATS_90_PERCENT,
AWARD_GREATS_100_PERCENT,
NUM_PER_DIFFICULTY_AWARDS,
PER_DIFFICULTY_AWARD_INVALID,
};
#define FOREACH_PerDifficultyAward( pma ) FOREACH_ENUM( PerDifficultyAward, NUM_PER_DIFFICULTY_AWARDS, pma )
CString PerDifficultyAwardToString( PerDifficultyAward pma );
CString PerDifficultyAwardToThemedString( PerDifficultyAward pma );
PerDifficultyAward StringToPerDifficultyAward( CString pma );
enum PeakComboAward
{
AWARD_1000_PEAK_COMBO,
AWARD_2000_PEAK_COMBO,
AWARD_3000_PEAK_COMBO,
AWARD_4000_PEAK_COMBO,
AWARD_5000_PEAK_COMBO,
AWARD_6000_PEAK_COMBO,
AWARD_7000_PEAK_COMBO,
AWARD_8000_PEAK_COMBO,
AWARD_9000_PEAK_COMBO,
AWARD_10000_PEAK_COMBO,
NUM_PEAK_COMBO_AWARDS,
PEAK_COMBO_AWARD_INVALID,
};
#define FOREACH_PeakComboAward( pca ) FOREACH_ENUM( PeakComboAward, NUM_PEAK_COMBO_AWARDS, pca )
CString PeakComboAwardToString( PeakComboAward pma );
CString PeakComboAwardToThemedString( PeakComboAward pma );
PeakComboAward StringToPeakComboAward( CString pma );
#endif
+9
View File
@@ -409,6 +409,15 @@ void GameState::ResetStageStatistics()
m_iLastPositiveSumOfAttackLevels[p] = 0;
m_fSecondsUntilAttacksPhasedOut[p] = 0; // PlayerAI not affected
}
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_vLastPerDifficultyAwards[p].clear();
m_vLastPeakComboAwards[p].clear();
}
}
}
void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp )
+10
View File
@@ -21,6 +21,7 @@
#include "RageTimer.h"
#include <map>
#include <deque>
class Song;
class Steps;
@@ -247,6 +248,15 @@ public:
void StoreRankingName( PlayerNumber pn, CString name ); // Called by name entry screens
vector<CString*> m_vpsNamesThatWereFilled; // filled on StoreRankingName,
//
// Award stuff
//
// lowest priority in front, highest priority at the back.
deque<PerDifficultyAward> m_vLastPerDifficultyAwards[NUM_PLAYERS];
deque<PeakComboAward> m_vLastPeakComboAwards[NUM_PLAYERS];
//
// Arrow positioning
//
+1 -1
View File
@@ -35,7 +35,7 @@ $(srcdir)/libresample/libresample.a:
cd $(srcdir)/libresample && autoconf && sh ./configure && make
Screens = \
Screen.cpp Screen.h ScreenAttract.cpp ScreenAttract.h ScreenBookkeeping.h ScreenBookkeeping.cpp \
Screen.cpp Screen.h ScreenAttract.cpp ScreenAttract.h ScreenAward.cpp ScreenAward.h ScreenBookkeeping.h ScreenBookkeeping.cpp \
ScreenBranch.cpp ScreenBranch.h ScreenCaution.cpp ScreenCaution.h ScreencenterImage.h ScreenCenterImage.cpp ScreenCredits.cpp ScreenCredits.h ScreenDemonstration.cpp ScreenDemonstration.h \
ScreenDimensions.h ScreenEdit.cpp ScreenEdit.h ScreenEditCoursesMenu.cpp ScreenEditCoursesMenu.h \
ScreenEditMenu.cpp ScreenEditMenu.h ScreenEnding.cpp ScreenEnding.h ScreenEndlessBreak.cpp ScreenEndlessBreak.h ScreenEvaluation.cpp ScreenEvaluation.h \
+1
View File
@@ -133,6 +133,7 @@ CString MemoryCardManager::GetOsMountDir( PlayerNumber pn )
else
{
CString sDir = m_Device[pn].sOsMountDir;
FixSlashesInPlace( sDir );
if( !sDir.empty() && sDir.Right(1)!="/" )
sDir += '/';
return sDir;
+167
View File
@@ -124,6 +124,20 @@ void Profile::InitCalorieData()
m_mapDayToCaloriesBurned.clear();
}
void Profile::InitAwards()
{
FOREACH_StepsType( st )
{
FOREACH_Difficulty( dc )
FOREACH_PerDifficultyAward( pda )
m_PerDifficultyAwards[st][dc][pda].Unset();
}
FOREACH_PeakComboAward( pca )
{
m_PeakComboAwards[pca].Unset();
}
}
CString Profile::GetDisplayName() const
{
if( !m_sDisplayName.empty() )
@@ -390,6 +404,7 @@ bool Profile::LoadAllFromDir( CString sDir )
LOAD_NODE( CategoryScores );
LOAD_NODE( ScreenshotData );
LOAD_NODE( CalorieData );
LOAD_NODE( Awards );
}
return true; // FIXME? Investigate what happens if we always return true.
@@ -414,6 +429,7 @@ bool Profile::SaveAllToDir( CString sDir ) const
xml.AppendChild( SaveCategoryScoresCreateNode() );
xml.AppendChild( SaveScreenshotDataCreateNode() );
xml.AppendChild( SaveCalorieDataCreateNode() );
xml.AppendChild( SaveAwardsCreateNode() );
bool bSaved = xml.SaveToFile(fn);
if( bSaved && PREFSMAN->m_bSignProfileData )
{
@@ -1531,3 +1547,154 @@ float Profile::GetCaloriesBurnedForDay( Day day ) const
else
return i->second;
}
XNode* Profile::AwardRecord::CreateNode() const
{
XNode* pNode = new XNode;
pNode->name = "AwardRecord";
pNode->AppendChild( "FirstTime", first );
pNode->AppendChild( "LastTime", last );
pNode->AppendChild( "Count", iCount );
return pNode;
}
void Profile::AwardRecord::LoadFromNode( const XNode* pNode )
{
Unset();
ASSERT( pNode->name == "AwardRecord" );
pNode->GetChildValue( "FirstTime", (int&)first ); // time_t is a signed long in Win32. Is this OK on other platforms?
pNode->GetChildValue( "LastTime", (int&)last );
pNode->GetChildValue( "Count", iCount );
}
void Profile::LoadAwardsFromNode( const XNode* pNode )
{
CHECKPOINT;
ASSERT( pNode->name == "Awards" );
for( XNodes::const_iterator pAward = pNode->childs.begin();
pAward != pNode->childs.end();
pAward++ )
{
if( (*pAward)->name == "PerDifficultyAward" )
{
CString sStepsType;
if( !(*pAward)->GetAttrValue( "StepsType", sStepsType ) )
WARN_AND_CONTINUE;
StepsType st = GameManager::StringToNotesType( sStepsType );
if( st == STEPS_TYPE_INVALID )
WARN_AND_CONTINUE;
CString sDifficulty;
if( !(*pAward)->GetAttrValue( "Difficulty", sDifficulty ) )
WARN_AND_CONTINUE;
Difficulty dc = StringToDifficulty( sDifficulty );
if( dc == DIFFICULTY_INVALID )
WARN_AND_CONTINUE;
CString sPerDifficultyAward;
if( !(*pAward)->GetAttrValue( "PerDifficultyAward", sPerDifficultyAward ) )
WARN_AND_CONTINUE;
PerDifficultyAward pda = StringToPerDifficultyAward( sPerDifficultyAward );
if( pda == PER_DIFFICULTY_AWARD_INVALID )
WARN_AND_CONTINUE;
AwardRecord &ar = m_PerDifficultyAwards[st][dc][pda];
XNode* pAwardRecord = (*pAward)->GetChild("AwardRecord");
if( pAwardRecord == NULL )
WARN_AND_CONTINUE;
ar.LoadFromNode( pAwardRecord );
}
else if( (*pAward)->name == "PeakComboAward" )
{
CString sPeakComboAward;
if( !(*pAward)->GetAttrValue( "PerDifficultyAward", sPeakComboAward ) )
WARN_AND_CONTINUE;
PeakComboAward pca = StringToPeakComboAward( sPeakComboAward );
if( pca == PEAK_COMBO_AWARD_INVALID )
WARN_AND_CONTINUE;
AwardRecord &ar = m_PeakComboAwards[pca];
XNode* pAwardRecord = (*pAward)->GetChild("AwardRecord");
if( pAwardRecord == NULL )
WARN_AND_CONTINUE;
ar.LoadFromNode( pAwardRecord );
}
else
WARN_AND_CONTINUE;
}
}
XNode* Profile::SaveAwardsCreateNode() const
{
CHECKPOINT;
const Profile* pProfile = this;
ASSERT( pProfile );
XNode* pNode = new XNode;
pNode->name = "Awards";
FOREACH_StepsType( st )
{
FOREACH_Difficulty( dc )
{
FOREACH_PerDifficultyAward( pda )
{
const AwardRecord &ar = m_PerDifficultyAwards[st][dc][pda];
if( !ar.IsSet() )
continue;
XNode* pAward = pNode->AppendChild( "PerDifficultyAward" );
pAward->AppendAttr( "StepsType", GameManager::NotesTypeToString(st) );
pAward->AppendAttr( "Difficulty", DifficultyToString(dc) );
pAward->AppendAttr( "PerDifficultyAward", PerDifficultyAwardToString(pda) );
pAward->AppendChild( ar.CreateNode() );
}
}
}
FOREACH_PeakComboAward( pca )
{
const AwardRecord &ar = m_PeakComboAwards[pca];
if( !ar.IsSet() )
continue;
XNode* pAward = pNode->AppendChild( "PeakComboAward" );
pAward->AppendAttr( "PeakComboAward", PeakComboAwardToString(pca) );
pAward->AppendChild( ar.CreateNode() );
}
return pNode;
}
void Profile::AddPerDifficultyAward( StepsType st, Difficulty dc, PerDifficultyAward pda )
{
m_PerDifficultyAwards[st][dc][pda].Set( time(NULL) );
}
void Profile::AddPeakComboAward( PeakComboAward pca )
{
m_PeakComboAwards[pca].Set( time(NULL) );
}
bool Profile::HasPerDifficultyAward( StepsType st, Difficulty dc, PerDifficultyAward pda )
{
return m_PerDifficultyAwards[st][dc][pda].IsSet();
}
bool Profile::HasPeakComboAward( PeakComboAward pca )
{
return m_PeakComboAwards[pca].IsSet();
}
+29
View File
@@ -198,6 +198,31 @@ public:
map<Day,float> m_mapDayToCaloriesBurned;
float GetCaloriesBurnedForDay( Day day ) const;
//
// Awards
//
struct AwardRecord
{
time_t first;
time_t last;
int iCount; // num times achieved
AwardRecord() { Unset(); }
bool IsSet() const { return iCount>0; }
void Set(time_t t) { if (iCount==0) first = t; last = t; iCount++; }
void Unset() { iCount = 0; first = -1; last = -1; }
XNode* CreateNode() const;
void LoadFromNode( const XNode* pNode );
};
AwardRecord m_PerDifficultyAwards[NUM_STEPS_TYPES][NUM_DIFFICULTIES][NUM_PER_DIFFICULTY_AWARDS];
AwardRecord m_PeakComboAwards[NUM_PEAK_COMBO_AWARDS];
void AddPerDifficultyAward( StepsType st, Difficulty dc, PerDifficultyAward pda );
void AddPeakComboAward( PeakComboAward pca );
bool HasPerDifficultyAward( StepsType st, Difficulty dc, PerDifficultyAward pda );
bool HasPeakComboAward( PeakComboAward pca );
//
// Init'ing
//
@@ -210,6 +235,7 @@ public:
InitCategoryScores();
InitScreenshotData();
InitCalorieData();
InitAwards();
}
void InitEditableData();
void InitGeneralData();
@@ -218,6 +244,7 @@ public:
void InitCategoryScores();
void InitScreenshotData();
void InitCalorieData();
void InitAwards();
//
// Loading and saving
@@ -237,6 +264,7 @@ public:
void LoadCategoryScoresFromNode( const XNode* pNode );
void LoadScreenshotDataFromNode( const XNode* pNode );
void LoadCalorieDataFromNode( const XNode* pNode );
void LoadAwardsFromNode( const XNode* pNode );
void SaveEditableDataToDir( CString sDir ) const;
XNode* SaveGeneralDataCreateNode() const;
@@ -245,6 +273,7 @@ public:
XNode* SaveCategoryScoresCreateNode() const;
XNode* SaveScreenshotDataCreateNode() const;
XNode* SaveCalorieDataCreateNode() const;
XNode* SaveAwardsCreateNode() const;
void DeleteProfileDataFromDirSM390a12( CString sDir ) const;
void DeleteSongScoresFromDirSM390a12( CString sDir ) const;
+7 -7
View File
@@ -154,15 +154,15 @@ bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn )
// moust slot
if( MEMCARDMAN->GetCardState(pn) == MEMORY_CARD_STATE_READY )
{
// XXX: Remounting the same mount point is broken. Investigate this later...
// XXX: Remounting a different OS directory to the same mount point
// seems to be broken. Investigate this later...
FILEMAN->Mount( "dir", MEMCARDMAN->GetOsMountDir(pn), MEM_CARD_DIR[pn] );
LOG->Trace( "mount %s %s", MEMCARDMAN->GetOsMountDir(pn).c_str(), MEM_CARD_DIR[pn] );
CString sDir = MEM_CARD_DIR[pn];
// FILEMAN->Mount( "dir", MEMCARDMAN->GetOsMountDir(pn), MEM_CARD_DIR[pn] );
// LOG->Trace( "mount %s %s", MEMCARDMAN->GetOsMountDir(pn).c_str(), MEM_CARD_DIR[pn] );
// CString sDir = MEM_CARD_DIR[pn];
// CString sDir = MEMCARDMAN->GetOsMountDir(pn);
CString sDir = MEMCARDMAN->GetOsMountDir(pn);
DEBUG_ASSERT( FILEMAN->IsMounted(sDir) ); // should be called only if we've already mounted
DEBUG_ASSERT( MEMCARDMAN->GetOsMountDir(pn) ); // should be called only if we've already mounted
// tack on a subdirectory so that we don't write everything to the root
sDir += PREFSMAN->m_sMemoryCardProfileSubdir;
+2
View File
@@ -291,6 +291,7 @@ void Screen::ClearMessageQueue( const ScreenMessage SM )
#include "ScreenBookkeeping.h"
#include "ScreenBranch.h"
#include "ScreenEnding.h"
#include "ScreenAward.h"
Screen* Screen::Create( CString sClassName )
{
@@ -353,6 +354,7 @@ Screen* Screen::Create( CString sClassName )
IF_RETURN( ScreenBookkeeping );
IF_RETURN( ScreenBranch );
IF_RETURN( ScreenEnding );
IF_RETURN( ScreenAward );
RageException::Throw( "Invalid Screen class name '%s'", sClassName.c_str() );
}
+149
View File
@@ -0,0 +1,149 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
Class: ScreenAward
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ScreenAward.h"
#include "ScreenManager.h"
#include "AnnouncerManager.h"
#include "RageSounds.h"
#include "ThemeManager.h"
#include "GameState.h"
#include "SongManager.h"
#include "Steps.h"
#define NEXT_SCREEN THEME->GetMetric (m_sName,"NextScreen")
ScreenAward::ScreenAward( CString sName ) : Screen( sName )
{
bool bEitherPlayerHasAward = false;
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsHumanPlayer(p) )
continue;
CString sAward;
CString sDescription;
if( !GAMESTATE->m_vLastPerDifficultyAwards[p].empty() )
{
PerDifficultyAward pda = GAMESTATE->m_vLastPerDifficultyAwards[p].front();
GAMESTATE->m_vLastPerDifficultyAwards[p].pop_front();
sAward = PerDifficultyAwardToString( pda );
sDescription =
PerDifficultyAwardToThemedString( pda ) + "\n" +
SONGMAN->GetDifficultyThemeName( GAMESTATE->m_pCurNotes[p]->GetDifficulty() );
}
else if( !GAMESTATE->m_vLastPeakComboAwards[p].empty() )
{
PeakComboAward pca = GAMESTATE->m_vLastPeakComboAwards[p].front();
GAMESTATE->m_vLastPeakComboAwards[p].pop_front();
sAward = PeakComboAwardToString( pca );
sDescription = PeakComboAwardToThemedString( pca );
}
if( sAward.empty() )
continue; // skip this player
bEitherPlayerHasAward = true;
m_Received[p].Load( THEME->GetPathG(m_sName,"received") );
m_Received[p]->SetName( ssprintf("ReceivedP%d",p+1) );
SET_XY_AND_ON_COMMAND( m_Received[p] );
this->AddChild( m_Received[p] );
m_Trophy[p].Load( THEME->GetPathG(m_sName,"trophy "+sAward) );
m_Trophy[p]->SetName( ssprintf("TrophyP%d",p+1) );
SET_XY_AND_ON_COMMAND( m_Trophy[p] );
this->AddChild( m_Trophy[p] );
m_textDescription[p].LoadFromFont( THEME->GetPathF(m_sName,"description") );
m_textDescription[p].SetName( ssprintf("DescriptionP%d",p+1) );
m_textDescription[p].SetText( sDescription );
SET_XY_AND_ON_COMMAND( m_textDescription[p] );
this->AddChild( &m_textDescription[p] );
}
if( !bEitherPlayerHasAward )
{
HandleScreenMessage( SM_GoToNextScreen );
return;
}
m_Menu.Load( m_sName );
this->AddChild( &m_Menu );
SOUND->PlayMusic( THEME->GetPathToS( m_sName + " music") );
}
void ScreenAward::DrawPrimitives()
{
m_Menu.DrawBottomLayer();
Screen::DrawPrimitives();
m_Menu.DrawTopLayer();
}
void ScreenAward::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
{
// LOG->Trace( "ScreenAward::Input()" );
if( m_Menu.IsTransitioning() )
return;
Screen::Input( DeviceI, type, GameI, MenuI, StyleI );
}
void ScreenAward::HandleScreenMessage( const ScreenMessage SM )
{
switch( SM )
{
case SM_MenuTimer:
MenuStart( PLAYER_INVALID );
break;
case SM_GoToNextScreen:
// TRICKY: Keep looping on this screen until all awards are shown
bool bMoreAwardsLeft = false;
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsHumanPlayer(p) )
continue;
if( !GAMESTATE->m_vLastPerDifficultyAwards[p].empty() ||
!GAMESTATE->m_vLastPeakComboAwards[p].empty() )
{
bMoreAwardsLeft = true;
}
}
if( bMoreAwardsLeft )
SCREENMAN->SetNewScreen( m_sName );
else
SCREENMAN->SetNewScreen( NEXT_SCREEN );
break;
}
}
void ScreenAward::MenuStart( PlayerNumber pn )
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsHumanPlayer(p) )
continue;
OFF_COMMAND( m_Received[p] );
OFF_COMMAND( m_Trophy[p] );
OFF_COMMAND( m_textDescription[p] );
}
m_Menu.StartTransitioning( SM_GoToNextScreen );
}
+38
View File
@@ -0,0 +1,38 @@
/*
-----------------------------------------------------------------------------
Class: ScreenAward
Desc: .
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "Screen.h"
#include "MenuElements.h"
#include "BitmapText.h"
#include "ActorUtil.h"
class ScreenAward : public Screen
{
public:
ScreenAward( CString sName );
virtual void DrawPrimitives();
virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI );
virtual void HandleScreenMessage( const ScreenMessage SM );
virtual void MenuStart( PlayerNumber pn );
private:
AutoActor m_Received[NUM_PLAYERS];
AutoActor m_Trophy[NUM_PLAYERS];
BitmapText m_textDescription[NUM_PLAYERS];
MenuElements m_Menu;
};
+74 -9
View File
@@ -75,7 +75,7 @@ const char* STATS_STRING[NUM_STATS_LINES] =
#define SHOW_TIME_AREA THEME->GetMetricB(m_sName,"ShowTimeArea")
#define SHOW_GRAPH_AREA THEME->GetMetricB(m_sName,"ShowGraphArea")
#define SHOW_COMBO_AREA THEME->GetMetricB(m_sName,"ShowComboArea")
#define SHOW_FULL_COMBO THEME->GetMetricB(m_sName,"ShowFullCombo")
#define SHOW_PER_DIFFICULTY_AWARD THEME->GetMetricB(m_sName,"ShowPerDifficultyAward")
#define GRAPH_START_HEIGHT THEME->GetMetricF(m_sName,"GraphStartHeight")
#define TYPE THEME->GetMetric (m_sName,"Type")
#define PASSED_SOUND_TIME THEME->GetMetricF(m_sName,"PassedSoundTime")
@@ -83,6 +83,7 @@ const char* STATS_STRING[NUM_STATS_LINES] =
#define NUM_SEQUENCE_SOUNDS THEME->GetMetricI(m_sName,"NumSequenceSounds")
#define SOUNDSEQ_TIME( i ) THEME->GetMetricF(m_sName,ssprintf("SoundSeqTime%d", i+1))
#define SOUNDSEQ_NAME( i ) THEME->GetMetric (m_sName,ssprintf("SoundSeqName%d", i+1))
#define PEAK_COMBO_AWARD_COMMAND THEME->GetMetric (m_sName,"PeakComboAwardCommand")
static const int NUM_SHOWN_RADAR_CATEGORIES = 5;
@@ -734,13 +735,15 @@ void ScreenEvaluation::Init()
this->AddChild( &m_sprPersonalRecord[p] );
}
if( SHOW_FULL_COMBO && stageStats.FullCombo( (PlayerNumber) p ) )
if( SHOW_PER_DIFFICULTY_AWARD && !GAMESTATE->m_vLastPerDifficultyAwards[p].empty() )
{
LOG->Trace( "Full combo for P%i", p+1 );
m_FullCombo[p].Load( THEME->GetPathToG(ssprintf("ScreenEvaluation full combo P%i",p+1)) );
m_FullCombo[p]->SetName( ssprintf("FullComboP%d",p+1) );
SET_XY_AND_ON_COMMAND( m_FullCombo[p] );
this->AddChild( m_FullCombo[p] );
PerDifficultyAward pda = GAMESTATE->m_vLastPerDifficultyAwards[p].front();
CString sAward = PerDifficultyAwardToString( pda );
m_PerDifficultyAward[p].Load( THEME->GetPathToG(ssprintf("ScreenEvaluation award %s",sAward.c_str(),p+1)) );
m_PerDifficultyAward[p]->SetName( ssprintf("PerDifficultyAwardP%d",p+1) );
SET_XY_AND_ON_COMMAND( m_PerDifficultyAward[p] );
this->AddChild( m_PerDifficultyAward[p] );
}
}
@@ -874,6 +877,68 @@ void ScreenEvaluation::CommitScores( const StageStats &stageStats, int iPersonal
if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore )
PROFILEMAN->AddStepsHighScore( GAMESTATE->m_pCurNotes[p], (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] );
if( PROFILEMAN->IsUsingProfile((PlayerNumber)p) )
{
// check for awards
Profile* pProfile = PROFILEMAN->GetProfile((PlayerNumber)p);
if( stageStats.FullComboOfScore( (PlayerNumber)p, TNS_GREAT ) )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_FULL_COMBO_GREATS );
if( stageStats.FullComboOfScore( (PlayerNumber)p, TNS_PERFECT ) )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_FULL_COMBO_PERFECTS );
if( stageStats.FullComboOfScore( (PlayerNumber)p, TNS_MARVELOUS ) )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_FULL_COMBO_MARVELOUSES );
if( stageStats.SingleDigitsOfScore( (PlayerNumber)p, TNS_GREAT ) )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_SINGLE_DIGIT_GREATS );
if( stageStats.SingleDigitsOfScore( (PlayerNumber)p, TNS_PERFECT ) )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_SINGLE_DIGIT_PERFECTS );
float fPercentGreats = stageStats.GetPercentageOfTaps((PlayerNumber)p, TNS_GREAT);
if( fPercentGreats >= 0.8f )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_GREATS_80_PERCENT );
if( fPercentGreats >= 0.9f )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_GREATS_90_PERCENT );
if( fPercentGreats >= 1.f )
GAMESTATE->m_vLastPerDifficultyAwards[p].push_back( AWARD_GREATS_100_PERCENT );
int iComboAtStartOfStage = stageStats.GetComboAtStartOfStage( (PlayerNumber)p );
int iPeakCombo = stageStats.GetMaxCombo((PlayerNumber)p).cnt;
FOREACH_PeakComboAward( pca )
{
int iLevel = 100/*0*/ * (pca+1);
bool bCrossedLevel = iComboAtStartOfStage < iLevel && iPeakCombo >= iLevel;
if( bCrossedLevel )
{
GAMESTATE->m_vLastPeakComboAwards[p].push_back( pca );
m_textJudgeNumbers[max_combo][p].Command( PEAK_COMBO_AWARD_COMMAND );
}
}
{
for( int i=GAMESTATE->m_vLastPerDifficultyAwards[p].size()-1; i>=0; i-- )
{
PerDifficultyAward pda = GAMESTATE->m_vLastPerDifficultyAwards[p][i];
Steps* pSteps = stageStats.pSteps[p];
bool bAlreadyHad = pProfile->HasPerDifficultyAward( pSteps->m_StepsType, pSteps->GetDifficulty(), pda );
pProfile->AddPerDifficultyAward( pSteps->m_StepsType, pSteps->GetDifficulty(), pda );
if( bAlreadyHad )
GAMESTATE->m_vLastPerDifficultyAwards[p].erase( GAMESTATE->m_vLastPerDifficultyAwards[p].begin()+i );
}
}
{
for( int i=GAMESTATE->m_vLastPeakComboAwards[p].size()-1; i>=0; i-- )
{
PeakComboAward pca = GAMESTATE->m_vLastPeakComboAwards[p][i];
bool bAlreadyHad = pProfile->HasPeakComboAward( pca );
pProfile->AddPeakComboAward( pca );
if( bAlreadyHad )
GAMESTATE->m_vLastPeakComboAwards[p].erase( GAMESTATE->m_vLastPeakComboAwards[p].begin()+i );
}
}
}
}
break;
@@ -1147,8 +1212,8 @@ void ScreenEvaluation::TweenOffScreen()
continue;
OFF_COMMAND( m_sprMachineRecord[p] );
OFF_COMMAND( m_sprPersonalRecord[p] );
if( m_FullCombo[p].IsLoaded() )
OFF_COMMAND( m_FullCombo[p] );
if( m_PerDifficultyAward[p].IsLoaded() )
OFF_COMMAND( m_PerDifficultyAward[p] );
}
OFF_COMMAND( m_sprTryExtraStage );
}
+3 -3
View File
@@ -31,8 +31,8 @@
#include "HighScore.h"
const int MAX_SONGS_TO_SHOW = 5; // In summary, we show last 3 stages, plus extra stages if passed
const int NUM_JUDGE_LINES = 9; // marvelous, perfect, great, good, boo, miss, ok, max_combo, error
const int NUM_STATS_LINES = 4; // jumps, holds, mines, hands
enum JudgeLine { marvelous, perfect, great, good, boo, miss, ok, max_combo, error, NUM_JUDGE_LINES };
enum StatsLine { jumps, holds, mines, hands, NUM_STATS_LINES };
// sound sequences for the evaluation screen
struct EvalSoundSequence
@@ -136,7 +136,7 @@ protected:
Sprite m_sprPersonalRecord[NUM_PLAYERS];
bool m_bTryExtraStage;
Sprite m_sprTryExtraStage;
AutoActor m_FullCombo[NUM_PLAYERS];
AutoActor m_PerDifficultyAward[NUM_PLAYERS];
bool m_bFailed;
RageSound m_soundStart; // sound played if the player passes or fails
+3
View File
@@ -1536,6 +1536,9 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
{
switch( DeviceI.button )
{
case SDLK_F5:
this->HandleScreenMessage( SM_NotesEnded );
break;
case SDLK_F6:
m_bChangedOffsetOrBPM = true;
GAMESTATE->m_SongOptions.m_bAutoSync = !GAMESTATE->m_SongOptions.m_bAutoSync; // toggle
+42 -15
View File
@@ -389,23 +389,51 @@ StageStats::Combo_t StageStats::GetMaxCombo( PlayerNumber pn ) const
return ComboList[pn][m];
}
bool StageStats::FullCombo( PlayerNumber pn ) const
int StageStats::GetComboAtStartOfStage( PlayerNumber pn ) const
{
if( ComboList[pn].size() != 1 )
{
LOG->Trace("FullCombo(%i): %i != 1", pn, (int)ComboList[pn].size());
return false;
}
if( ComboList[pn].empty() )
return 0;
else
return ComboList[pn][0].rollover;
}
const float ComboStart = ComboList[pn][0].start;
const float ComboEnd = ComboList[pn][0].start + ComboList[pn][0].size;
const bool ComboStartsAtBeginning = fabs( ComboStart - fFirstPos[pn] ) < 0.001f;
const bool ComboEndsAtEnd = fabs( ComboEnd - fLastPos[pn] ) < 0.001f;
bool StageStats::FullComboOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const
{
ASSERT( tnsAllGreaterOrEqual >= TNS_GREAT );
ASSERT( tnsAllGreaterOrEqual <= TNS_MARVELOUS );
LOG->Trace("FullCombo(%i): %f .. %f, %f .. %f, %i, %i",
pn, ComboStart, ComboEnd, fFirstPos[pn], fLastPos[pn], ComboStartsAtBeginning, ComboEndsAtEnd );
return ComboStartsAtBeginning && ComboEndsAtEnd;
for( int i=TNS_MISS; i<tnsAllGreaterOrEqual; i++ )
{
if( iTapNoteScores[pn][i] > 0 )
return false;
}
return true;
}
bool StageStats::SingleDigitsOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const
{
return FullComboOfScore( pn, tnsAllGreaterOrEqual ) &&
iTapNoteScores[pn][tnsAllGreaterOrEqual] < 10;
}
int StageStats::GetTotalTaps( PlayerNumber pn ) const
{
int iTotalTaps = 0;
for( int i=TNS_MISS; i<NUM_TAP_NOTE_SCORES; i++ )
{
iTotalTaps += iTapNoteScores[pn][i];
}
return iTotalTaps;
}
float StageStats::GetPercentageOfTaps( PlayerNumber pn, TapNoteScore tns ) const
{
int iTotalTaps = 0;
for( int i=TNS_MISS; i<NUM_TAP_NOTE_SCORES; i++ )
{
iTotalTaps += iTapNoteScores[pn][i];
}
return iTapNoteScores[pn][tns] / (float)iTotalTaps;
}
static Grade GetBestGrade()
@@ -487,4 +515,3 @@ Grade GetBestFinalGrade()
return top_grade;
}
LuaFunction_NoArgs( GetBestFinalGrade, GetBestFinalGrade() );
+6 -1
View File
@@ -94,7 +94,12 @@ struct StageStats
vector<Combo_t> ComboList[NUM_PLAYERS];
float fFirstPos[NUM_PLAYERS], fLastPos[NUM_PLAYERS];
bool FullCombo( PlayerNumber pn ) const;
int GetComboAtStartOfStage( PlayerNumber pn ) const;
bool FullComboOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const;
bool FullCombo( PlayerNumber pn ) const { return FullComboOfScore(pn,TNS_GREAT); }
bool SingleDigitsOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const;
int GetTotalTaps( PlayerNumber pn ) const;
float GetPercentageOfTaps( PlayerNumber pn, TapNoteScore tns ) const;
void UpdateComboList( PlayerNumber pn, float pos, bool rollover );
Combo_t GetMaxCombo( PlayerNumber pn ) const;
};
+23 -4
View File
@@ -58,14 +58,14 @@ BSC32=bscmake.exe
LINK32=link.exe
# ADD BASE LINK32 $(intdir)\verstub.obj kernel32.lib shell32.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /pdb:"../debug6/StepMania-debug.pdb" /map /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /out:"../StepMania-debug.exe"
# SUBTRACT BASE LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
# ADD LINK32 $(intdir)\verstub.obj kernel32.lib gdi32.lib shell32.lib user32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../Program/StepMania-debug.exe"
# ADD LINK32 $(intdir)\verstub.obj kernel32.lib gdi32.lib shell32.lib user32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../itg/Program/StepMania-debug.exe"
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
# Begin Special Build Tool
IntDir=.\../Debug6
TargetDir=\stepmania\stepmania\Program
TargetDir=\stepmania\itg\Program
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
# End Special Build Tool
@@ -142,7 +142,7 @@ IntDir=.\../Release6
TargetDir=\stepmania\stepmania\Program
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
# End Special Build Tool
@@ -4725,6 +4725,25 @@ SOURCE=.\ScreenAttract.h
# End Source File
# Begin Source File
SOURCE=.\ScreenAward.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
!ELSEIF "$(CFG)" == "StepMania - Xbox Debug"
!ELSEIF "$(CFG)" == "StepMania - Win32 Release"
!ELSEIF "$(CFG)" == "StepMania - Xbox Release"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\ScreenAward.h
# End Source File
# Begin Source File
SOURCE=.\ScreenBookkeeping.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
+7 -1
View File
@@ -82,7 +82,7 @@ cl /Zl /nologo /c verstub.cpp /Fo&quot;$(IntDir)&quot;\
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="./../Program"
OutputDirectory="./../../itg/Program"
IntermediateDirectory="./../Release"
ConfigurationType="1"
UseOfMFC="0"
@@ -175,6 +175,12 @@ cl /Zl /nologo /c verstub.cpp /Fo&quot;$(IntDir)&quot;\
<File
RelativePath="ScreenAttract.h">
</File>
<File
RelativePath="ScreenAward.cpp">
</File>
<File
RelativePath="ScreenAward.h">
</File>
<File
RelativePath="ScreenBookkeeping.cpp">
</File>