diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp index f23c26987..31d4ba53e 100644 --- a/src/race/grand_prix_data.cpp +++ b/src/race/grand_prix_data.cpp @@ -81,9 +81,14 @@ void GrandPrixData::createRandomGP(const unsigned int number_of_tracks, changeTrackNumber(number_of_tracks, track_group); changeReverse(use_reverse); -} +} // createRandomGP // ---------------------------------------------------------------------------- +/** Either adds or removes tracks to get the requested numder of tracks in + * a random GP. + * \param number_of_tracks How many tracks should be in the random list. + * \param track_group From which group to select the tracks. + */ void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks, const std::string& track_group) { @@ -95,7 +100,13 @@ void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks, for(unsigned int i=0; igetNumberOfTracks(); i++) { const Track *track = track_manager->getTrack(i); - if(!track->isArena() && !track->isSoccer() && !track->isInternal()) + // Ignore no-racing tracks: + if(track->isArena() || track->isSoccer() || track->isInternal()) + continue; + + // Only add tracks that are not already picked. + if(std::find(m_tracks.begin(), m_tracks.end(), track->getIdent())== + m_tracks.end()) track_indices.push_back(i); } } @@ -103,24 +114,23 @@ void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks, { track_indices = track_manager->getTracksInGroup(track_group); } - assert(number_of_tracks <= track_indices.size()); + assert(number_of_tracks <= track_indices.size() + m_tracks.size()); // add or remove the right number of tracks if (m_tracks.size() < number_of_tracks) { while (m_tracks.size() < number_of_tracks) { - int index = track_indices[rand() % track_indices.size()]; + int index = rand() % track_indices.size(); + int track_index = track_indices[index]; - const Track *track = track_manager->getTrack(index); + const Track *track = track_manager->getTrack(track_index); std::string id = track->getIdent(); - // Avoid duplicate tracks - if (std::find(m_tracks.begin(), m_tracks.end(), id) != m_tracks.end()) - continue; m_tracks.push_back(id); m_laps.push_back(track->getDefaultNumberOfLaps()); m_reversed.push_back(false); // This will be changed later in the code + track_indices.erase(track_indices.begin()+index); } } else if (m_tracks.size() > number_of_tracks) @@ -135,7 +145,7 @@ void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks, assert(m_tracks.size() == m_laps.size() ); assert(m_laps.size() == m_reversed.size()); -} +} // changeTrackNumber // ---------------------------------------------------------------------------- /** Updates the GP data with newly decided reverse requirements. diff --git a/src/states_screens/gp_info_screen.cpp b/src/states_screens/gp_info_screen.cpp index fe04d1268..dd0e979ab 100644 --- a/src/states_screens/gp_info_screen.cpp +++ b/src/states_screens/gp_info_screen.cpp @@ -83,7 +83,7 @@ void BaseGPInfoScreen::loadedFromFile() m_num_tracks_spinner = getWidget("track-spinner"); // Only init the number of tracks here, this way the previously selected // number of tracks will be the default. - m_num_tracks_spinner->setValue(4); + m_num_tracks_spinner->setValue(1); int number_of_tracks = m_num_tracks_spinner->getValue(); } // loadedFromFile @@ -163,9 +163,10 @@ void BaseGPInfoScreen::init() // If there are more tracks selected atm as in the group (which can // happen if the group has been changed since last time this screen // was shown), adjust it: - int max_num_tracks = - m_group_name=="all" ? track_manager->getNumberOfTracks() - : track_manager->getTracksInGroup(m_group_name).size(); + int max_num_tracks = m_group_name=="all" + ? track_manager->getNumberOfRaceTracks() + : track_manager->getTracksInGroup(m_group_name).size(); + m_num_tracks_spinner->setMax(max_num_tracks); if(m_num_tracks_spinner->getValue() > max_num_tracks) { m_num_tracks_spinner->setValue(max_num_tracks); @@ -287,14 +288,7 @@ void BaseGPInfoScreen::eventCallback(GUIEngine::Widget *, const std::string &nam if (button == "start" || button=="continue") { - // Save GP identifier, since dismiss will delete this object. - GrandPrixData gp_data = m_gp; - // Also create a copy of the string: it is a reference to data - // in a widget in the dialog - so if we call dismiss, this reference - // becomes invalid! - std::string save_source = name; - // FIXME ModalDialog::dismiss(); - race_manager->startGP(gp_data, false, (save_source == "continue")); + race_manager->startGP(m_gp, false, (name == "continue")); } } // name=="buttons" else if (name=="group-spinner") @@ -305,20 +299,20 @@ void BaseGPInfoScreen::eventCallback(GUIEngine::Widget *, const std::string &nam // the current track. The current value in the Number-of-tracks-spinner // has to be updated, since otherwise the displayed (and used) value // can be bigger than the maximum. (Might be a TODO to fix this) - unsigned int max = (m_group_name == "all") ? - track_manager->getNumberOfTracks() : - track_manager->getTracksInGroup(m_group_name).size(); - m_num_tracks_spinner->setMax(max); - int number_of_tracks = std::min((int)max, m_num_tracks_spinner->getValue()); - if (m_num_tracks_spinner->getValue() > (signed)max) - m_num_tracks_spinner->setValue(max); + int max_num_tracks = m_group_name=="all" + ? track_manager->getNumberOfRaceTracks() + : track_manager->getTracksInGroup(m_group_name).size(); + m_num_tracks_spinner->setMax(max_num_tracks); + int number_of_tracks = std::min(max_num_tracks, + m_num_tracks_spinner->getValue()); + if (m_num_tracks_spinner->getValue() > max_num_tracks) + m_num_tracks_spinner->setValue(max_num_tracks); // Create a new (i.e. with new tracks) random gp, since the old // tracks might not all belong to the newly selected group. m_gp.createRandomGP(m_num_tracks_spinner->getValue(), m_group_name, getReverse(), /*new_tracks*/true); addTracks(); - } else if (name=="track-spinner") { diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 424598de4..894280d36 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -464,8 +464,16 @@ public: /** Returns true if this track has an arena mode. */ bool isArena() const { return m_is_arena; } // ------------------------------------------------------------------------ + /** Returns true if this track is a racing track. This means it is not an + * internal track (like cut scenes), arena, or soccer field. */ + bool isRaceTrack() const + { + return !m_internal && !m_is_arena && !m_is_soccer; + } // isRaceTrack + // ------------------------------------------------------------------------ /** Returns true if this track has easter eggs. */ bool hasEasterEggs() const { return m_has_easter_eggs; } + // ------------------------------------------------------------------------ bool isSoccer () const { return m_is_soccer; } // ------------------------------------------------------------------------ void loadTrackModel (World* parent, diff --git a/src/tracks/track_manager.cpp b/src/tracks/track_manager.cpp index b2092b13e..94c9a5637 100644 --- a/src/tracks/track_manager.cpp +++ b/src/tracks/track_manager.cpp @@ -57,6 +57,19 @@ void TrackManager::addTrackSearchDir(const std::string &dir) m_track_search_path.push_back(dir); } // addTrackDir +//----------------------------------------------------------------------------- +/** Returns the number of racing tracks. Those are tracks that are not + * internal (like cut scenes), arenas, or soccer fields. + */ +int TrackManager::getNumberOfRaceTracks() const +{ + int n=0; + for(unsigned int i=0; iisRaceTrack()) + n++; + return n; +} // getNumberOfRaceTracks + //----------------------------------------------------------------------------- /** Get TrackData by the track identifier. * \param ident Identifier = basename of the directory the track is in. diff --git a/src/tracks/track_manager.hpp b/src/tracks/track_manager.hpp index 3faf53921..7d2b86ed1 100644 --- a/src/tracks/track_manager.hpp +++ b/src/tracks/track_manager.hpp @@ -53,9 +53,6 @@ private: /** List of all soccer arena groups. */ Group2Indices m_soccer_arena_groups; - /** List of all groups (for both normal tracks and arenas) */ - //std::vector m_all_group_names; - /** List of the names of all groups containing tracks */ std::vector m_track_group_names; @@ -85,6 +82,7 @@ public: void removeTrack(const std::string &ident); bool loadTrack(const std::string& dirname); void removeAllCachedData(); + int getNumberOfRaceTracks() const; Track* getTrack(const std::string& ident) const; // ------------------------------------------------------------------------ /** Sets a list of track as being unavailable (e.g. in network mode the