From 7a25743c5d371d2b6ec7da7476e1acb53cd59b54 Mon Sep 17 00:00:00 2001 From: CodingJellyfish Date: Thu, 17 Oct 2024 02:20:02 +0800 Subject: [PATCH] Implement kart grouping/searching/favorite (#5172) * Implement kart grouping/searching/favprite * Add search bar for arenas * Use methods instead of friend class --- data/gui/screens/arenas.stkgui | 15 +- data/gui/screens/karts.stkgui | 17 ++- data/gui/screens/online/network_karts.stkgui | 15 +- data/gui/screens/race_setup.stkgui | 4 +- data/gui/screens/tracks_and_gp.stkgui | 10 +- ...e_track_status.cpp => favorite_status.cpp} | 54 ++++---- ...e_track_status.hpp => favorite_status.hpp} | 40 +++--- src/config/player_profile.cpp | 14 +- src/config/player_profile.hpp | 42 ++++-- src/guiengine/widgets/player_kart_widget.cpp | 6 +- src/karts/kart_properties.cpp | 14 +- src/karts/kart_properties_manager.cpp | 102 +++++++++++++- src/karts/kart_properties_manager.hpp | 18 ++- src/states_screens/arenas_screen.cpp | 124 +++++++---------- src/states_screens/arenas_screen.hpp | 18 ++- src/states_screens/kart_selection.cpp | 129 ++++++++++++++---- src/states_screens/kart_selection.hpp | 14 +- src/states_screens/tracks_and_gp_screen.cpp | 4 +- src/tracks/track.cpp | 4 +- src/tracks/track_manager.cpp | 61 ++++----- src/tracks/track_manager.hpp | 8 +- 21 files changed, 482 insertions(+), 231 deletions(-) rename src/config/{favorite_track_status.cpp => favorite_status.cpp} (68%) rename src/config/{favorite_track_status.hpp => favorite_status.hpp} (56%) diff --git a/data/gui/screens/arenas.stkgui b/data/gui/screens/arenas.stkgui index 6c71e81cf7f..ef416f501ea 100644 --- a/data/gui/screens/arenas.stkgui +++ b/data/gui/screens/arenas.stkgui @@ -4,14 +4,15 @@
- -
- - - - - + + +
+ + + +
diff --git a/data/gui/screens/karts.stkgui b/data/gui/screens/karts.stkgui index afdabf82723..f6998767625 100644 --- a/data/gui/screens/karts.stkgui +++ b/data/gui/screens/karts.stkgui @@ -7,14 +7,27 @@ align="center" text_align="center" /> - + -
+
+ +
+
+
diff --git a/data/gui/screens/online/network_karts.stkgui b/data/gui/screens/online/network_karts.stkgui index 537e2e00113..ade06ac4f82 100644 --- a/data/gui/screens/online/network_karts.stkgui +++ b/data/gui/screens/online/network_karts.stkgui @@ -9,9 +9,22 @@ -
+
+ +
+
+
diff --git a/data/gui/screens/race_setup.stkgui b/data/gui/screens/race_setup.stkgui index 1a82c160bf9..aa3a0096fa2 100644 --- a/data/gui/screens/race_setup.stkgui +++ b/data/gui/screens/race_setup.stkgui @@ -4,7 +4,7 @@
- + @@ -21,7 +21,7 @@ - + diff --git a/data/gui/screens/tracks_and_gp.stkgui b/data/gui/screens/tracks_and_gp.stkgui index 17d5ce75a54..2a870c36caf 100644 --- a/data/gui/screens/tracks_and_gp.stkgui +++ b/data/gui/screens/tracks_and_gp.stkgui @@ -25,10 +25,12 @@
- - - - + +
+ + + +
diff --git a/src/config/favorite_track_status.cpp b/src/config/favorite_status.cpp similarity index 68% rename from src/config/favorite_track_status.cpp rename to src/config/favorite_status.cpp index f5dedb43310..85240cb2027 100644 --- a/src/config/favorite_track_status.cpp +++ b/src/config/favorite_status.cpp @@ -16,31 +16,33 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#include "config/favorite_track_status.hpp" +#include "config/favorite_status.hpp" #include "config/player_manager.hpp" #include "io/utf_writer.hpp" #include "io/xml_node.hpp" #include "utils/string_utils.hpp" -const std::string FavoriteTrackStatus::DEFAULT_FAVORITE_GROUP_NAME = "Favorites"; +const std::string FavoriteStatus::DEFAULT_FAVORITE_GROUP_NAME = "Favorites"; //------------------------------------------------------------------------------ -FavoriteTrackStatus::FavoriteTrackStatus(const XMLNode* node) +FavoriteStatus::FavoriteStatus(const XMLNode* node, std::string parse_type) { + m_parse_type = parse_type; + std::vector xml_favorite_tracks; std::vector xml_favorite_groups; if (node) { - node->getNodes("track", xml_favorite_tracks); + node->getNodes(parse_type.c_str(), xml_favorite_tracks); node->getNodes("group", xml_favorite_groups); } for (unsigned int i = 0; i < xml_favorite_tracks.size(); i++) { std::string temp_string; xml_favorite_tracks[i]->get("ident", &temp_string); - m_favorite_tracks[DEFAULT_FAVORITE_GROUP_NAME].insert(temp_string); + m_favorite[DEFAULT_FAVORITE_GROUP_NAME].insert(temp_string); } for (unsigned int i = 0; i < xml_favorite_groups.size(); i++) { @@ -48,63 +50,62 @@ FavoriteTrackStatus::FavoriteTrackStatus(const XMLNode* node) std::vector temp_group; xml_favorite_groups[i]->get("name", &temp_group_string); - xml_favorite_groups[i]->getNodes("track", temp_group); + xml_favorite_groups[i]->getNodes(parse_type.c_str(), temp_group); for (unsigned int j = 0; j < temp_group.size(); j++) { std::string temp_string; temp_group[j]->get("ident", &temp_string); - m_favorite_tracks[temp_group_string].insert(temp_string); + m_favorite[temp_group_string].insert(temp_string); } } -} // FavoriteTrackStatus +} // FavoriteStatus //------------------------------------------------------------------------------ -FavoriteTrackStatus::~FavoriteTrackStatus() +FavoriteStatus::~FavoriteStatus() { -} // ~FavoriteTrackStatus +} // ~FavoriteStatus //------------------------------------------------------------------------------ /** Adds a new favorite track to this player profile and to the group * of favorite tracks of the Track Manager. * To be used only if this player profile is the current player. */ -bool FavoriteTrackStatus::isFavoriteTrack(std::string ident) +bool FavoriteStatus::isFavorite(std::string ident) { - return m_favorite_tracks[DEFAULT_FAVORITE_GROUP_NAME].find(ident) - != m_favorite_tracks[DEFAULT_FAVORITE_GROUP_NAME].end(); -} // addFavoriteTrack + return m_favorite[DEFAULT_FAVORITE_GROUP_NAME].find(ident) + != m_favorite[DEFAULT_FAVORITE_GROUP_NAME].end(); +} // addFavorite //------------------------------------------------------------------------------ /** Adds a new favorite track to this player profile and to the group * of favorite tracks of the Track Manager. */ -void FavoriteTrackStatus::addFavoriteTrack(std::string ident, std::string group) +void FavoriteStatus::addFavorite(std::string ident, std::string group) { - m_favorite_tracks[group].insert(ident); -} // addFavoriteTrack + m_favorite[group].insert(ident); +} // addFavorite //------------------------------------------------------------------------------ /** Removes a favorite track from this player profile and from the group * of favorite tracks of the Track Manager. */ -void FavoriteTrackStatus::removeFavoriteTrack(std::string ident, std::string group) +void FavoriteStatus::removeFavorite(std::string ident, std::string group) { - if (m_favorite_tracks[group].find(ident) != m_favorite_tracks[group].end()) + if (m_favorite[group].find(ident) != m_favorite[group].end()) { - m_favorite_tracks[group].erase(ident); + m_favorite[group].erase(ident); } -} // removeFavoriteTrack +} // removeFavorite //------------------------------------------------------------------------------ /** Writes the data for this player to the specified UTFWriter. * \param out The utf writer to write the data to. */ -void FavoriteTrackStatus::save(UTFWriter &out) +void FavoriteStatus::save(UTFWriter &out) { - out << " \n"; - for (auto it_group = m_favorite_tracks.begin(); it_group != m_favorite_tracks.end(); it_group++) + for (auto it_group = m_favorite.begin(); it_group != m_favorite.end(); it_group++) { std::string group_name = it_group->first; @@ -112,7 +113,7 @@ void FavoriteTrackStatus::save(UTFWriter &out) { for (auto it_track = it_group->second.begin(); it_track != it_group->second.end(); it_track++) { - out << " \n"; + out << " <" << m_parse_type.c_str() << " ident=\"" << *it_track << "\"/>\n"; } } else @@ -120,10 +121,9 @@ void FavoriteTrackStatus::save(UTFWriter &out) out << " \n"; for (auto it_track = it_group->second.begin(); it_track != it_group->second.end(); it_track++) { - out << " \n"; + out << " <" << m_parse_type.c_str() << " ident=\"" << *it_track << "\"/>\n"; } out << " \n"; } } - out << " \n"; } // save diff --git a/src/config/favorite_track_status.hpp b/src/config/favorite_status.hpp similarity index 56% rename from src/config/favorite_track_status.hpp rename to src/config/favorite_status.hpp index 6defd245dcc..522ae3dd550 100644 --- a/src/config/favorite_track_status.hpp +++ b/src/config/favorite_status.hpp @@ -16,8 +16,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_FAVORITE_TRACK_STATUS_HPP -#define HEADER_FAVORITE_TRACK_STATUS_HPP +#ifndef HEADER_FAVORITE_STATUS_HPP +#define HEADER_FAVORITE_STATUS_HPP #include "utils/leak_check.hpp" @@ -29,45 +29,45 @@ using namespace irr; +class KartPropertiesManager; class TrackManager; class UTFWriter; class XMLNode; -/** Class for managing player profiles (name, usage frequency, - * etc.). All PlayerProfiles are managed by the PlayerManager. - * A PlayerProfile keeps track of the story mode progress using an instance - * of StoryModeStatus, and achievements with AchievementsStatus. All data - * is saved in the players.xml file. - * This class also defines the interface for handling online data. All of - * the online handling is done in the derived class OnlinePlayerProfile, - * where the interface is fully implemented. +/** Class for storing the current favorites/custom groups of karts and tracks. + * Put it into KartPropertiesManager or TrackManager by setFavoriteStatus() + * to add them into the original groups. * \ingroup config */ -class FavoriteTrackStatus +class FavoriteStatus { private: LEAK_CHECK() + std::string m_parse_type; + /** unordered_map > .*/ - std::unordered_map > m_favorite_tracks; + std::unordered_map > m_favorite; public: - friend class TrackManager; - static const std::string DEFAULT_FAVORITE_GROUP_NAME; - FavoriteTrackStatus(const XMLNode *node); + /** Parse all <(parse_type)/> in in xml node */ + FavoriteStatus(const XMLNode *node, std::string parse_type); - virtual ~FavoriteTrackStatus(); + virtual ~FavoriteStatus(); void save(UTFWriter &out); - bool isFavoriteTrack(std::string ident); + bool isFavorite(std::string ident); + + void addFavorite(std::string ident, std::string group = DEFAULT_FAVORITE_GROUP_NAME); - void addFavoriteTrack(std::string ident, std::string group = DEFAULT_FAVORITE_GROUP_NAME); + void removeFavorite(std::string ident, std::string group = DEFAULT_FAVORITE_GROUP_NAME); - void removeFavoriteTrack(std::string ident, std::string group = DEFAULT_FAVORITE_GROUP_NAME); -}; // class PlayerProfile + const std::unordered_map >& getAllFavorites() const + { return m_favorite; } +}; // class FavoriteStatus #endif diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp index 52c4016f965..e2d1aa9f739 100644 --- a/src/config/player_profile.cpp +++ b/src/config/player_profile.cpp @@ -80,6 +80,7 @@ PlayerProfile::PlayerProfile(const XMLNode* node) m_story_mode_status = NULL; m_achievements_status = NULL; m_favorite_track_status = NULL; + m_favorite_kart_status = NULL; m_default_kart_color = 0.0f; m_icon_filename = ""; @@ -132,7 +133,10 @@ void PlayerProfile::loadRemainingData(const XMLNode *node) // Some favorites may correspond to uninstalled addons, so we do not sanitize the strings assert(m_favorite_track_status == NULL); const XMLNode *xml_favorites = node->getNode("favorites"); - m_favorite_track_status = new FavoriteTrackStatus(xml_favorites); + m_favorite_track_status = new FavoriteStatus(xml_favorites, "track"); + + assert(m_favorite_kart_status == NULL); + m_favorite_kart_status = new FavoriteStatus(xml_favorites, "kart"); // Fix up any potentially missing icons. addIcon(); @@ -147,7 +151,8 @@ void PlayerProfile::initRemainingData() m_story_mode_status = unlock_manager->createStoryModeStatus(); m_achievements_status = AchievementsManager::get()->createAchievementsStatus(); - m_favorite_track_status = new FavoriteTrackStatus(NULL); + m_favorite_track_status = new FavoriteStatus(NULL, "track"); + m_favorite_kart_status = new FavoriteStatus(NULL, "kart"); addIcon(); } // initRemainingData @@ -241,8 +246,13 @@ void PlayerProfile::save(UTFWriter &out) if (m_achievements_status) m_achievements_status->save(out); + + out << " \n"; if (m_favorite_track_status) m_favorite_track_status->save(out); + if (m_favorite_kart_status) + m_favorite_kart_status->save(out); + out << " \n"; } out << " \n"; } // save diff --git a/src/config/player_profile.hpp b/src/config/player_profile.hpp index d0ecf5c9811..9746518aeb0 100644 --- a/src/config/player_profile.hpp +++ b/src/config/player_profile.hpp @@ -20,7 +20,7 @@ #define HEADER_PLAYER_PROFILE_HPP #include "challenges/story_mode_status.hpp" -#include "config/favorite_track_status.hpp" +#include "config/favorite_status.hpp" #include "network/remote_kart_info.hpp" #include "utils/leak_check.hpp" #include "utils/no_copy.hpp" @@ -116,7 +116,10 @@ class PlayerProfile : public NoCopy AchievementsStatus *m_achievements_status; /** The favorite tracks selected by this player. */ - FavoriteTrackStatus *m_favorite_track_status; + FavoriteStatus *m_favorite_track_status; + + /** The favorite karts selected by this player. */ + FavoriteStatus *m_favorite_kart_status; public: @@ -294,22 +297,39 @@ class PlayerProfile : public NoCopy // ---------------------------------------------------------------------------------------- StoryModeStatus* getStoryModeStatus() { return m_story_mode_status; } // ---------------------------------------------------------------------------------------- - FavoriteTrackStatus* getFavoriteTrackStatus() { return m_favorite_track_status; } + FavoriteStatus* getFavoriteTrackStatus() { return m_favorite_track_status; } + // ---------------------------------------------------------------------------------------- + FavoriteStatus* getFavoriteKartStatus() { return m_favorite_kart_status; } // ---------------------------------------------------------------------------------------- bool isFavoriteTrack(std::string ident) { - return m_favorite_track_status->isFavoriteTrack(ident); - } // getNumBestTrophies + return m_favorite_track_status->isFavorite(ident); + } void addFavoriteTrack(std::string ident, std::string group = - FavoriteTrackStatus::DEFAULT_FAVORITE_GROUP_NAME) + FavoriteStatus::DEFAULT_FAVORITE_GROUP_NAME) { - m_favorite_track_status->addFavoriteTrack(ident, group); - } // getNumBestTrophies + m_favorite_track_status->addFavorite(ident, group); + } void removeFavoriteTrack(std::string ident, std::string group = - FavoriteTrackStatus::DEFAULT_FAVORITE_GROUP_NAME) + FavoriteStatus::DEFAULT_FAVORITE_GROUP_NAME) { - m_favorite_track_status->removeFavoriteTrack(ident, group); - } // getNumBestTrophies + m_favorite_track_status->removeFavorite(ident, group); + } + // ---------------------------------------------------------------------------------------- + bool isFavoriteKart(std::string ident) + { + return m_favorite_kart_status->isFavorite(ident); + } + void addFavoriteKart(std::string ident, std::string group = + FavoriteStatus::DEFAULT_FAVORITE_GROUP_NAME) + { + m_favorite_kart_status->addFavorite(ident, group); + } + void removeFavoriteKart(std::string ident, std::string group = + FavoriteStatus::DEFAULT_FAVORITE_GROUP_NAME) + { + m_favorite_kart_status->removeFavorite(ident, group); + } // ---------------------------------------------------------------------------------------- /** If a session was saved, return the id of the saved user. */ int getSavedUserId() const diff --git a/src/guiengine/widgets/player_kart_widget.cpp b/src/guiengine/widgets/player_kart_widget.cpp index 4e06b0af64d..804261b2f58 100644 --- a/src/guiengine/widgets/player_kart_widget.cpp +++ b/src/guiengine/widgets/player_kart_widget.cpp @@ -238,7 +238,11 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent, m_model_view->setRotateContinuously( 35.0f ); // ---- Kart name label - m_kart_name = new LabelWidget(LabelWidget::NORMAL); + m_kart_name = new LabelWidget( + m_parent_screen->m_multiplayer ? + LabelWidget::TINY_TITLE: + LabelWidget::SMALL_TITLE); + m_kart_name->setText(props->getName(), false); m_kart_name->m_properties[PROP_TEXT_ALIGN] = "center"; m_kart_name->m_properties[PROP_ID] = diff --git a/src/karts/kart_properties.cpp b/src/karts/kart_properties.cpp index d7c1a68ebc1..2ef98446a14 100644 --- a/src/karts/kart_properties.cpp +++ b/src/karts/kart_properties.cpp @@ -658,12 +658,18 @@ bool KartProperties::operator<(const KartProperties &other) const PlayerProfile *p = PlayerManager::getCurrentPlayer(); bool this_is_locked = p->isLocked(getIdent()); bool other_is_locked = p->isLocked(other.getIdent()); - if (this_is_locked == other_is_locked) + bool this_is_favorite = p->isFavoriteKart(getNonTranslatedName()); + bool other_is_favorite = p->isFavoriteKart(other.getNonTranslatedName()); + + if (this_is_locked != other_is_locked) { - return getName() < other.getName(); - } - else return other_is_locked; + } + else if (this_is_favorite != other_is_favorite) + { + return this_is_favorite; + } + else return getName() < other.getName(); return true; } // operator< diff --git a/src/karts/kart_properties_manager.cpp b/src/karts/kart_properties_manager.cpp index 2eb0f09a8d5..adce7c117f1 100644 --- a/src/karts/kart_properties_manager.cpp +++ b/src/karts/kart_properties_manager.cpp @@ -52,6 +52,7 @@ std::vector KartPropertiesManager::m_kart_search_path; /** Constructor, only clears internal data structures. */ KartPropertiesManager::KartPropertiesManager() { + m_current_favorite_status = NULL; m_all_groups.clear(); } // KartPropertiesManager @@ -89,6 +90,7 @@ void KartPropertiesManager::unloadAllKarts() m_selected_karts.clear(); m_kart_available.clear(); m_groups_2_indices.clear(); + m_groups_2_indices_no_custom.clear(); m_all_groups.clear(); } // unloadAllKarts @@ -108,11 +110,34 @@ void KartPropertiesManager::removeKart(const std::string &ident) // Remove the just removed kart from the 'group-name to kart property // index' mapping. If a group is now empty (i.e. the removed kart was // the only member of this group), remove the group - const std::vector &groups = kp->getGroups(); + std::vector groups = kp->getGroups(); + if (m_current_favorite_status) + { + for (auto it = m_current_favorite_status->getAllFavorites().begin(); + it != m_current_favorite_status->getAllFavorites().end(); it++) + { // User-defined groups + if (it->second.find(kp->getNonTranslatedName()) != it->second.end()) + { + groups.push_back(it->first); + } + } + } for (unsigned int i=0; i ::iterator it; + it = std::find(m_groups_2_indices_no_custom[groups[i]].begin(), + m_groups_2_indices_no_custom[groups[i]].end(), index); + // Handle no custom group first + assert(it!=m_groups_2_indices_no_custom[groups[i]].end()); + + m_groups_2_indices_no_custom[groups[i]].erase(it); + + if(m_groups_2_indices_no_custom[groups[i]].size()==0) + { + m_groups_2_indices_no_custom.erase(groups[i]); + } + it = std::find(m_groups_2_indices[groups[i]].begin(), m_groups_2_indices[groups[i]].end(), index); // Since we are iterating over all groups the kart belongs to, @@ -138,6 +163,15 @@ void KartPropertiesManager::removeKart(const std::string &ident) // kart property index' mapping: all kart properties with an index // greater than index were moved one position further to the beginning std::map >::iterator it_gr; + for(it_gr=m_groups_2_indices_no_custom.begin(); it_gr != m_groups_2_indices_no_custom.end(); + it_gr++) + { + for(unsigned int i=0; i<(*it_gr).second.size(); i++) + { + if( (*it_gr).second[i]>index) + (*it_gr).second[i]--; + } + } for(it_gr=m_groups_2_indices.begin(); it_gr != m_groups_2_indices.end(); it_gr++) { @@ -281,7 +315,20 @@ bool KartPropertiesManager::loadKart(const std::string &dir) m_karts_properties.push_back(kart_properties); m_kart_available.push_back(true); - const std::vector& groups=kart_properties->getGroups(); + + std::vector groups=kart_properties->getGroups(); + if (m_current_favorite_status) + { + for (auto it = m_current_favorite_status->getAllFavorites().begin(); + it != m_current_favorite_status->getAllFavorites().end(); it++) + { // User-defined groups + if (it->second.find(kart_properties->getNonTranslatedName()) != it->second.end()) + { + groups.push_back(it->first); + } + } + } + for(unsigned int g=0; ggetAllFavorites().begin(); it != status->getAllFavorites().end(); it++) + { + for (auto it_name = it->second.begin(); it_name != it->second.end(); it_name++) + { + for (unsigned int i=0; ifirst].push_back(i); + break; + } + } + } + } + } + + std::map > &g2i = m_groups_2_indices; + std::vector &gn = m_all_groups; + gn.clear(); + + for (auto it = g2i.begin(); it != g2i.end(); it++) + { + std::sort(it->second.begin(), it->second.end()); + auto unique_end = std::unique(it->second.begin(), it->second.end()); + it->second.erase(unique_end, it->second.end()); + gn.push_back(it->first); + } + // Make sure the order of groups are correct + std::sort(gn.begin(), gn.end(), [&, g2i](std::string &a, std::string &b)->bool{ + int x = g2i.find(a)->second[0], y = g2i.find(b)->second[0]; + return x == y ? a < b : x < y; + }); +} // addFavorite + +//----------------------------------------------------------------------------- +void KartPropertiesManager::clearFavoriteKartStatus() +{ + setFavoriteKartStatus(NULL); +} // addFavorite + //----------------------------------------------------------------------------- /** Returns true if a kart is available to be selected. A kart is available to * be selected if it is available on all clients (i.e. m_kart_available is diff --git a/src/karts/kart_properties_manager.hpp b/src/karts/kart_properties_manager.hpp index 9466020a60f..a45c8daea6c 100644 --- a/src/karts/kart_properties_manager.hpp +++ b/src/karts/kart_properties_manager.hpp @@ -25,6 +25,7 @@ #include #include +#include "config/favorite_status.hpp" #include "network/remote_kart_info.hpp" #include "utils/no_copy.hpp" @@ -50,12 +51,18 @@ class KartPropertiesManager: public NoCopy /** List of all kart groups. */ std::vector m_all_groups; + /** Current favorite karts */ + FavoriteStatus* m_current_favorite_status; + /** List of all kart types. */ std::vector m_kart_types; /** Mapping of group names to list of kart indices in each group. */ std::map > m_groups_2_indices; + /** Mapping of group names to list of kart indices in each group without customized ones. */ + std::map > m_groups_2_indices_no_custom; + /** Vector containing kart numbers that have been selected in multiplayer * games. This it used to ensure the same kart can not be selected more * than once. */ @@ -93,6 +100,11 @@ class KartPropertiesManager: public NoCopy void unloadAllKarts (); void removeKart(const std::string &id); const std::vector getKartsInGroup (const std::string& g); + /** Adds a track to the special group of favorite tracks. + * We need to treat it specially, because the list of tracks in this group + * depends on the player-profile, not on the track data. */ + void setFavoriteKartStatus(FavoriteStatus *status); + void clearFavoriteKartStatus(); bool kartAvailable(int kartid); std::vector getAllAvailableKarts() const; void setUnavailableKarts(std::vector); @@ -112,7 +124,9 @@ class KartPropertiesManager: public NoCopy /** Get a characteristic that holds the values for a kart type. */ const AbstractCharacteristic* getKartTypeCharacteristic(const std::string &type, const std::string &name) const; // ------------------------------------------------------------------------ - const std::string& getDefaultKartType() const { return m_kart_types[0]; } + const std::vector& getAllKartTypes() const { return m_kart_types; } + // ------------------------------------------------------------------------ + const std::string& getDefaultKartType() const { return m_kart_types[0]; } // ------------------------------------------------------------------------ bool hasKartTypeCharacteristic(const std::string& type) const { @@ -124,7 +138,7 @@ class KartPropertiesManager: public NoCopy const AbstractCharacteristic* getPlayerCharacteristic(const std::string &type) const; // ------------------------------------------------------------------------ /** Returns a list of all groups. */ - const std::vector& getAllGroups() const {return m_all_groups;} + const std::vector& getAllGroups() const { return m_all_groups; } // ------------------------------------------------------------------------ /** Clears all selected karts (used in networking only). */ void clearAllSelectedKarts() { m_selected_karts.clear(); } diff --git a/src/states_screens/arenas_screen.cpp b/src/states_screens/arenas_screen.cpp index 9b6283d4533..21a915eb296 100644 --- a/src/states_screens/arenas_screen.cpp +++ b/src/states_screens/arenas_screen.cpp @@ -133,8 +133,13 @@ void ArenasScreen::beforeAddingWidget() void ArenasScreen::init() { - m_unsupported_arena.clear(); + m_random_arena_list.clear(); Screen::init(); + + m_search_box = getWidget("search"); + m_search_box->clearListeners(); + m_search_box->addListener(this); + buildTrackList(); DynamicRibbonWidget* w = this->getWidget("tracks"); // select something by default for the game master @@ -151,85 +156,48 @@ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const DynamicRibbonWidget* w2 = dynamic_cast(widget); if (w2 == NULL) return; - const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER); + std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER); if (UserConfigParams::logGUI()) Log::info("ArenasScreen", "Clicked on arena %s", selection.c_str()); if (selection == "random_track") { - RibbonWidget* tabs = this->getWidget("trackgroups"); - assert( tabs != NULL ); - - bool soccer_mode = RaceManager::get()->getMinorMode() == RaceManager::MINOR_MODE_SOCCER; - - std::vector curr_group; - if (tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER) == ALL_ARENA_GROUPS_ID) - { - const std::vector& groups = track_manager->getAllArenaGroups(); - for (unsigned int i = 0; i < groups.size(); i++) - { - const std::vector& tmp_group = track_manager->getArenasInGroup(groups[i], soccer_mode); - // Append to our main vector - curr_group.insert(curr_group.end(), tmp_group.begin(), tmp_group.end()); - } - } // if on tab "all" - else - { - curr_group = track_manager->getArenasInGroup( - tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER), soccer_mode ); - } - // Remove unsupported arena - if (m_unsupported_arena.size() > 0) - { - for (std::set::iterator it = m_unsupported_arena.begin(); - it != m_unsupported_arena.end(); ++it) - { - curr_group.erase(std::remove(curr_group.begin(), - curr_group.end(), *it), curr_group.end()); - } - } - - RandomGenerator random; - const int randomID = random.get((int)curr_group.size()); - - Track* clicked_track = track_manager->getTrack( curr_group[randomID] ); - if (clicked_track != NULL) - { - TrackInfoScreen::getInstance()->setTrack(clicked_track); - TrackInfoScreen::getInstance()->push(); - } + if (m_random_arena_list.empty()) return; + selection = m_random_arena_list.front(); + m_random_arena_list.pop_front(); + m_random_arena_list.push_back(selection); } else if (selection == "locked") { unlock_manager->playLockSound(); + return; } else if (selection == RibbonWidget::NO_ITEM_ID) { + return; } - else + + Track* clicked_track = track_manager->getTrack(selection); + if (clicked_track) { - Track* clicked_track = track_manager->getTrack(selection); - if (clicked_track != NULL) + // In favorite edit mode, switch the status of the selected track + if (getWidget("favorite")->getState()) { - // In favorite edit mode, switch the status of the selected track - if (getWidget("favorite")->getState()) - { - if(PlayerManager::getCurrentPlayer()->isFavoriteTrack(clicked_track->getIdent())) - PlayerManager::getCurrentPlayer()->removeFavoriteTrack(clicked_track->getIdent()); - else - PlayerManager::getCurrentPlayer()->addFavoriteTrack(clicked_track->getIdent()); - - buildTrackList(); - } + if(PlayerManager::getCurrentPlayer()->isFavoriteTrack(clicked_track->getIdent())) + PlayerManager::getCurrentPlayer()->removeFavoriteTrack(clicked_track->getIdent()); else - { - TrackInfoScreen::getInstance()->setTrack(clicked_track); - TrackInfoScreen::getInstance()->push(); - } - } // clickedTrack != NULL - } // if random_track + PlayerManager::getCurrentPlayer()->addFavoriteTrack(clicked_track->getIdent()); + + buildTrackList(); + } + else + { + TrackInfoScreen::getInstance()->setTrack(clicked_track); + TrackInfoScreen::getInstance()->push(); + } + } // clickedTrack != NULL } else if (name == "trackgroups") @@ -264,6 +232,8 @@ void ArenasScreen::buildTrackList() bool arenas_have_navmesh = false; PtrVector tracks; + m_random_arena_list.clear(); + if (curr_group_name == ALL_ARENA_GROUPS_ID) { const int track_amount = (int)track_manager->getNumberOfTracks(); @@ -271,6 +241,13 @@ void ArenasScreen::buildTrackList() for (int n=0; ngetTrack(n); + + core::stringw search_text = m_search_box->getText(); + search_text.make_lower(); + if (!search_text.empty() && + curr->getName().make_lower().find(search_text.c_str()) == -1) + continue; + if (soccer_mode) { if(curr->isSoccer() && curr->hasNavMesh() && !arenas_have_navmesh) @@ -281,8 +258,6 @@ void ArenasScreen::buildTrackList() RaceManager::get()->getNumLocalPlayers() > 1 || UserConfigParams::m_artist_debug_mode))) { - if (curr->isSoccer()) - m_unsupported_arena.insert(n); continue; } } @@ -296,8 +271,6 @@ void ArenasScreen::buildTrackList() RaceManager::get()->getNumLocalPlayers() > 1 || UserConfigParams::m_artist_debug_mode))) { - if (curr->isArena()) - m_unsupported_arena.insert(n); continue; } } @@ -312,6 +285,13 @@ void ArenasScreen::buildTrackList() for (int n=0; ngetTrack(currArenas[n]); + + core::stringw search_text = m_search_box->getText(); + search_text.make_lower(); + if (!search_text.empty() && + curr->getName().make_lower().find(search_text.c_str()) == -1) + continue; + if (soccer_mode) { if(curr->isSoccer() && curr->hasNavMesh() && !arenas_have_navmesh) @@ -322,8 +302,6 @@ void ArenasScreen::buildTrackList() RaceManager::get()->getNumLocalPlayers() > 1 || UserConfigParams::m_artist_debug_mode))) { - if (curr->isSoccer()) - m_unsupported_arena.insert(currArenas[n]); continue; } } @@ -337,8 +315,6 @@ void ArenasScreen::buildTrackList() RaceManager::get()->getNumLocalPlayers() > 1 || UserConfigParams::m_artist_debug_mode))) { - if (curr->isArena()) - m_unsupported_arena.insert(currArenas[n]); continue; } } @@ -360,22 +336,22 @@ void ArenasScreen::buildTrackList() w->addItem(curr->getName(), curr->getIdent(), curr->getScreenshotFile(), HEART_BADGE, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); + m_random_arena_list.push_back(curr->getIdent()); } else { w->addItem(curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE ); + m_random_arena_list.push_back(curr->getIdent()); } } + if (arenas_have_navmesh || RaceManager::get()->getNumLocalPlayers() > 1 || UserConfigParams::m_artist_debug_mode) w->addItem(_("Random Arena"), "random_track", "/gui/icons/track_random.png"); w->updateItemDisplay(); - if (m_unsupported_arena.size() > 0) - w->setText( _P("%d arena unavailable in single player.", - "%d arenas unavailable in single player.", - (int)m_unsupported_arena.size()) ); + std::random_shuffle( m_random_arena_list.begin(), m_random_arena_list.end() ); } // ------------------------------------------------------------------------------------------------------ diff --git a/src/states_screens/arenas_screen.hpp b/src/states_screens/arenas_screen.hpp index 6f603e7680f..c3941fff2ec 100644 --- a/src/states_screens/arenas_screen.hpp +++ b/src/states_screens/arenas_screen.hpp @@ -19,7 +19,9 @@ #define HEADER_ARENAS_SCREEN_HPP #include "guiengine/screen.hpp" +#include "guiengine/widgets/text_box_widget.hpp" +#include namespace GUIEngine { class Widget; } @@ -27,7 +29,9 @@ namespace GUIEngine { class Widget; } * \brief Handles the screen where a battle arena choice is offered * \ingroup states_screens */ -class ArenasScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton +class ArenasScreen : public GUIEngine::Screen, + public GUIEngine::ScreenSingleton, + public GUIEngine::ITextBoxWidgetListener { friend class GUIEngine::ScreenSingleton; @@ -35,7 +39,9 @@ class ArenasScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton void buildTrackList(); private: - std::set m_unsupported_arena; + std::deque m_random_arena_list; + + GUIEngine::TextBoxWidget *m_search_box; public: @@ -51,6 +57,14 @@ class ArenasScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton /** \brief implement callback from parent class GUIEngine::Screen */ virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) OVERRIDE; + + /** Rebuild the list of arenas based on search text */ + virtual void onTextUpdated() OVERRIDE + { + buildTrackList(); + // After buildTrackList the m_search_box may be unfocused + m_search_box->focused(0); + } void setFocusOnTrack(const std::string& trackName); }; diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index e8f344b13bc..b022f3b0ba4 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -26,6 +26,7 @@ #include #include "guiengine/message_queue.hpp" #include "guiengine/widgets/bubble_widget.hpp" +#include "guiengine/widgets/check_box_widget.hpp" #include "guiengine/widgets/kart_stats_widget.hpp" #include "guiengine/widgets/model_view_widget.hpp" #include "guiengine/widgets/player_name_spinner.hpp" @@ -273,6 +274,9 @@ void KartSelectionScreen::loadedFromFile() void KartSelectionScreen::beforeAddingWidget() { + kart_properties_manager->setFavoriteKartStatus( + PlayerManager::getCurrentPlayer()->getFavoriteKartStatus() + ); if (useContinueButton()) { getWidget("kartlist")->m_properties[GUIEngine::PROP_WIDTH] = "85%"; @@ -295,6 +299,10 @@ void KartSelectionScreen::beforeAddingWidget() if (removed_dispatcher) m_widgets.push_back(m_dispatcher); + CheckBoxWidget* favorite_cb = getWidget("favorite"); + assert( favorite_cb != NULL ); + favorite_cb->setState(false); + // Dynamically add tabs RibbonWidget* tabs = getWidget("kartgroups"); assert( tabs != NULL ); @@ -318,9 +326,17 @@ void KartSelectionScreen::beforeAddingWidget() //I18N: kart group name FOR_GETTEXT_ONLY( _("All") ) //I18N: kart group name + FOR_GETTEXT_ONLY( _("Favorite") ) + //I18N: kart group name FOR_GETTEXT_ONLY( _("Standard") ) //I18N: kart group name FOR_GETTEXT_ONLY( _("Add-Ons") ) + //I18N: kart class name + FOR_GETTEXT_ONLY( _("light") ) + //I18N: kart class name + FOR_GETTEXT_ONLY( _("medium") ) + //I18N: kart class name + FOR_GETTEXT_ONLY( _("heavy") ) // Add other groups after @@ -332,6 +348,17 @@ void KartSelectionScreen::beforeAddingWidget() tabs->addTextChild( _(groups[n].c_str()) , groups[n]); } // for n &classes = kart_properties_manager->getAllKartTypes(); + GUIEngine::SpinnerWidget* kart_class = getWidget("kart_class"); + assert(kart_class != NULL); + kart_class->m_properties[GUIEngine::PROP_MIN_VALUE] = "0"; + kart_class->m_properties[GUIEngine::PROP_MAX_VALUE] = StringUtils::toString(classes.size()); + + for (int i = 0; i < classes.size(); i++) + { + kart_class->addLabel(_(classes[i].c_str())); + } + kart_class->addLabel(_("All")); DynamicRibbonWidget* w = getWidget("karts"); assert( w != NULL ); @@ -378,6 +405,10 @@ void KartSelectionScreen::init() m_kart_widgets.clearAndDeleteAll(); + m_search_box = getWidget("search"); + m_search_box->clearListeners(); + m_search_box->addListener(this); + DynamicRibbonWidget* w = getWidget("karts"); assert( w != NULL ); // Only allow keyboard and gamepad to choose kart without continue button in @@ -387,6 +418,10 @@ void KartSelectionScreen::init() KartHoverListener* karthoverListener = new KartHoverListener(this); w->registerHoverListener(karthoverListener); + const std::vector &classes = kart_properties_manager->getAllKartTypes(); + GUIEngine::SpinnerWidget* kart_class = getWidget("kart_class"); + assert(kart_class != NULL); + kart_class->setValue(classes.size()); // All // Build kart list (it is built everytime, to account for .g. locking) setKartsFromCurrentGroup(); @@ -455,6 +490,8 @@ void KartSelectionScreen::init() void KartSelectionScreen::tearDown() { + kart_properties_manager->clearFavoriteKartStatus(); + #ifndef SERVER_ONLY GE::getGEConfig()->m_enable_draw_call_cache = false; GE::GEVulkanDriver* gevk = GE::getVKDriver(); @@ -795,7 +832,13 @@ void KartSelectionScreen::playerConfirm(const int player_id) { DynamicRibbonWidget* w = getWidget("karts"); assert(w != NULL); + const std::string selection = w->getSelectionIDString(player_id); + + if (selection == RANDOM_KART_ID && w->getItems().size() == 1) + { // Random kart only, do nothing + return; + } if (StringUtils::startsWith(selection, ID_LOCKED) && !m_multiplayer) { unlock_manager->playLockSound(); @@ -1163,9 +1206,32 @@ void KartSelectionScreen::eventCallback(Widget* widget, } else if (name == "karts") { - if (m_kart_widgets.size() > unsigned(player_id)) + if (getWidget("favorite")->getState()) + { + DynamicRibbonWidget* w = getWidget("karts"); + assert(w != NULL); + const std::string selection = w->getSelectionIDString(PLAYER_ID_GAME_MASTER); + + const KartProperties *kp = kart_properties_manager->getKart(selection); + + if (PlayerManager::getCurrentPlayer()->isFavoriteKart(kp->getNonTranslatedName())) + { + PlayerManager::getCurrentPlayer()->removeFavoriteKart(kp->getNonTranslatedName()); + } + else + { + PlayerManager::getCurrentPlayer()->addFavoriteKart(kp->getNonTranslatedName()); + } + + setKartsFromCurrentGroup(); + } + else if (m_kart_widgets.size() > unsigned(player_id)) playerConfirm(player_id); } + else if (name == "kart_class") + { + setKartsFromCurrentGroup(); + } else if (name == "continue") { if (m_kart_widgets.size() > unsigned(player_id)) @@ -1541,13 +1607,30 @@ PtrVector KartSelectionScreen::getUsableKarts( const std::string& selected_kart_group) { PtrVector karts; - for(unsigned int i=0; igetNumberOfKarts(); i++) + std::vector group = kart_properties_manager->getKartsInGroup(selected_kart_group); + + const std::vector &classes = kart_properties_manager->getAllKartTypes(); + GUIEngine::SpinnerWidget* kart_class = getWidget("kart_class"); + assert(kart_class != NULL); + + for(unsigned int i=0; igetKartById(i); + const KartProperties* prop = kart_properties_manager->getKartById(group[i]); // Ignore karts that are not in the selected group - if((selected_kart_group != ALL_KART_GROUPS_ID && - !prop->isInGroup(selected_kart_group)) || isIgnored(prop->getIdent())) + if(isIgnored(prop->getIdent())) continue; + + // Check if there's text in search bar + core::stringw search_text = m_search_box->getText(); + search_text.make_lower(); + if (!search_text.empty() && + prop->getName().make_lower().find(search_text.c_str()) == -1) + continue; + + if (kart_class->getValue() != classes.size() && + classes[kart_class->getValue()] != prop->getKartType()) + continue; + karts.push_back(prop); } karts.insertionSort(); @@ -1558,6 +1641,10 @@ PtrVector KartSelectionScreen::getUsableKarts( void KartSelectionScreen::setKartsFromCurrentGroup() { + kart_properties_manager->setFavoriteKartStatus( + PlayerManager::getCurrentPlayer()->getFavoriteKartStatus() + ); + RibbonWidget* tabs = getWidget("kartgroups"); assert(tabs != NULL); @@ -1566,30 +1653,11 @@ void KartSelectionScreen::setKartsFromCurrentGroup() UserConfigParams::m_last_used_kart_group = selected_kart_group; - // This can happen if addons are removed so that also the previously - // selected kart group is removed. In this case, select the - // 'standard' group - if (selected_kart_group != ALL_KART_GROUPS_ID && - !kart_properties_manager->getKartsInGroup(selected_kart_group).size()) - { - selected_kart_group = DEFAULT_GROUP_NAME; - } - DynamicRibbonWidget* w = getWidget("karts"); w->clearItems(); - int usable_kart_count = 0; PtrVector karts = getUsableKarts(selected_kart_group); - if (karts.empty()) - { - // In network this will happen if no addons kart on server - PtrVector new_karts = - getUsableKarts(DEFAULT_GROUP_NAME); - std::swap(karts.m_contents_vector, new_karts.m_contents_vector); - tabs->select(DEFAULT_GROUP_NAME, PLAYER_ID_GAME_MASTER); - } - for(unsigned int i=0; igetAbsoluteIconFile(), LOCKED_BADGE, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); } + else if (PlayerManager::getCurrentPlayer()->isFavoriteKart(prop->getNonTranslatedName())) + { + w->addItem(prop->getName(), + prop->getIdent(), + prop->getAbsoluteIconFile(), HEART_BADGE, + IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); + } else { w->addItem(prop->getName(), prop->getIdent(), prop->getAbsoluteIconFile(), 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); - usable_kart_count++; } } // add random - if (usable_kart_count > 1) - { - w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/icons/random_kart.png"); - } + w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/icons/random_kart.png"); w->updateItemDisplay(); } diff --git a/src/states_screens/kart_selection.hpp b/src/states_screens/kart_selection.hpp index b03b4e4308c..f79198547c0 100644 --- a/src/states_screens/kart_selection.hpp +++ b/src/states_screens/kart_selection.hpp @@ -22,6 +22,7 @@ #include "guiengine/screen.hpp" #include "guiengine/widgets/dynamic_ribbon_widget.hpp" #include "guiengine/widgets/player_kart_widget.hpp" +#include "guiengine/widgets/text_box_widget.hpp" #include "states_screens/state_manager.hpp" namespace GUIEngine @@ -47,7 +48,8 @@ extern int g_root_id; * \brief screen where players can choose their kart * \ingroup states_screens */ -class KartSelectionScreen : public GUIEngine::Screen +class KartSelectionScreen : public GUIEngine::Screen, + public GUIEngine::ITextBoxWidgetListener { friend class KartHoverListener; friend class PlayerNameSpinner; @@ -78,6 +80,8 @@ class KartSelectionScreen : public GUIEngine::Screen GUIEngine::PlayerKartWidget* m_removed_widget; + GUIEngine::TextBoxWidget *m_search_box; + /** Message shown in multiplayer mode */ GUIEngine::BubbleWidget* m_multiplayer_message; @@ -172,6 +176,14 @@ class KartSelectionScreen : public GUIEngine::Screen /** \brief implement callback from parent class GUIEngine::Screen */ virtual void onUpdate(float dt) OVERRIDE; + /** Rebuild the list of tracks based on search text */ + virtual void onTextUpdated() OVERRIDE + { + setKartsFromCurrentGroup(); + // After setKartsFromCurrentGroup the m_search_box may be unfocused + m_search_box->focused(PLAYER_ID_GAME_MASTER); + } + /** \brief implement optional callback from parent * class GUIEngine::Screen */ virtual void unloaded() OVERRIDE; diff --git a/src/states_screens/tracks_and_gp_screen.cpp b/src/states_screens/tracks_and_gp_screen.cpp index a8ab6542edd..124002d6ace 100644 --- a/src/states_screens/tracks_and_gp_screen.cpp +++ b/src/states_screens/tracks_and_gp_screen.cpp @@ -18,7 +18,7 @@ #include "states_screens/tracks_and_gp_screen.hpp" #include "challenges/unlock_manager.hpp" -#include "config/favorite_track_status.hpp" +#include "config/favorite_status.hpp" #include "config/player_manager.hpp" #include "config/user_config.hpp" #include "graphics/stk_tex_manager.hpp" @@ -227,7 +227,7 @@ void TracksAndGPScreen::init() const GrandPrixData* gp = grand_prix_manager->getGrandPrix(n); const std::vector tracks = gp->getTrackNames(true); - //Skip epmpty GPs + //Skip empty GPs if (gp->getNumberOfTracks()==0) continue; diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index d5934ec0e67..67ccf059a79 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -23,7 +23,7 @@ #include "audio/music_manager.hpp" #include "challenges/challenge_status.hpp" #include "challenges/unlock_manager.hpp" -#include "config/favorite_track_status.hpp" +#include "config/favorite_status.hpp" #include "config/player_manager.hpp" #include "config/stk_config.hpp" #include "config/user_config.hpp" @@ -616,7 +616,7 @@ void Track::loadTrackInfo() m_all_modes.push_back(tm); } - if(m_groups.size()==0) m_groups.push_back(FavoriteTrackStatus::DEFAULT_FAVORITE_GROUP_NAME); + if(m_groups.size()==0) m_groups.push_back(FavoriteStatus::DEFAULT_FAVORITE_GROUP_NAME); const XMLNode *xml_node = root->getNode("curves"); if(xml_node) loadCurves(*xml_node); diff --git a/src/tracks/track_manager.cpp b/src/tracks/track_manager.cpp index 271492cabbd..667cc7ad842 100644 --- a/src/tracks/track_manager.cpp +++ b/src/tracks/track_manager.cpp @@ -318,8 +318,8 @@ void TrackManager::removeTrackFromGroups(TrackGroupType type, const Track* track std::vector groups = track->getGroups(); if (m_current_favorite_status) { - for (auto it = m_current_favorite_status->m_favorite_tracks.begin(); - it != m_current_favorite_status->m_favorite_tracks.end(); it++) + for (auto it = m_current_favorite_status->getAllFavorites().begin(); + it != m_current_favorite_status->getAllFavorites().end(); it++) { // User-defined groups if (it->second.find(track->getIdent()) != it->second.end()) { @@ -415,8 +415,8 @@ void TrackManager::updateGroups(TrackGroupType type, const Track* track) if (m_current_favorite_status) { - for (auto it = m_current_favorite_status->m_favorite_tracks.begin(); - it != m_current_favorite_status->m_favorite_tracks.end(); it++) + for (auto it = m_current_favorite_status->getAllFavorites().begin(); + it != m_current_favorite_status->getAllFavorites().end(); it++) { // User-defined groups if (it->second.find(ident) != it->second.end()) { @@ -433,36 +433,37 @@ void TrackManager::updateGroups(TrackGroupType type, const Track* track) // ---------------------------------------------------------------------------- /** \brief Adds a player's favorite track status to define the custom group */ -void TrackManager::setFavoriteTrackStatus(FavoriteTrackStatus *status) +void TrackManager::setFavoriteTrackStatus(FavoriteStatus *status) { - clearFavoriteTrackStatus(); + m_track_groups = m_track_groups_no_custom; + m_arena_groups = m_arena_groups_no_custom; + m_soccer_arena_groups = m_soccer_arena_groups_no_custom; m_current_favorite_status = status; - if (status == NULL) - { - return; - } - - // Add all user-defined groups - for (auto it = status->m_favorite_tracks.begin(); it != status->m_favorite_tracks.end(); it++) + if (status) { - for (auto it_name = it->second.begin(); it_name != it->second.end(); it_name++) + // Add all user-defined groups + for (auto it = status->getAllFavorites().begin(); it != status->getAllFavorites().end(); it++) { - int id = getTrackIndexByIdent(*it_name); - if (id >= 0) // The index is negative if a track matching the index is missing + for (auto it_name = it->second.begin(); it_name != it->second.end(); it_name++) { - Track *track = m_tracks[id]; - - if(track->isArena()) - m_arena_groups[it->first].push_back(id); - if(track->isSoccer()) - m_soccer_arena_groups[it->first].push_back(id); - if(!track->isArena() && !track->isSoccer()) - m_track_groups[it->first].push_back(id); + int id = getTrackIndexByIdent(*it_name); + if (id >= 0) // The index is negative if a track matching the index is missing + { + Track *track = m_tracks[id]; + + if(track->isArena()) + m_arena_groups[it->first].push_back(id); + if(track->isSoccer()) + m_soccer_arena_groups[it->first].push_back(id); + if(!track->isArena() && !track->isSoccer()) + m_track_groups[it->first].push_back(id); + } } } } + for (int i = 0; i < 3; i++) { Group2Indices &g2i = (i==0 ? m_soccer_arena_groups : @@ -479,13 +480,13 @@ void TrackManager::setFavoriteTrackStatus(FavoriteTrackStatus *status) it->second.erase(unique_end, it->second.end()); gn.push_back(it->first); } - // Make sure the order of groups are right + // Make sure the order of groups are correct std::sort(gn.begin(), gn.end(), [&, g2i](std::string &a, std::string &b)->bool{ int x = g2i.find(a)->second[0], y = g2i.find(b)->second[0]; return x == y ? a < b : x < y; }); } -} // addFavoriteTrack +} // addFavorite // ---------------------------------------------------------------------------- /** \brief Clears the list of active favorite tracks, used e.g. when switching @@ -493,12 +494,8 @@ void TrackManager::setFavoriteTrackStatus(FavoriteTrackStatus *status) */ void TrackManager::clearFavoriteTrackStatus() { - m_track_groups = m_track_groups_no_custom; - m_arena_groups = m_arena_groups_no_custom; - m_soccer_arena_groups = m_soccer_arena_groups_no_custom; - - m_current_favorite_status = NULL; -} // clearFavoriteTracks + setFavoriteTrackStatus(NULL); +} // clearFavorites // ---------------------------------------------------------------------------- int TrackManager::getTrackIndexByIdent(const std::string& ident) const diff --git a/src/tracks/track_manager.hpp b/src/tracks/track_manager.hpp index c40e56fd951..cacf421a6af 100644 --- a/src/tracks/track_manager.hpp +++ b/src/tracks/track_manager.hpp @@ -19,7 +19,7 @@ #ifndef HEADER_TRACK_MANAGER_HPP #define HEADER_TRACK_MANAGER_HPP -#include "config/favorite_track_status.hpp" +#include "config/favorite_status.hpp" #include #include @@ -81,7 +81,7 @@ class TrackManager */ std::vector m_track_avail; - FavoriteTrackStatus *m_current_favorite_status; + FavoriteStatus *m_current_favorite_status; void updateAllGroups(const Track* track); void updateGroups(TrackGroupType type, const Track* track); @@ -94,9 +94,9 @@ class TrackManager static void addTrackSearchDir(const std::string &dir); /** Adds a track to the special group of favorite tracks. - * We need a special treatment, because the list of tracks in this group + * We need to treat it specially, because the list of tracks in this group * depends on the player-profile, not on the track data. */ - void setFavoriteTrackStatus(FavoriteTrackStatus *status); + void setFavoriteTrackStatus(FavoriteStatus *status); void clearFavoriteTrackStatus();