Skip to content

Commit

Permalink
Rewrite favorite system
Browse files Browse the repository at this point in the history
  • Loading branch information
CodingJellyfish committed Aug 9, 2024
1 parent c61ab02 commit a435655
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 162 deletions.
13 changes: 10 additions & 3 deletions data/gui/screens/arenas.stkgui
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@
<icon-button id="back" x="1%" y="0" height="9%" icon="gui/icons/back.png"/>

<div x="2%" y="1%" width="96%" height="99%" layout="vertical-row" >
<header height="8%" width="80%" I18N="Section in arena tracks selection screen" text="Arenas"
align="center" text_align="center" />
<spacer width="20" height="1%" />
<div width="100%" height="8%" layout="horizontal-row" >
<spacer width="30%" height="100%" />
<header height="8%" width="40%" I18N="Section in arena tracks selection screen" text="Arenas"
align="center" text_align="center" />
<spacer width="1%" height="100%" />
<checkbox id="favorite" align="center"/>
<spacer width="1%" height="100%" />
<bright width="30%" height="100%" I18N="In the track and grand prix selection screen" text="Edit favorite tracks"/>
<spacer width="20" height="1%" />
</div>

<box proportion="1" width="100%" layout="vertical-row" padding="2">
<ribbon_grid id="tracks" proportion="1" width="100%" square_items="true"
Expand Down
4 changes: 2 additions & 2 deletions data/gui/screens/tracks_and_gp.stkgui
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
<div width="100%" height="fit" layout="horizontal-row" >
<header width="30%" I18N="In the track and grand prix selection screen" text="All Tracks"
align="center" text_align="center" />
<textbox width="35%" id="search"/>
<textbox width="40%" id="search"/>
<spacer width="1%" height="100%" />
<checkbox id="favorite"/>
<spacer width="1%" height="100%" />
<label width="30%" height="100%" I18N="In the track and grand prix selection screen" text="Edit favorite tracks"/>
<bright width="25%" height="100%" I18N="In the track and grand prix selection screen" text="Edit favorite tracks"/>
</div>

<spacer width="100%" height="1%" />
Expand Down
5 changes: 0 additions & 5 deletions src/config/player_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,6 @@ void PlayerManager::initRemainingData()

// Sort player by frequency
m_all_players.insertionSort(/*start*/0, /*desc*/true);

// Load favorite tracks for the current player
if (m_current_player)
m_current_player->setFavoriteTracks();
} // initRemainingData

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -486,7 +482,6 @@ void PlayerManager::setCurrentPlayer(PlayerProfile *player)
if(m_current_player)
{
m_current_player->computeActive();
m_current_player->setFavoriteTracks();
}

if (player_has_changed)
Expand Down
81 changes: 15 additions & 66 deletions src/config/player_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
m_remember_password = false;
m_story_mode_status = NULL;
m_achievements_status = NULL;
m_favorite_tracks.clear();
m_favorite_track_status = NULL;
m_default_kart_color = 0.0f;
m_icon_filename = "";

Expand All @@ -106,6 +106,7 @@ PlayerProfile::~PlayerProfile()
{
delete m_story_mode_status;
delete m_achievements_status;
delete m_favorite_track_status;
#ifdef DEBUG
m_magic_number = 0xDEADBEEF;
#endif
Expand All @@ -118,29 +119,20 @@ PlayerProfile::~PlayerProfile()
*/
void PlayerProfile::loadRemainingData(const XMLNode *node)
{
assert(m_story_mode_status == NULL);
const XMLNode *xml_story_mode = node->getNode("story-mode");
m_story_mode_status =
unlock_manager->createStoryModeStatus(xml_story_mode);
m_story_mode_status = unlock_manager->createStoryModeStatus(xml_story_mode);

assert(m_achievements_status == NULL);
const XMLNode *xml_achievements = node->getNode("achievements");
m_achievements_status = AchievementsManager::get()
->createAchievementsStatus(xml_achievements, m_unique_id == 1);
->createAchievementsStatus(xml_achievements, m_unique_id == 1);

// We first load the list of all favorite tracks
// Some favorites may correspond to uninstalled addons, so we do not sanitize the strings
// TODO : handle Arena and Soccer fields
assert(m_favorite_track_statuss == NULL);
const XMLNode *xml_favorites = node->getNode("favorites");
std::vector<XMLNode*> xml_favorite_tracks;
xml_favorites->getNodes("track", xml_favorite_tracks);
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.push_back(temp_string);
}
// Deduplicate the list just in case.
std::sort(m_favorite_tracks.begin(), m_favorite_tracks.end());
auto it = std::unique(m_favorite_tracks.begin(), m_favorite_tracks.end());
m_favorite_tracks.erase(it, m_favorite_tracks.end());
m_favorite_track_status = new FavoriteTrackStatus(xml_favorites);

// Fix up any potentially missing icons.
addIcon();
Expand All @@ -155,49 +147,10 @@ void PlayerProfile::initRemainingData()
m_story_mode_status = unlock_manager->createStoryModeStatus();
m_achievements_status =
AchievementsManager::get()->createAchievementsStatus();
m_favorite_track_status = new FavoriteTrackStatus(NULL);
addIcon();
} // initRemainingData

