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