diff --git a/src/challenges/challenge_data.cpp b/src/challenges/challenge_data.cpp index f6116ba73..591998271 100755 --- a/src/challenges/challenge_data.cpp +++ b/src/challenges/challenge_data.cpp @@ -249,7 +249,7 @@ bool ChallengeData::raceFinished() // ---------------------------------------------------------------------------- bool ChallengeData::grandPrixFinished() { - printf("checking if GP challenge is solved"); + // printf("----- checking if GP challenge is solved\n"); if (race_manager->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX || race_manager->getMinorMode() != m_minor || race_manager->getGrandPrix()->getId() != m_gp_id || @@ -259,54 +259,9 @@ bool ChallengeData::grandPrixFinished() // check if the player came first. Kart* kart = RaceManager::getPlayerKart(0); - - // FIXME - this code is duplicated from GrandPrixEnding. We should find a cleaner way to solve this. - const unsigned int NUM_KARTS = race_manager->getNumKarts(); - - int *scores = new int[NUM_KARTS]; - int *position = new int[NUM_KARTS]; - double *race_time = new double[NUM_KARTS]; - // Ignore the first kart if it's a follow-the-leader race. - int start=(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER) ? 1 : 0; - for( unsigned int kart_id = start; kart_id < NUM_KARTS; ++kart_id ) - { - position[kart_id] = kart_id; - scores[kart_id] = race_manager->getKartScore(kart_id); - race_time[kart_id] = race_manager->getOverallTime(kart_id); - } - - //Bubblesort - bool sorted; - do - { - sorted = true; - for( unsigned int i = start; i < NUM_KARTS - 1; ++i ) - { - if( scores[i] < scores[i+1] || (scores[i] == scores[i+1] - && race_time[i] > race_time[i+1])) - { - int tmp_score[2]; - double tmp_time; - - tmp_score[0] = position[i]; - tmp_score[1] = scores[i]; - tmp_time = race_time[i]; - - position[i] = position[i+1]; - scores[i] = scores[i+1]; - race_time[i] = race_time[i+1]; - - position[i+1] = tmp_score[0]; - scores[i+1] = tmp_score[1]; - race_time[i+1] = tmp_time; - - sorted = false; - } - } - } while(!sorted); - - if(kart->getIdent() != race_manager->getKartName(position[start])) return false; // winner is not player - return true; - + const int rank = race_manager->getKartFinalGPRank(kart->getWorldKartId()); + //printf("getting rank for %s : %i \n", kart->getName().c_str(), rank ); + if( rank != 0 ) return false; + return true; } // grandPrixFinished diff --git a/src/gui/grand_prix_ending.cpp b/src/gui/grand_prix_ending.cpp index 2a36e973a..0bb4d1ccd 100644 --- a/src/gui/grand_prix_ending.cpp +++ b/src/gui/grand_prix_ending.cpp @@ -63,52 +63,25 @@ GrandPrixEnd::GrandPrixEnd() const unsigned int MAX_STR_LEN = 60; const unsigned int NUM_KARTS = race_manager->getNumKarts(); - - int *scores = new int[NUM_KARTS]; - int *position = new int[NUM_KARTS]; - double *race_time = new double[NUM_KARTS]; + // Ignore the first kart if it's a follow-the-leader race. int start=(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER) ? 1 : 0; - for( unsigned int kart_id = start; kart_id < NUM_KARTS; ++kart_id ) + + + int winner_kart_id = -1; + // find which kart ended at rank '0' + for(unsigned int j=start; j < NUM_KARTS; ++j) { - position[kart_id] = kart_id; - scores[kart_id] = race_manager->getKartScore(kart_id); - race_time[kart_id] = race_manager->getOverallTime(kart_id); - } - - //Bubblesort - bool sorted; - do - { - sorted = true; - for( unsigned int i = start; i < NUM_KARTS - 1; ++i ) + if( race_manager->getKartFinalGPRank(j) == 0 ) { - if( scores[i] < scores[i+1] || (scores[i] == scores[i+1] - && race_time[i] > race_time[i+1])) - { - int tmp_score[2]; - double tmp_time; - - tmp_score[0] = position[i]; - tmp_score[1] = scores[i]; - tmp_time = race_time[i]; - - position[i] = position[i+1]; - scores[i] = scores[i+1]; - race_time[i] = race_time[i+1]; - - position[i+1] = tmp_score[0]; - scores[i+1] = tmp_score[1]; - race_time[i+1] = tmp_time; - - sorted = false; - } + winner_kart_id = j; + break; } - } while(!sorted); + } static char output[MAX_MESSAGE_LENGTH]; snprintf(output, sizeof(output), - _("The winner is %s!"),race_manager->getKartName(position[start]).c_str()); // FIXME - uses inner-name and not user name + _("The winner is %s!"),race_manager->getKartName(winner_kart_id).c_str()); // FIXME - uses inner-name and not user name widget_manager->addWgt( WTOK_TITLE, 60, 10); widget_manager->showWgtRect(WTOK_TITLE); widget_manager->showWgtText(WTOK_TITLE); @@ -120,15 +93,26 @@ GrandPrixEnd::GrandPrixEnd() for(unsigned int i=start; i < NUM_KARTS; ++i) { - char sTime[20];sTime[0]=0; - //if(race_manager->getWorld()->getClockMode()==CHRONO) + // char sTime[20];sTime[0]=0; + // if(RaceManager::isLinearRaceMode(race_manager->getMinorMode()) && + // RaceManager::modeHasLaps(race_manager->getMinorMode()) ) + // TimeToString(race_time[i], sTime); - if(RaceManager::isLinearRaceMode(race_manager->getMinorMode()) && - RaceManager::modeHasLaps(race_manager->getMinorMode()) ) - TimeToString(race_time[i], sTime); - - sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %d %s", - i + 1-start, race_manager->getKartName(position[i]).c_str(), scores[i], sTime ); + int this_kart_id = -1; + // find which kart ended at rank 'i' + for(unsigned int j=start; j < NUM_KARTS; ++j) + { + if( race_manager->getKartFinalGPRank(j) == i-start ) + { + this_kart_id = j; + break; + } + } + + sprintf((char*)(m_score + MAX_STR_LEN * i), "#%d (%d) : %s", + i-start + 1 /* add 1 because, while the inner ranks start at 0, users expect them to start at 1 */, + race_manager->getKartScore(this_kart_id), + race_manager->getKartName(this_kart_id).c_str() ); widget_manager->addWgt(WTOK_FIRSTKART + i, 40, 5); widget_manager->showWgtRect(WTOK_FIRSTKART + i); @@ -138,11 +122,8 @@ GrandPrixEnd::GrandPrixEnd() widget_manager->setWgtTextSize(WTOK_FIRSTKART + i, WGT_FNT_SML); widget_manager->breakLine(); } - const std::string KART_NAME = race_manager->getKartName(position[start]); - const KartProperties* WINNING_KART = kart_properties_manager->getKart(KART_NAME); - delete []scores; - delete []position; - delete []race_time; + const std::string WINNER_KART_NAME = race_manager->getKartName(winner_kart_id); + const KartProperties* WINNING_KART = kart_properties_manager->getKart(WINNER_KART_NAME); widget_manager->addWgt(WTOK_QUIT, 50, 7); widget_manager->activateWgt(WTOK_QUIT); diff --git a/src/gui/race_results_gui.cpp b/src/gui/race_results_gui.cpp index 810112dd2..b0ed6cda2 100644 --- a/src/gui/race_results_gui.cpp +++ b/src/gui/race_results_gui.cpp @@ -173,8 +173,8 @@ Widget *RaceResultsGUI::displayKartList(Widget *w_prev, int *order, float horizo //This shows position + driver name + time + points earned + total points if(race_manager->getMajorMode()==RaceManager::MAJOR_MODE_GRAND_PRIX) { - sprintf((char*)(score + MAX_STR_LEN * i), "%d. %s %s +%d %d", - current_kart->getPosition(), kart_name.c_str(), sTime, + sprintf((char*)(score + MAX_STR_LEN * i), "#%d. %s (%d -> %d)", + current_kart->getPosition(), kart_name.c_str(),// sTime, race_manager->getKartPrevScore(order[i]), race_manager->getKartScore(order[i])); } diff --git a/src/race_manager.cpp b/src/race_manager.cpp index 07a753502..94496ff74 100644 --- a/src/race_manager.cpp +++ b/src/race_manager.cpp @@ -299,6 +299,60 @@ void RaceManager::exit_race() // were finished, and not when a race is aborted. if(m_major_mode==MAJOR_MODE_GRAND_PRIX && m_track_number==(int)m_tracks.size()) { + // calculate the rank of each kart + const unsigned int NUM_KARTS = race_manager->getNumKarts(); + + int *scores = new int[NUM_KARTS]; + int *position = new int[NUM_KARTS]; + double *race_time = new double[NUM_KARTS]; + // Ignore the first kart if it's a follow-the-leader race. + int start=(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER) ? 1 : 0; + for( unsigned int kart_id = start; kart_id < NUM_KARTS; ++kart_id ) + { + position[kart_id] = kart_id; + scores[kart_id] = race_manager->getKartScore(kart_id); + race_time[kart_id] = race_manager->getOverallTime(kart_id); + } + + //Bubblesort + bool sorted; + do + { + sorted = true; + for( unsigned int i = start; i < NUM_KARTS - 1; ++i ) + { + if( scores[i] < scores[i+1] || (scores[i] == scores[i+1] + && race_time[i] > race_time[i+1])) + { + int tmp_score[2]; + double tmp_time; + + tmp_score[0] = position[i]; + tmp_score[1] = scores[i]; + tmp_time = race_time[i]; + + position[i] = position[i+1]; + scores[i] = scores[i+1]; + race_time[i] = race_time[i+1]; + + position[i+1] = tmp_score[0]; + scores[i+1] = tmp_score[1]; + race_time[i+1] = tmp_time; + + sorted = false; + } + } + } while(!sorted); + + for(unsigned int i=start; i < NUM_KARTS; ++i) + { + //printf("setting kart %s to rank %i\n", race_manager->getKartName(position[i]).c_str(), i); + m_kart_status[position[i]].m_gp_final_rank = i; + } + delete []scores; + delete []position; + delete []race_time; + unlock_manager->grandPrixFinished(); menu_manager->switchToGrandPrixEnding(); } diff --git a/src/race_manager.hpp b/src/race_manager.hpp index 149610bc3..5214f4063 100644 --- a/src/race_manager.hpp +++ b/src/race_manager.hpp @@ -110,7 +110,8 @@ private: KartType m_kart_type; // Kart type: AI, player, network player etc. int m_local_player_id; // player controling the kart, for AI: -1 int m_global_player_id; // global ID of player - + int m_gp_final_rank; // In GPs, at the end, will hold the overall rank of this kart. + KartStatus(const std::string& ident, const int& prev_finish_pos, int local_player_id, int global_player_id, KartType kt) : m_ident(ident), m_score(0), m_last_score(0), @@ -194,7 +195,11 @@ public: const GrandPrixData *getGrandPrix() const { return &m_grand_prix; } unsigned int getFinishedKarts() const { return m_num_finished_karts; } unsigned int getFinishedPlayers() const { return m_num_finished_players; } - const std::string& getItemStyle() const { return m_grand_prix.getItemStyle(); } + const std::string& getItemStyle() const { return m_grand_prix.getItemStyle(); } + + int getKartFinalGPRank(const int kart_id) + const { return m_kart_status[kart_id].m_gp_final_rank; } + const std::string& getKartName(int kart) const { return m_kart_status[kart].m_ident;} int getKartScore(int krt) const { return m_kart_status[krt].m_score; }