From 35c1c3eb32af178518cf3ca5b75f65a04781da33 Mon Sep 17 00:00:00 2001 From: auria Date: Thu, 16 Oct 2008 19:53:37 +0000 Subject: [PATCH] work towards encapsulation of race results display git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2344 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/gui/race_results_gui.cpp | 39 +++++++++++++++------------ src/gui/race_results_gui.hpp | 5 +--- src/modes/follow_the_leader.cpp | 43 ++++++++++++++++++++++++++++++ src/modes/follow_the_leader.hpp | 4 +++ src/modes/linear_world.cpp | 8 ++++++ src/modes/linear_world.hpp | 5 +++- src/modes/three_strikes_battle.cpp | 27 ++++++++++++++----- src/modes/three_strikes_battle.hpp | 4 +++ src/modes/world.hpp | 4 +++ 9 files changed, 111 insertions(+), 28 deletions(-) diff --git a/src/gui/race_results_gui.cpp b/src/gui/race_results_gui.cpp index 19b27e81c..939736299 100644 --- a/src/gui/race_results_gui.cpp +++ b/src/gui/race_results_gui.cpp @@ -40,10 +40,7 @@ RaceResultsGUI::RaceResultsGUI() network_manager->beginRaceResultBarrier(); Widget *bottom_of_list; - if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER) - bottom_of_list = displayLeaderResults(); - else - bottom_of_list = displayRaceResults(); + bottom_of_list = displayRaceResults(); // If it's a server, the user can only select 'ok', since the // server does all the game mode selection etc. @@ -89,6 +86,7 @@ RaceResultsGUI::RaceResultsGUI() } // RaceResultsGUI // ---------------------------------------------------------------------------- +#if 0 Widget *RaceResultsGUI::displayLeaderResults() { const unsigned int NUM_KARTS = race_manager->getNumKarts(); @@ -138,6 +136,7 @@ Widget *RaceResultsGUI::displayLeaderResults() delete []race_time; return w_prev; } // displayLeaderResults +#endif // ---------------------------------------------------------------------------- Widget *RaceResultsGUI::displayRaceResults() @@ -145,25 +144,25 @@ Widget *RaceResultsGUI::displayRaceResults() Widget *w_prev=widget_manager->addTextWgt( WTOK_RESULTS, 5, 7, _("Race results") ); widget_manager->hideWgtRect(WTOK_RESULTS); w_prev->setPosition(WGT_DIR_FROM_LEFT, 0.1f, NULL, WGT_DIR_FROM_TOP, 0.1f, NULL); - + const unsigned int MAX_STR_LEN = 60; const unsigned int NUM_KARTS = race_manager->getNumKarts(); int* order = new int [NUM_KARTS]; + RaceManager::getWorld()->raceResultOrder( order ); + unsigned int max_name_len = 1; for(unsigned int i=0; i < NUM_KARTS; i++) { Kart *k = RaceManager::getKart(i); // Display even for eliminated karts! - order[k->getPosition()-1] = i; const std::string& s = k->getName(); unsigned int l = (unsigned int)s.size(); if(l>max_name_len) max_name_len = l; } // for i // save bottom of result list for later - Widget *bottom_of_list=displayKartList(0, NUM_KARTS-1, w_prev, - order, /*displayTime*/ true, 0.1f); + Widget *bottom_of_list=displayKartList(w_prev, order, 0.1f); delete[] order; @@ -203,14 +202,18 @@ Widget *RaceResultsGUI::displayRaceResults() } // displayRaceResults //----------------------------------------------------------------------------- -Widget *RaceResultsGUI::displayKartList(unsigned int from, unsigned int to, - Widget *w_prev, int *order, - bool display_time, float horizontal) +Widget *RaceResultsGUI::displayKartList(Widget *w_prev, int *order, float horizontal) { + const bool display_time = RaceManager::getWorld()->getClockMode() == CHRONO; + const unsigned int NUM_KARTS = race_manager->getNumKarts(); + const int MAX_STR_LEN=60; - char *score = new char[(to-from+1) * MAX_STR_LEN]; - for(unsigned int i = from; i <= to; ++i) + char *score = new char[NUM_KARTS * MAX_STR_LEN]; + int kart_id = 0; // 'i' below is not reliable because some karts (e.g. leader) will be skipped + for(unsigned int i = 0; i < NUM_KARTS; ++i) { + if(order[i] == -1) continue; + const Kart *KART = RaceManager::getKart(order[i]); const std::string& KART_NAME = KART->getName(); char sTime[20];sTime[0]=0; @@ -232,19 +235,21 @@ Widget *RaceResultsGUI::displayKartList(unsigned int from, unsigned int to, KART->getPosition(), KART_NAME.c_str(), sTime); } - Widget *image=widget_manager->addImgButtonWgt(WTOK_FIRST_IMAGE + i, 7, 7, + Widget *image=widget_manager->addImgButtonWgt(WTOK_FIRST_IMAGE + kart_id, 7, 7, KART->getKartProperties()->getIconFile() ); - widget_manager->deactivateWgt(WTOK_FIRST_IMAGE+i); + widget_manager->deactivateWgt(WTOK_FIRST_IMAGE+kart_id); image->setPosition(WGT_DIR_FROM_LEFT, horizontal, NULL, WGT_DIR_UNDER_WIDGET, 0.0f, w_prev); - Widget *w=widget_manager->addTextWgt(WTOK_FIRST_RESULT + i, 5, 7, + Widget *w=widget_manager->addTextWgt(WTOK_FIRST_RESULT + kart_id, 5, 7, (char*)(score + MAX_STR_LEN * i) ); w->setPosition(WGT_DIR_RIGHT_WIDGET, 0.1f, image, WGT_DIR_UNDER_WIDGET, 0.0f, w_prev); w_prev=w; + + kart_id++; } - widget_manager->sameWidth(WTOK_FIRST_RESULT+from, WTOK_FIRST_RESULT+to); + widget_manager->sameWidth(WTOK_FIRST_RESULT, WTOK_FIRST_RESULT+kart_id-1); return w_prev; } // displayKartList diff --git a/src/gui/race_results_gui.hpp b/src/gui/race_results_gui.hpp index ff2402843..241658a01 100644 --- a/src/gui/race_results_gui.hpp +++ b/src/gui/race_results_gui.hpp @@ -49,11 +49,8 @@ private: /** The widget selected by the user, so that the right action can be done * once clients and server are synchronised. */ WidgetTokens m_selected_widget; - Widget *displayLeaderResults(); Widget *displayRaceResults(); - Widget *displayKartList(unsigned int from, unsigned int to, - Widget *w_prev, int *order, bool display_time, - float horizontal); + Widget *displayKartList(Widget *w_prev, int *order, float horizontal); public: RaceResultsGUI(); ~RaceResultsGUI(); diff --git a/src/modes/follow_the_leader.cpp b/src/modes/follow_the_leader.cpp index 89e76579e..c9063ff8b 100644 --- a/src/modes/follow_the_leader.cpp +++ b/src/modes/follow_the_leader.cpp @@ -106,6 +106,7 @@ void FollowTheLeaderRace::terminateRace() LinearWorld::terminateRace(); } + #if 0 #pragma mark - #pragma mark overridden from World @@ -134,3 +135,45 @@ KartIconDisplayInfo* FollowTheLeaderRace::getKartsDisplayInfo(const RaceGUI* cal m_kart_display_info[0].special_title = _("Leader"); return m_kart_display_info; } +//----------------------------------------------------------------------------- + +void FollowTheLeaderRace::raceResultOrder( int* order ) +{ + const unsigned int NUM_KARTS = race_manager->getNumKarts(); + + int *scores = new int[NUM_KARTS]; + double *race_time = new double[NUM_KARTS]; + + // Ignore kart 0, since it was the leader + order[0] = -1; + for( unsigned int kart_id = 1; kart_id < NUM_KARTS; ++kart_id ) + { + order[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 = 1; i < NUM_KARTS - 1; ++i ) + { + if( scores[order[i]] < scores[order[i+1]] || + (scores[order[i]] == scores[order[i+1]] + && race_time[order[i]] > race_time[order[i+1]]) ) + { + int tmp = order[i]; + order[i] = order[i+1]; + order[i+1] = tmp; + sorted = false; + } + } + } while(!sorted); + for(unsigned int i=1; isetPosition(i); + + delete []scores; + delete []race_time; +} diff --git a/src/modes/follow_the_leader.hpp b/src/modes/follow_the_leader.hpp index 0a7a647c1..bd1eb4c03 100644 --- a/src/modes/follow_the_leader.hpp +++ b/src/modes/follow_the_leader.hpp @@ -40,6 +40,10 @@ public: virtual KartIconDisplayInfo* getKartsDisplayInfo(const RaceGUI* caller); virtual bool raceHasLaps(){ return false; } + + /** Called by the race result GUI at the end of the race to know the final order + (fill in the 'order' array) */ + virtual void raceResultOrder( int* order ); }; diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 6dea86b82..6829e5c29 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -425,6 +425,14 @@ void LinearWorld::terminateRace() } // if !hasFinishedRace } // for i } +void LinearWorld::raceResultOrder( int* order ) +{ + const unsigned int NUM_KARTS = race_manager->getNumKarts(); + for(unsigned int i=0; i < NUM_KARTS; i++) + { + order[RaceManager::getKart(i)->getPosition()-1] = i; // even for eliminated karts + } +} //----------------------------------------------------------------------------- float LinearWorld::estimateFinishTimeForKart (Kart* kart, KartInfo& kart_info) { diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp index 10b17b4ee..28204ef66 100644 --- a/src/modes/linear_world.hpp +++ b/src/modes/linear_world.hpp @@ -85,8 +85,11 @@ public: virtual void terminateRace(); virtual void restartRace(); - virtual bool raceHasLaps(){ return true; } + + /** Called by the race result GUI at the end of the race to know the final order + (fill in the 'order' array) */ + virtual void raceResultOrder( int* order ); }; #endif diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index 5afbd7008..c9c9d4f1d 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -21,6 +21,7 @@ #include +//----------------------------------------------------------------------------- ThreeStrikesBattle::ThreeStrikesBattle() : World() { TimedRace::setClockMode(CHRONO); @@ -46,13 +47,12 @@ ThreeStrikesBattle::ThreeStrikesBattle() : World() m_kart[n]->setPosition(-1); }// next kart } - +//----------------------------------------------------------------------------- ThreeStrikesBattle::~ThreeStrikesBattle() { delete[] m_kart_display_info; } - - +//----------------------------------------------------------------------------- void ThreeStrikesBattle::onGo() { // Reset the brakes now that the prestart @@ -63,11 +63,12 @@ void ThreeStrikesBattle::onGo() m_kart[i]->resetBrakes(); } } +//----------------------------------------------------------------------------- void ThreeStrikesBattle::terminateRace() { World::terminateRace(); } - +//----------------------------------------------------------------------------- void ThreeStrikesBattle::kartHit(const int kart_id) { assert(kart_id >= 0); @@ -84,10 +85,12 @@ void ThreeStrikesBattle::kartHit(const int kart_id) if(getCurrentNumKarts()==2) sound_manager->switchToFastMusic(); } +//----------------------------------------------------------------------------- std::string ThreeStrikesBattle::getInternalCode() const { return "BATTLE_3_STRIKES"; } +//----------------------------------------------------------------------------- void ThreeStrikesBattle::update(float delta) { World::update(delta); @@ -104,6 +107,7 @@ void ThreeStrikesBattle::update(float delta) return; } } +//----------------------------------------------------------------------------- void ThreeStrikesBattle::restartRace() { World::restartRace(); @@ -116,7 +120,7 @@ void ThreeStrikesBattle::restartRace() }// next kart } //void ThreeStrikesBattle::getDefaultCollectibles(int& collectible_type, int& amount) - +//----------------------------------------------------------------------------- KartIconDisplayInfo* ThreeStrikesBattle::getKartsDisplayInfo(const RaceGUI* caller) { const unsigned int kart_amount = race_manager->getNumKarts(); @@ -159,7 +163,7 @@ KartIconDisplayInfo* ThreeStrikesBattle::getKartsDisplayInfo(const RaceGUI* call return m_kart_display_info; } - +//----------------------------------------------------------------------------- void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body) { // find closest point to drop kart on @@ -202,4 +206,15 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body) body->setCenterOfMassTransform(pos); +} +//----------------------------------------------------------------------------- +void ThreeStrikesBattle::raceResultOrder( int* order ) +{ + // FIXME - implement properly + const unsigned int NUM_KARTS = race_manager->getNumKarts(); + + for( unsigned int kart_id = 0; kart_id < NUM_KARTS; ++kart_id ) + { + order[kart_id] = kart_id; + } } \ No newline at end of file diff --git a/src/modes/three_strikes_battle.hpp b/src/modes/three_strikes_battle.hpp index e3fd220cf..1df3d4a56 100644 --- a/src/modes/three_strikes_battle.hpp +++ b/src/modes/three_strikes_battle.hpp @@ -59,6 +59,10 @@ public: virtual std::string getInternalCode() const; virtual void kartHit(const int kart_id); + + /** Called by the race result GUI at the end of the race to know the final order + (fill in the 'order' array) */ + virtual void raceResultOrder( int* order ); }; diff --git a/src/modes/world.hpp b/src/modes/world.hpp index 5319079fa..ab72bc5ee 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -192,6 +192,10 @@ public: /** Called when a kart was hit by a projectile */ virtual void kartHit(const int kart_id) {}; + + /** Called by the race result GUI at the end of the race to know the final order + (fill in the 'order' array) */ + virtual void raceResultOrder( int* order ) = 0; }; #endif