//------------------------------------------------------------------------------
/** Update the group of favorite tracks handled by the Track Manager.
* To be used only if this player profile is the current player.
*/
void PlayerProfile::setFavoriteTracks()
{
// Update the group data from the Track Manager
track_manager->clearFavoriteTracks();
for (unsigned int i = 0; i < m_favorite_tracks.size(); i++)
{
track_manager->addFavoriteTrack(m_favorite_tracks[i]);
}
} // setFavoriteTracks

//------------------------------------------------------------------------------
/** 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.
*/
void PlayerProfile::addFavoriteTrack(std::string ident)
{
m_favorite_tracks.push_back(ident);
track_manager->addFavoriteTrack(ident);
} // addFavoriteTrack

//------------------------------------------------------------------------------
/** Removes a favorite track from this player profile and from the group
* of favorite tracks of the Track Manager.
* To be used only if this player profile is the current player.
*/
void PlayerProfile::removeFavoriteTrack(std::string ident)
{
auto it = std::find(m_favorite_tracks.begin(), m_favorite_tracks.end(), ident);
if (it != m_favorite_tracks.end()) // the track to remove has been found
{
m_favorite_tracks.erase(it);
setFavoriteTracks();
}
} // removeFavoriteTrack

//------------------------------------------------------------------------------
/** Creates an icon for a player if non exist so far. It takes the unique
* player id modulo the number of karts to pick an icon from the karts. It
Expand Down Expand Up @@ -282,18 +235,14 @@ void PlayerProfile::save(UTFWriter &out)
if (player != NULL && (getName() == player->getName()))
is_current_player = true;

if(m_story_mode_status)
if (m_story_mode_status)
m_story_mode_status->save(out, is_current_player);

if(m_achievements_status)
if (m_achievements_status)
m_achievements_status->save(out);

out << " <favorites>\n";
for (unsigned int i=0; i < m_favorite_tracks.size(); i++)
{
out << " <track ident=\"" << m_favorite_tracks[i] << "\"/>\n";
}
out << " </favorites>\n";

if (m_favorite_track_status)
m_favorite_track_status->save(out);
}
out << " </player>\n";
} // save
Expand Down
32 changes: 20 additions & 12 deletions src/config/player_profile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define HEADER_PLAYER_PROFILE_HPP

#include "challenges/story_mode_status.hpp"
#include "config/favorite_track_status.hpp"
#include "network/remote_kart_info.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
Expand Down Expand Up @@ -114,8 +115,8 @@ class PlayerProfile : public NoCopy
/** The complete achievement data. */
AchievementsStatus *m_achievements_status;

/** The list of identifiers of favorite tracks .*/
std::vector<std::string> m_favorite_tracks;
/** The favorite tracks selected by this player. */
FavoriteTrackStatus *m_favorite_track_status;

public:

