From 11e74fe90cee96e8898134117d14f5fb5f1989da Mon Sep 17 00:00:00 2001 From: Mark Cannon Date: Wed, 2 Jul 2008 07:21:02 +0000 Subject: [PATCH] Lots of tournament code updates git-svn-id: https://openitg.svn.sourceforge.net/svnroot/openitg@417 83fadc84-e282-4d84-a09a-c4228d6ae7e5 --- src/ScreenEvaluation.cpp | 2 +- src/ScreenTournamentOptions.cpp | 203 +++++++++++++++++++++++++++++++++++----- src/ScreenTournamentOptions.h | 15 ++- src/TournamentManager.cpp | 152 ++++++++++++++++++++---------- src/TournamentManager.h | 87 ++++++++++++----- 5 files changed, 362 insertions(+), 97 deletions(-) diff --git a/src/ScreenEvaluation.cpp b/src/ScreenEvaluation.cpp index b62fbc23..49b5570b 100755 --- a/src/ScreenEvaluation.cpp +++ b/src/ScreenEvaluation.cpp @@ -94,7 +94,7 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName ) : ScreenWithMenuElement { LOG->Trace( "ScreenEvaluation::ScreenEvaluation" ); - TOURNAMENT->FinishMatch( STATSMAN->m_CurStageStats ); + TOURNAMENT->FinishStage( STATSMAN->m_CurStageStats ); // // debugging diff --git a/src/ScreenTournamentOptions.cpp b/src/ScreenTournamentOptions.cpp index a88a3acd..2669687f 100644 --- a/src/ScreenTournamentOptions.cpp +++ b/src/ScreenTournamentOptions.cpp @@ -12,7 +12,21 @@ REGISTER_SCREEN_CLASS( ScreenTournamentOptions ); -enum { +AutoScreenMessage( SM_BackFromRegisterMenu ); + +AutoScreenMessage( SM_SetDisplayName ); +AutoScreenMessage( SM_SetScoreName ); +AutoScreenMessage( SM_SetSeed ); +AutoScreenMessage( SM_RegisterPlayer ); + +// globals to store current player data +CString g_sCurPlayerName = ""; +CString g_sCurScoreName = ""; +unsigned g_iCurSeedIndex = 0; +int g_CurPlayerIndex = -1; + +enum TournamentOptionsLine +{ PO_ADD_PLAYER, PO_REMOVE_PLAYER, PO_SET_QUALIFY_SONG, @@ -20,14 +34,82 @@ enum { }; OptionRowDefinition g_TournamentOptionsLines[NUM_TOURNAMENT_OPTIONS_LINES] = { - OptionRowDefinition( "Add competitor", true, "Press START" ), - OptionRowDefinition( "Remove competitor", true ), - OptionRowDefinition( "Set qualifier song", true ), -// OptionRowDefinition( "", true ), + OptionRowDefinition( "AddPlayer", true, "Press START" ), + OptionRowDefinition( "ModifyPlayer", true ), + OptionRowDefinition( "SetQualifier", true ) +}; + +enum RegisterMenuChoice +{ + set_player_name, + set_highscore_name, + set_seed_number, + exit_and_register, + exit_and_delete, + exit_and_cancel, + NUM_REGISTER_MENU_CHOICES }; -AutoScreenMessage( SM_DoneCreating ); -AutoScreenMessage( SM_DoneDeleting ); +/* Row definitions. UGLY: MenuRow assumes Edit mode, but this isn't. We'll fix this up sometime... */ +MenuRow set_player_name_row = MenuRow( set_player_name, "Set player name", true, EDIT_MODE_PRACTICE, 0 ); +MenuRow set_highscore_name_row = MenuRow( set_highscore_name, "Set highscore name", true, EDIT_MODE_PRACTICE, 0 ); +MenuRow set_seed_number_row = MenuRow( set_seed_number, "Set seed (optional)", true, EDIT_MODE_PRACTICE, 0 ); +MenuRow exit_and_register_row = MenuRow( exit_and_register, "Finish registration", (!g_sCurPlayerName.empty() && !g_sCurScoreName.empty()), EDIT_MODE_PRACTICE, 0 ); +MenuRow exit_and_delete_row = MenuRow( exit_and_delete, "Delete registration", true, EDIT_MODE_PRACTICE, 0 ); +MenuRow exit_and_cancel_row = MenuRow( exit_and_cancel, "Cancel registration", true, EDIT_MODE_PRACTICE, 0 ); + +static Menu g_RegisterMenu +( +"ScreenMiniMenuRegisterMenu", +set_player_name_row, +set_highscore_name_row, +set_seed_number_row, +exit_and_register_row, +exit_and_cancel_row +); + +// this is used to cancel registrations +static Menu g_RegisterModifyMenu +( + "ScreenMiniMenuRegisterModifyMenu", + set_player_name_row, + set_highscore_name_row, + set_seed_number_row, + exit_and_register_row, + exit_and_delete_row +); + +// helper functions + +void RefreshRegisterMenuText() +{ + g_RegisterMenu.rows[set_player_name].choices.resize(1); + g_RegisterMenu.rows[set_player_name].choices[0] = g_sCurPlayerName; + g_RegisterMenu.rows[set_highscore_name].choices.resize(1); + g_RegisterMenu.rows[set_highscore_name].choices[0] = g_sCurScoreName; + g_RegisterMenu.rows[set_seed_number].choices.resize(1); + g_RegisterMenu.rows[set_seed_number].choices[0] = ssprintf( "%i", g_iCurSeedIndex ); +} + +void RefreshRegisterModifyMenuText() +{ +} + +void LoadCompetitor( Competitor *cptr ) +{ + g_sCurPlayerName = cptr->sDisplayName; + g_sCurScoreName = cptr->sHighScoreName; + g_iCurSeedIndex = cptr->iSeedIndex; + g_CurPlayerIndex = TOURNAMENT->FindCompetitorIndex( cptr ); +} + +void ResetPlayerData() +{ + g_sCurPlayerName = ""; + g_sCurScoreName = ""; + g_iCurSeedIndex = 0; + g_CurPlayerIndex = -1; +} ScreenTournamentOptions::ScreenTournamentOptions( CString sClassName ) : ScreenOptions( sClassName ) { @@ -38,60 +120,137 @@ void ScreenTournamentOptions::Init() { ScreenOptions::Init(); - g_TournamentOptionsLines[PO_ADD_PLAYER].choices.clear(); - g_TournamentOptionsLines[PO_ADD_PLAYER].choices.push_back( "Press START" ); - // enable all lines for all players for( unsigned i = 0; i < NUM_TOURNAMENT_OPTIONS_LINES; i++ ) FOREACH_PlayerNumber( pn ) g_TournamentOptionsLines[i].m_vEnabledForPlayers.insert( pn ); + g_TournamentOptionsLines[PO_ADD_PLAYER].choices.clear(); + g_TournamentOptionsLines[PO_ADD_PLAYER].choices.push_back( "Press START" ); + g_TournamentOptionsLines[PO_REMOVE_PLAYER].choices.clear(); + g_TournamentOptionsLines[PO_REMOVE_PLAYER].choices.push_back( "-NO ENTRIES-" ); + g_TournamentOptionsLines[PO_SET_QUALIFY_SONG].choices.clear(); + g_TournamentOptionsLines[PO_SET_QUALIFY_SONG].choices.push_back( "-NO ENTRIES-" ); + vector vDefs( &g_TournamentOptionsLines[0], &g_TournamentOptionsLines[ARRAYSIZE(g_TournamentOptionsLines)] ); vector vHands( vDefs.size(), NULL ); - SetNavigation( NAV_THREE_KEY ); InitMenu( INPUTMODE_SHARE_CURSOR, vDefs, vHands ); } void ScreenTournamentOptions::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) { + CHECKPOINT_M( "Input start" ); + ScreenOptions::Input( DeviceI, type, GameI, MenuI, StyleI ); + CHECKPOINT_M( "Input end" ); } void ScreenTournamentOptions::HandleScreenMessage( const ScreenMessage SM ) { - if( SM == SM_DoneCreating ) + if( SM == SM_BackFromRegisterMenu ) { - if( !ScreenTextEntry::s_bCancelledLast && ScreenTextEntry::s_sLastAnswer != "" ) + switch( ScreenMiniMenu::s_iLastRowCode ) { - CString sError; - bool bResult = TOURNAMENT->RegisterCompetitor( ScreenTextEntry::s_sLastAnswer, "BLAH", sError ); + case set_player_name: + SCREENMAN->TextEntry( SM_SetDisplayName, ssprintf( "Player %u's name:", TOURNAMENT->GetNumCompetitors()+1), "", 12 ); + break; + case set_highscore_name: + SCREENMAN->TextEntry( SM_SetScoreName, ssprintf( "Highscore name for %s:", g_sCurPlayerName.c_str()), "", 4 ); + break; + case set_seed_number: + SCREENMAN->TextEntry( SM_SetSeed, ssprintf( "Seed index for %s:", g_sCurPlayerName.c_str()), "", 3 ); + break; + case exit_and_register: + { + CString sError; + bool bRegistered = TOURNAMENT->RegisterCompetitor( g_sCurPlayerName, g_sCurScoreName, g_iCurSeedIndex, sError ); - if( !bResult ) - SCREENMAN->SystemMessage( sError ); + if( bRegistered ) + ResetPlayerData(); // we're registered - reset and prepare for new data + else + SCREENMAN->SystemMessage( ssprintf( "Registration error: %s", sError.c_str()) ); + } + break; + case exit_and_delete: + { + // TODO: implement a smart vector deletion function + } + break; + case exit_and_cancel: + ResetPlayerData(); + break; } } + else if( SM == SM_SetDisplayName ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + g_sCurPlayerName = ScreenTextEntry::s_sLastAnswer; + } + else if( SM == SM_SetScoreName ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + g_sCurScoreName = ScreenTextEntry::s_sLastAnswer; + g_sCurScoreName.MakeUpper(); + } + else if( SM == SM_SetSeed ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + g_iCurSeedIndex = (int) strtof( ScreenTextEntry::s_sLastAnswer, NULL ); + } + else if( SM == SM_GoToNextScreen || SM == SM_GoToPrevScreen ) + { + SCREENMAN->SetNewScreen( PREV_SCREEN ); + } } -void ScreenTournamentOptions::MenuStart( PlayerNumber pn ) +void ScreenTournamentOptions::MenuStart( PlayerNumber pn, const InputEventType type ) { + if( type != IET_FIRST_PRESS ) + return; + switch( GetCurrentRow() ) { case PO_ADD_PLAYER: - SCREENMAN->TextEntry( SM_DoneCreating, "Enter the player's name", "", 12 ); + { + RefreshRegisterMenuText(); + SCREENMAN->MiniMenu( &g_RegisterMenu, SM_RegisterPlayer ); + } break; - } + default: + ScreenOptions::MenuStart( pn, type ); + } } -void ScreenTournamentOptions::MenuBack( PlayerNumber pn ) +void ScreenTournamentOptions::MenuBack( PlayerNumber pn, const InputEventType type ) { + TOURNAMENT->DumpCompetitors(); + if( !IsTransitioning() ) + { + this->PlayCommand( "Off" ); + this->StartTransitioning( SM_GoToPrevScreen ); + } } void ScreenTournamentOptions::ImportOptions( int row, const vector &vpns ) { - + LOG->Debug( "ScreenTournamentOptions::ImportOptions( %i, vpns )", row ); + + switch( row ) + { + case PO_REMOVE_PLAYER: + { + LOG->Debug( "Getting indexes and names." ); + TOURNAMENT->GetCompetitorNames( g_TournamentOptionsLines[PO_REMOVE_PLAYER].choices, true ); + + for( unsigned i = 0; i < g_TournamentOptionsLines[PO_REMOVE_PLAYER].choices.size(); i++ ) + ssprintf( "Choice %i: %s", i+1, g_TournamentOptionsLines[PO_REMOVE_PLAYER].choices[i].c_str() ); + } + break; + } } void ScreenTournamentOptions::ExportOptions( int row, const vector &vpns ) { + } void ScreenTournamentOptions::GoToPrevScreen() diff --git a/src/ScreenTournamentOptions.h b/src/ScreenTournamentOptions.h index 83b3e210..10ce0575 100644 --- a/src/ScreenTournamentOptions.h +++ b/src/ScreenTournamentOptions.h @@ -1,6 +1,7 @@ #ifndef SCREEN_TOURNAMENT_OPTIONS_H #define SCREEN_TOURNAMENT_OPTIONS_H +#include "TournamentManager.h" #include "ScreenOptions.h" #include "PlayerNumber.h" @@ -14,9 +15,19 @@ public: 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 ); - virtual void MenuBack( PlayerNumber pn ); + virtual void MenuStart( PlayerNumber pn, const InputEventType type ); + virtual void MenuBack( PlayerNumber pn, const InputEventType type ); +/* + virtual void MenuLeft( PlayerNumber pn, const InputEventType type ) { LOG->Debug( "MenuLeft(%i)", pn+1); } + virtual void MenuRight( PlayerNumber pn, const InputEventType type ) { LOG->Debug( "MenuRight(%i)", pn+1); } + virtual void MenuUp( PlayerNumber pn, const InputEventType type ) { LOG->Debug( "MenuUp(%i)", pn+1); } + virtual void MenuDown( PlayerNumber pn, const InputEventType type ) { LOG->Debug( "MenuDown(%i)", pn+1); } +*/ + private: + CString m_sPlayerName, m_sPlayerScoreName; + bool RegistrationValid(); + virtual void ImportOptions( int row, const vector &vpns ); virtual void ExportOptions( int row, const vector &vpns ); diff --git a/src/TournamentManager.cpp b/src/TournamentManager.cpp index b23d08f9..95bf555f 100644 --- a/src/TournamentManager.cpp +++ b/src/TournamentManager.cpp @@ -4,11 +4,12 @@ #include "TournamentManager.h" #include "PrefsManager.h" #include "ProfileManager.h" -#include "GameState.h" // XXX: needed for course data +#include "GameState.h" #include "GameConstantsAndTypes.h" #include "StageStats.h" #include "Course.h" #include "song.h" +#include "Steps.h" #include "StepsUtil.h" #include "DateTime.h" #include "PlayerNumber.h" @@ -17,27 +18,25 @@ TournamentManager* TOURNAMENT = NULL; TournamentManager::TournamentManager() { - LOG->Debug( "TournamentManager::TournamentManager()" ); + Init(); +} +void TournamentManager::Init() +{ m_iMeterLimitLow = m_iMeterLimitHigh = -1; m_DifficultyLimitLow = m_DifficultyLimitHigh = DIFFICULTY_INVALID; m_pCurMatch = NULL; + m_pCurStage = NULL; FOREACH_PlayerNumber( pn ) m_pCurCompetitor[pn] = NULL; m_Round = ROUND_QUALIFIERS; - - m_iMeterLimitLow = 6; - m_iMeterLimitHigh = 11; - m_DifficultyLimitLow = DIFFICULTY_EASY; - m_DifficultyLimitHigh = DIFFICULTY_MEDIUM; - } TournamentManager::~TournamentManager() { - LOG->Debug( "TournamentManager::~TournamentManager()" ); - + DumpCompetitors(); + // de-allocate all matches and data Reset(); } @@ -48,7 +47,6 @@ bool TournamentManager::IsTournamentMode() void TournamentManager::RemoveStepsOutsideLimits( vector &vpSteps ) { - CHECKPOINT_M( "RemoveSteps" ); // don't apply limits if we don't need to if( !this->IsTournamentMode() ) return; @@ -58,21 +56,38 @@ void TournamentManager::RemoveStepsOutsideLimits( vector &vpSteps ) StepsUtil::RemoveStepsOutsideMeterRange( vpSteps, m_iMeterLimitLow, m_iMeterLimitHigh ); StepsUtil::RemoveStepsOutsideDifficultyRange( vpSteps, m_DifficultyLimitLow, m_DifficultyLimitHigh ); - CHECKPOINT_M( "~RemoveSteps" ); } bool TournamentManager::HasStepsInsideLimits( Song *pSong ) const { + ASSERT( m_iMeterLimitLow <= m_iMeterLimitHigh ); ASSERT( m_DifficultyLimitLow <= m_DifficultyLimitHigh ); return pSong->HasStepsWithinMeterAndDifficultyRange( m_iMeterLimitLow, m_iMeterLimitHigh, m_DifficultyLimitLow, m_DifficultyLimitHigh, STEPS_TYPE_DANCE_SINGLE ); } -int TournamentManager::FindIndexOfCompetitor( Competitor *cptr ) +void TournamentManager::GetCompetitorNames( vector &vsNames, bool bDisplayIndex ) +{ + LOG->Debug( "TournamentManager::GetCompetitorNames()" ); + vsNames.clear(); + + LOG->Debug( "Size of vector: %i", m_pCompetitors.size() ); + + // "1: Player 1" vs. "Player 1" + for( unsigned i = 0; i < m_pCompetitors.size(); i++ ) + { + LOG->Debug( "Iteration: %i", i ); + CString sNewLine = bDisplayIndex ? ssprintf("%i: %s", i+1, m_pCompetitors[i]->sDisplayName.c_str()) : m_pCompetitors[i]->sDisplayName; + LOG->Debug( "Adding line \"%s\" to vsNames.", sNewLine.c_str() ); + vsNames.push_back( sNewLine ); + } +} + +int TournamentManager::FindCompetitorIndex( Competitor *cptr ) { for( unsigned i = 0; i < m_pCompetitors.size(); i++ ) - if( m_pCompetitors[i]->sDisplayName.compare(cptr->sDisplayName)) + if( &m_pCompetitors[i] == &cptr ) return i; return -1; @@ -81,24 +96,35 @@ int TournamentManager::FindIndexOfCompetitor( Competitor *cptr ) Competitor *TournamentManager::FindCompetitorByName( CString sName ) { for( unsigned i = 0; i < m_pCompetitors.size(); i++ ) + { if( m_pCompetitors[i]->sDisplayName.compare(sName) ) + { + ssprintf("%s matches %s", m_pCompetitors[i]->sDisplayName.c_str(), sName.c_str() ); return m_pCompetitors[i]; + } + } return NULL; } void TournamentManager::Reset() { - for( unsigned i = 0; i < m_pCompetitors.size(); i++ ) - SAFE_DELETE( m_pCompetitors[i] ); - m_pCompetitors.clear(); - for( unsigned i = 0; i < m_pMatches.size(); i++ ) + { + // matches have pointers to stages - delete them first + for( unsigned j = 0; j < m_pMatches[i]->vStages.size(); j++ ) + SAFE_DELETE( m_pMatches[i]->vStages[j] ); + SAFE_DELETE( m_pMatches[i] ); + } m_pMatches.clear(); + + for( unsigned i = 0; i < m_pCompetitors.size(); i++ ) + SAFE_DELETE( m_pCompetitors[i] ); + m_pCompetitors.clear(); } -bool TournamentManager::RegisterCompetitor( CString sDisplayName, CString sHighScoreName, CString &sError ) +bool TournamentManager::RegisterCompetitor( CString sDisplayName, CString sHighScoreName, unsigned iSeed, CString &sError ) { if( !this->IsTournamentMode() ) return false; @@ -110,21 +136,27 @@ bool TournamentManager::RegisterCompetitor( CString sDisplayName, CString sHighS if( sDisplayName.empty() ) cptr->sDisplayName = ssprintf( "Player %i", m_pCompetitors.size()+1 ); +#if 0 // make sure we don't have any naming conflicts Competitor *conflict = FindCompetitorByName(cptr->sDisplayName); - if( &conflict != NULL ) + if( conflict != NULL ) { - sError = ssprintf( "same name as player %i", FindIndexOfCompetitor(conflict)+1 ); + sError = ssprintf( "duplicate name." ); delete cptr; return false; } +#endif cptr->sDisplayName = sDisplayName; + cptr->iSeedIndex = iSeed; // do we need to re-enforce the high score name length here? cptr->sHighScoreName = sHighScoreName; + m_pCompetitors.push_back( cptr ); + DumpCompetitors(); + return true; } @@ -135,81 +167,102 @@ void TournamentManager::StartMatch() LOG->Debug( "TournamentManager::StartMatch()" ); ASSERT( m_pCurMatch == NULL ); + ASSERT( m_pCurStage == NULL ); TournamentMatch *match = new TournamentMatch; + TournamentStage *stage = new TournamentStage; - match->sTimePlayed = DateTime::GetNowDateTime().GetString(); + // fill in new match data match->sRound = TournamentRoundToString( m_Round ); - if( GAMESTATE->m_PlayMode == PLAY_MODE_REGULAR || GAMESTATE->m_PlayMode == PLAY_MODE_RAVE ) + FOREACH_PlayerNumber( pn ) { - // fill in song data. XXX: GameState - match->sGroup = GAMESTATE->m_pCurSong->m_sGroupName; - match->sTitle = GAMESTATE->m_pCurSong->GetDisplayFullTitle(); + match->sPlayer[pn] = PROFILEMAN->GetPlayerName(pn); +// match->iSeedIndex[pn] = m_pCurCompetitor[pn]->iSeedIndex; } - else + + // fill in new stage data + stage->sTimePlayed = DateTime::GetNowDateTime().GetString(); + + stage->bIsSong = GAMESTATE->m_PlayMode == PLAY_MODE_REGULAR || GAMESTATE->m_PlayMode == PLAY_MODE_RAVE; + + if( stage->bIsSong ) { - // fill in course data. XXX: GameState - match->sGroup = GAMESTATE->m_pCurCourse->m_sGroupName; - match->sTitle = GAMESTATE->m_pCurCourse->GetDisplayFullTitle(); + // fill in song data + stage->sGroup = GAMESTATE->m_pCurSong->m_sGroupName; + stage->sTitle = GAMESTATE->m_pCurSong->GetDisplayFullTitle(); + stage->sDifficulty = DifficultyToString(GAMESTATE->m_pCurSteps[0]->GetDifficulty()); } - - FOREACH_PlayerNumber( pn ) + else { - match->sPlayer[pn] = PROFILEMAN->GetPlayerName(pn); -// match->iSeedIndex[pn] = m_pCurCompetitor[pn]->iSeedIndex; + // fill in course data + stage->sGroup = GAMESTATE->m_pCurCourse->m_sGroupName; + stage->sTitle = GAMESTATE->m_pCurCourse->GetDisplayFullTitle(); + stage->sDifficulty = CourseDifficultyToString(GAMESTATE->m_pCurTrail[0]->m_CourseDifficulty); } m_pCurMatch = match; + m_pCurStage = stage; } // we don't want to save this data if the player backed out. -// delete the allocated data and re-set for a new match. +// delete the allocated data and re-set for a new stage. +void TournamentManager::CancelStage() +{ + if( m_pCurStage == NULL ) + return; + + LOG->Debug( "TournamentManager::CancelStage()" ); + + SAFE_DELETE( m_pCurStage ); +} + void TournamentManager::CancelMatch() { - if( !this->IsTournamentMode() ) + if( m_pCurMatch == NULL ) return; - LOG->Debug( "TOurnamentManager::CancelMatch()" ); + // free the stages we've played in this match + for( unsigned i = 0; i < m_pCurMatch->vStages.size(); i++ ) + SAFE_DELETE( m_pCurMatch->vStages[i] ); SAFE_DELETE( m_pCurMatch ); } // save all scores and game data from the stats given -void TournamentManager::FinishMatch( StageStats &stats ) +void TournamentManager::FinishStage( StageStats &stats ) { if( !this->IsTournamentMode() ) return; - LOG->Debug( "TournamentManager::FinishMatch()" ); + LOG->Debug( "TournamentManager::FinishStage()" ); FOREACH_PlayerNumber( pn ) { // fill in score data - m_pCurMatch->iActualPoints[pn] = stats.m_player[pn].iActualDancePoints; - m_pCurMatch->iPossiblePoints[pn] = stats.m_player[pn].iPossibleDancePoints; + m_pCurStage->iActualPoints[pn] = stats.m_player[pn].iActualDancePoints; + m_pCurStage->iPossiblePoints[pn] = stats.m_player[pn].iPossibleDancePoints; // truncate the rest to avoid rounding errors - m_pCurMatch->fPercentPoints[pn] = ftruncf( stats.m_player[pn].GetPercentDancePoints(), 0.0001 ); + m_pCurStage->fPercentPoints[pn] = ftruncf( stats.m_player[pn].GetPercentDancePoints(), 0.0001 ); FOREACH_TapNoteScore( tns ) - m_pCurMatch->iTapNoteScores[pn][tns] = stats.m_player[pn].iTapNoteScores[tns]; + m_pCurStage->iTapNoteScores[pn][tns] = stats.m_player[pn].iTapNoteScores[tns]; FOREACH_HoldNoteScore( hns ) - m_pCurMatch->iHoldNoteScores[pn][hns] = stats.m_player[pn].iHoldNoteScores[hns]; + m_pCurStage->iHoldNoteScores[pn][hns] = stats.m_player[pn].iHoldNoteScores[hns]; // neither player won if( !stats.OnePassed() ) - m_pCurMatch->winner = PLAYER_INVALID; + m_pCurStage->iWinner = -1; } - m_pMatches.push_back( m_pCurMatch ); - m_pCurMatch = NULL; - - m_Round = (TournamentRound)((int)m_Round + 1); // debugging + m_pCurMatch->vStages.push_back( m_pCurStage ); + m_pCurStage = NULL; } void TournamentManager::DumpMatches() { +#if 0 for( unsigned i = 0; i < m_pMatches.size(); i++ ) { LOG->Debug( "Match %i: %s vs. %s, points %i vs. %i\non song %s in group %s\nPlayed on %s", @@ -217,6 +270,7 @@ void TournamentManager::DumpMatches() m_pMatches[i]->iActualPoints[PLAYER_1], m_pMatches[i]->iActualPoints[PLAYER_2], m_pMatches[i]->sTitle.c_str(), m_pMatches[i]->sGroup.c_str(), m_pMatches[i]->sTimePlayed.c_str() ); } +#endif } void TournamentManager::DumpCompetitors() diff --git a/src/TournamentManager.h b/src/TournamentManager.h index 493539f4..954ec91a 100644 --- a/src/TournamentManager.h +++ b/src/TournamentManager.h @@ -16,40 +16,69 @@ struct lua_State; const unsigned TOURNAMENT_MAX_PLAYERS = 256; -// a struct that holds the saved data of a tournament match; +// a struct that holds the saved data of a single tournament stage; // this is sort of a watered-down PlayerStageStats -struct TournamentMatch +struct TournamentStage { - CString sPlayer[NUM_PLAYERS]; - int iSeedIndex[NUM_PLAYERS]; - // score data + CString sModifiers[NUM_PLAYERS]; int iActualPoints[NUM_PLAYERS]; - int iPossiblePoints[NUM_PLAYERS]; + int iPossiblePoints[NUM_PLAYERS]; // this may be different due to insert mods float fPercentPoints[NUM_PLAYERS]; int iTapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES]; int iHoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES]; - // general statistics - CString sGroup, sTitle; - CString sTimePlayed; - CString sDifficulty; - CString sRound; // the round of the tournament - CString sStage; // the sta + // data on the song or course played + bool bIsSong; + CString sGroup, sTitle, sDifficulty, sTimePlayed; + + // corresponds to one seed index, or -1 for a tie + int iWinner; + + // stage of the match this was played + Stage stage; +}; + +// a struct that holds data for an entire match, +// allowing for as many stages as needed +struct TournamentMatch +{ +/* I'm not sure if we need this... - Vyhd + ~TournamentMatch() + { + for( unsigned i = 0; i < vStages.size(); i++ ) + SAFE_DELETE( vStages[i] ); + vStages.clear(); + } +*/ + + CString sPlayer[NUM_PLAYERS]; + int iSeedIndex[NUM_PLAYERS]; + + // the round this match was held in + CString sRound; - PlayerNumber winner; + std::vector vStages; }; // a player in the tournament format struct Competitor { + Competitor(): sDisplayName(""), + sHighScoreName(""), iSeedScorePossible(0), + iSeedScoreActual(0), iSeedIndex(0) + { } + CString sDisplayName, sHighScoreName; // i prefer keeping these unsigned so we don't // run into floating-point-related problems ~ Vyhd unsigned iSeedScorePossible; unsigned iSeedScoreActual; - unsigned iSeedIndex; + unsigned iSeedIndex; + + vector vPlayedSongs; + vector vPlayedMatches; }; class TournamentManager @@ -58,21 +87,33 @@ public: TournamentManager(); ~TournamentManager(); - // currently used data + void Init(); + Competitor *m_pCurCompetitor[NUM_PLAYERS]; TournamentMatch *m_pCurMatch; + TournamentStage *m_pCurStage; void SetMeterLimitLow( int iLow ); void SetMeterLimitHigh( int iHigh ); void SetDifficultyLimitLow( Difficulty dLow ); void SetDifficultyLimitHigh( Difficulty dHigh ); - void StartMatch(); // initialise and save date, song, etc. - void CancelMatch(); // delete the data and prepare for a new match - void FinishMatch( StageStats &stats ); // save end-of-game data + void StartMatch(); + void CancelMatch(); + void FinishMatch(); + + void CancelStage(); + void FinishStage( StageStats &stats ); bool IsTournamentMode(); + void GetCompetitorNames( vector &vsNames, bool bDisplayIndex = false ); + void GetCompetitorNamesAndIndexes( vector &vsNames ) { GetCompetitorNames( vsNames, true ); } + + // vector search-and-find functions + int FindCompetitorIndex( Competitor *cptr ); + Competitor *FindCompetitorByName( CString sName ); + // some utilities to cleanly check against tournament limits void RemoveStepsOutsideLimits( vector &vpSteps ); bool HasStepsInsideLimits( Song *pSong ) const; @@ -80,12 +121,8 @@ public: TournamentRound GetCurrentRound() { return m_Round; } unsigned GetNumCompetitors() { return m_pCompetitors.size(); } - // vector search-and-find functions - int FindIndexOfCompetitor( Competitor *cptr ); - Competitor *FindCompetitorByName( CString sName ); - // attempt to add a new, unique competitor - bool RegisterCompetitor( CString sDisplayName, CString sHighScoreName, CString &sError ); + bool RegisterCompetitor( CString sDisplayName, CString sHighScoreName, unsigned iSeed, CString &sError ); void Reset(); void PushSelf( lua_State *L ); @@ -94,6 +131,10 @@ public: void DumpMatches(); void DumpCompetitors(); private: + // conditions to win + bool m_bChoosingPlayerLosesIfBothFail; + PlayerNumber m_ChoosingPlayer; + // limitations on the playable songs + steps int m_iMeterLimitLow, m_iMeterLimitHigh; Difficulty m_DifficultyLimitLow, m_DifficultyLimitHigh; -- 2.11.0