From a53ca214c506dec660fabcb2523f24f9b750b98b Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 17 Apr 2008 00:20:06 +0000 Subject: [PATCH] 1) Follow the leader mode now removes the first kart if the leader is not the first. 2) AI karts brake if they are ahead of the leader 3) The leader has now the text 'leader' displayed next to the item. 4) The ranks in the leader results table are now correct (starting with 1 instead of 2) 5) Fixed two potential bugs, which might result in triggering an assert. 6) Replaced assert (in case that it should get triggered again) with useful messages to stderr. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1688 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/gui/leader_result.cpp | 2 +- src/gui/race_gui.cpp | 14 ++++++---- src/kart.cpp | 3 ++- src/kart.hpp | 11 ++++---- src/robots/default_robot.cpp | 10 +++++++ src/world.cpp | 51 ++++++++++++++++++++++++------------ 6 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/gui/leader_result.cpp b/src/gui/leader_result.cpp index 4311af681..e5a5ae57c 100644 --- a/src/gui/leader_result.cpp +++ b/src/gui/leader_result.cpp @@ -121,7 +121,7 @@ LeaderResult::LeaderResult() char sTime[20]; TimeToString(race_time[i], sTime); sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %d %s", - i + 1, race_manager->getKartName(position[i]).c_str(), scores[i], sTime ); + i , race_manager->getKartName(position[i]).c_str(), scores[i], sTime ); widget_manager->addWgt(WTOK_FIRSTKART + i, 40, 5); widget_manager->showWgtRect(WTOK_FIRSTKART + i); diff --git a/src/gui/race_gui.cpp b/src/gui/race_gui.cpp index f90edd7e2..541819eb9 100644 --- a/src/gui/race_gui.cpp +++ b/src/gui/race_gui.cpp @@ -381,8 +381,8 @@ void RaceGUI::drawPlayerIcons () glDisable(GL_CULL_FACE); if(laps_of_leader>0 && // Display position during first lap - (world->getTime() - kart->getTimeAtLap()<5.0f || - lap!=laps_of_leader)) + (world->getTime() - kart->getTimeAtLap()<5.0f || lap!=laps_of_leader) && + race_manager->raceHasLaps()) { // Display for 5 seconds char str[256]; if(position==1) @@ -398,9 +398,13 @@ void RaceGUI::drawPlayerIcons () str[0]='+'; str[1]=0; TimeToString(timeBehind, str+1); } - if(race_manager->raceHasLaps()) - font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5, - red, green, blue); + font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5, + red, green, blue); + } + if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER && i==0) + { + font_race->PrintShadow(_("Leader"), 30, ICON_PLAYER_WIDHT+x, y+5, + 255, 0, 0); } glEnable(GL_CULL_FACE); diff --git a/src/kart.cpp b/src/kart.cpp index b6c1481a3..99aaee7f9 100644 --- a/src/kart.cpp +++ b/src/kart.cpp @@ -58,7 +58,8 @@ Kart::Kart (const std::string& kart_name, int position_ , #endif { m_kart_properties = kart_properties_manager->getKart(kart_name); - m_grid_position = position_ ; + m_grid_position = position_; + m_initial_position = position_; m_num_herrings_gobbled = 0; m_eliminated = false; m_finished_race = false; diff --git a/src/kart.hpp b/src/kart.hpp index 19f28bf2e..5cb6361b2 100644 --- a/src/kart.hpp +++ b/src/kart.hpp @@ -51,14 +51,14 @@ class Smoke; class Kart : public TerrainInfo, public Moveable { protected: - bool m_on_road; //true if the kart is on top of the - //road path drawn by the drivelines - + bool m_on_road; // true if the kart is on top of the + // road path drawn by the drivelines Attachment m_attachment; Collectable m_collectable; int m_grid_position; - int m_race_position; + int m_race_position; // current race position (1-numKarts) + int m_initial_position; // initial position of kart KartControl m_controls; // The position of the karts controls int m_track_sector; // index in driveline, special values // e.g. UNKNOWN_SECTOR can be negative! @@ -142,7 +142,8 @@ public: int getNumCollectables () const { return m_collectable.getNum();} int getNumHerring () const { return m_num_herrings_gobbled;} int getLap () const { return m_race_lap; } - int getPosition () const { return m_race_position ; } + int getPosition () const { return m_race_position; } + int getInitialPosition () const { return m_initial_position; } void setFinishingState(float time); float getFinishTime () const { return m_finish_time; } bool raceIsFinished () const { return m_finished_race; } diff --git a/src/robots/default_robot.cpp b/src/robots/default_robot.cpp index 691a73c89..701be1c26 100755 --- a/src/robots/default_robot.cpp +++ b/src/robots/default_robot.cpp @@ -126,6 +126,16 @@ void DefaultRobot::handle_wheelie( const int STEPS ) //----------------------------------------------------------------------------- void DefaultRobot::handle_braking() { + // In follow the leader mode, the kart should brake if they are ahead of + // the leader (and not the leader, i.e. don't have initial position 1) + if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER && + getPosition()getKart(0)->getPosition() && + getInitialPosition()>1 ) + { + printf("kart %s: braking",this->getName().c_str()); + m_controls.brake = true; + return; + } const float MIN_SPEED = world->m_track->getWidth()[m_track_sector]; //We may brake if we are about to get out of the road, but only if the diff --git a/src/world.cpp b/src/world.cpp index 605d7ecbb..d4dca05f0 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -94,26 +94,27 @@ World::World() loadTrack() ; int playerIndex = 0; - for(unsigned int position=0; positiongetNumKarts(); position++) + for(unsigned int i=0; igetNumKarts(); i++) { + int position = i+1; // position start with 1 sgCoord init_pos; - m_track->getStartCoords(position, &init_pos); + m_track->getStartCoords(i, &init_pos); Kart* newkart; - const std::string& kart_name=race_manager->getKartName(position); + const std::string& kart_name=race_manager->getKartName(i); if(user_config->m_profile) { // In profile mode, load only the old kart newkart = new DefaultRobot(kart_name, position, init_pos); // Create a camera for the last kart (since this way more of the // karts can be seen. - if(position==race_manager->getNumKarts()-1) + if(i==race_manager->getNumKarts()-1) { scene->createCamera(race_manager->getNumPlayers(), playerIndex); } } else { - if (race_manager->isPlayer(position)) + if (race_manager->isPlayer(i)) { Camera *cam = scene->createCamera(race_manager->getNumPlayers(), playerIndex); // the given position belongs to a player @@ -130,7 +131,7 @@ World::World() } // if !user_config->m_profile if(user_config->m_replay_history) { - history->LoadKartData(newkart, position); + history->LoadKartData(newkart, i); } newkart -> getModelTransform() -> clrTraversalMaskBits(SSGTRAV_ISECT|SSGTRAV_HOT); @@ -306,7 +307,7 @@ void World::update(float dt) for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i) { - if(!m_kart[i]) continue; // ignore eliminated kart + if(m_kart[i]->isEliminated()) continue; // ignore eliminated kart if(!m_kart[i]->raceIsFinished()) updateRacePosition((int)i); if(m_kart[i]->isPlayerKart()) m_kart[i]->addMessages(); // add 'wrong direction' } @@ -465,14 +466,30 @@ void World::updateRaceStatus(float dt) m_leader_intervals.erase(m_leader_intervals.begin()); m_clock=m_leader_intervals[0]; int kart_number; + // If the leader kart is not the first kart, remove the first + // kart, otherwise remove the last kart. + int position_to_remove = m_kart[0]->getPosition()==1 + ? getCurrentNumKarts() : 1; for (kart_number=0; kart_number<(int)m_kart.size(); kart_number++) { if(m_kart[kart_number]->isEliminated()) continue; - if(m_kart[kart_number]->getPosition()==getCurrentNumKarts()) + if(m_kart[kart_number]->getPosition()==position_to_remove) break; } - assert(kart_number!=m_kart.size()); - removeKart(kart_number); + if(kart_number==m_kart.size()) + { + fprintf(stderr,"Problem with removing leader: position %d not found\n", + position_to_remove); + for(int i=0; i<(int)m_kart.size(); i++) + { + fprintf(stderr,"kart %d: eliminated %d position %d\n", + i,m_kart[i]->isEliminated(), m_kart[i]->getPosition()); + } // for i + } // kart_number==m_kart.size() + else + { + removeKart(kart_number); + } // The follow the leader race is over if there isonly one kart left, // or if all players have gone if(getCurrentNumKarts()==2 ||getCurrentNumPlayers()==0) @@ -614,12 +631,12 @@ void World::removeKart(int kart_number) camera->setMode(Camera::CM_LEADER_MODE); m_eliminated_players++; } - - // The kart can't be eliminated, since otherwise a race can't be restarted. - // So it's only marked to be eliminated (and ignored in all loops). Important: - // world->getCurrentNumKarts() returns the number of still racing karts. This - // value can not be used for loops over all karts, use race_manager->getNumKarts() - // instead! + projectile_manager->newExplosion(kart->getCoord()); + // The kart can't be really removed from the m_kart array, since otherwise + // a race can't be restarted. So it's only marked to be eliminated (and + // ignored in all loops). Important:world->getCurrentNumKarts() returns + // the number of karts still racing. This value can not be used for loops + // over all karts, use race_manager->getNumKarts() instead! race_manager->addKartResult(kart_number, kart->getPosition(), m_clock); race_manager->eliminate(kart_number); kart->eliminate(); @@ -637,7 +654,7 @@ void World::updateRacePosition ( int k ) for ( Karts::size_type j = 0 ; j < m_kart.size() ; ++j ) { if(int(j) == k) continue; - if(!m_kart[j]) continue; // eliminated karts + if(m_kart[j]->isEliminated()) continue; // eliminated karts // Count karts ahead of the current kart, i.e. kart that are already // finished (the current kart k has not yet finished!!), have done more