Expand All @@ -125,9 +126,6 @@ class PlayerProfile : public NoCopy
void save(UTFWriter &out);
void loadRemainingData(const XMLNode *node);
void initRemainingData();
void setFavoriteTracks();
void addFavoriteTrack(std::string ident);
void removeFavoriteTrack(std::string ident);
void incrementUseFrequency();
int getUseFrequency() const { return m_use_frequency; }
bool operator<(const PlayerProfile &other);
Expand Down Expand Up @@ -204,13 +202,6 @@ class PlayerProfile : public NoCopy
return m_story_mode_status->isLocked(feature);
} // isLocked
// ----------------------------------------------------------------------------------------
/** Returnes if the track is favorite. */
bool isFavoriteTrack(const std::string &ident) const
{
return std::find(m_favorite_tracks.begin(), m_favorite_tracks.end(), ident)
!= m_favorite_tracks.end();
} // isFavoriteTrack
// ----------------------------------------------------------------------------------------
/** Returns all active challenges. */
void computeActive() { m_story_mode_status->computeActive(); }
// ----------------------------------------------------------------------------------------
Expand Down Expand Up @@ -303,6 +294,23 @@ class PlayerProfile : public NoCopy
// ----------------------------------------------------------------------------------------
StoryModeStatus* getStoryModeStatus() { return m_story_mode_status; }
// ----------------------------------------------------------------------------------------
FavoriteTrackStatus* getFavoriteTrackStatus() { return m_favorite_track_status; }
// ----------------------------------------------------------------------------------------
bool isFavoriteTrack(std::string ident)
{
return m_favorite_track_status->isFavoriteTrack(ident);
} // getNumBestTrophies
void addFavoriteTrack(std::string ident, std::string group =
FavoriteTrackStatus::DEFAULT_FAVORITE_GROUP_NAME)
{
m_favorite_track_status->addFavoriteTrack(ident, group);
} // getNumBestTrophies
void removeFavoriteTrack(std::string ident, std::string group =
FavoriteTrackStatus::DEFAULT_FAVORITE_GROUP_NAME)
{
m_favorite_track_status->removeFavoriteTrack(ident, group);
} // getNumBestTrophies
// ----------------------------------------------------------------------------------------
/** If a session was saved, return the id of the saved user. */
int getSavedUserId() const
{
Expand Down
72 changes: 48 additions & 24 deletions src/states_screens/arenas_screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "io/file_manager.hpp"
Expand Down Expand Up @@ -57,6 +58,11 @@ void ArenasScreen::loadedFromFile()

void ArenasScreen::beforeAddingWidget()
{
track_manager->setFavoriteTrackStatus(PlayerManager::getCurrentPlayer()->getFavoriteTrackStatus());

CheckBoxWidget* favorite_cb = getWidget<CheckBoxWidget>("favorite");
assert( favorite_cb != NULL );
favorite_cb->setState(false);

// Dynamically add tabs
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
Expand All @@ -79,6 +85,8 @@ void ArenasScreen::beforeAddingWidget()
//I18N: track group name
FOR_GETTEXT_ONLY( _("All") )
//I18N: track group name
FOR_GETTEXT_ONLY( _("Favorites") )
//I18N: track group name
FOR_GETTEXT_ONLY( _("Standard") )
//I18N: track group name
FOR_GETTEXT_ONLY( _("Add-Ons") )
Expand Down Expand Up @@ -204,8 +212,20 @@ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const
Track* clicked_track = track_manager->getTrack(selection);
if (clicked_track != NULL)
{
TrackInfoScreen::getInstance()->setTrack(clicked_track);
TrackInfoScreen::getInstance()->push();
if (getWidget<CheckBoxWidget>("favorite")->getState())
{
if(PlayerManager::getCurrentPlayer()->isFavoriteTrack(clicked_track->getIdent()))
PlayerManager::getCurrentPlayer()->removeFavoriteTrack(clicked_track->getIdent());
else
PlayerManager::getCurrentPlayer()->addFavoriteTrack(clicked_track->getIdent());

buildTrackList();
}
else
{
TrackInfoScreen::getInstance()->setTrack(clicked_track);
TrackInfoScreen::getInstance()->push();
}
} // clickedTrack != NULL
} // if random_track

Expand All @@ -225,6 +245,8 @@ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const

void ArenasScreen::buildTrackList()
{
track_manager->setFavoriteTrackStatus(PlayerManager::getCurrentPlayer()->getFavoriteTrackStatus());

DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tracks");
assert( w != NULL );

Expand All @@ -237,6 +259,7 @@ void ArenasScreen::buildTrackList()

bool soccer_mode = RaceManager::get()->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
bool arenas_have_navmesh = false;
PtrVector<Track, REF> tracks;

if (curr_group_name == ALL_ARENA_GROUPS_ID)
{
Expand Down Expand Up @@ -275,19 +298,8 @@ void ArenasScreen::buildTrackList()
continue;
}
}

if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE );
}
else
{
w->addItem(curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
}
tracks.push_back(curr);
}

}
else
{
Expand Down Expand Up @@ -327,17 +339,29 @@ void ArenasScreen::buildTrackList()
continue;
}
}
tracks.push_back(curr);
}
}
tracks.insertionSort();

if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE );
}
else
{
w->addItem(curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
}
for (unsigned int i = 0; i < tracks.size(); i++)
{
Track *curr = tracks.get(i);
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE );
}
else if (PlayerManager::getCurrentPlayer()->isFavoriteTrack(curr->getIdent()))
{
w->addItem(curr->getName(), curr->getIdent(),
curr->getScreenshotFile(), HEART_BADGE,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
}
else
{
w->addItem(curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
}
}
if (arenas_have_navmesh || RaceManager::get()->getNumLocalPlayers() > 1 ||
Expand Down
Loading

0 comments on commit a435655

Please sign in to comment.