Big ass commit regarding achievement viewing of other people via their profile.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13658 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
unitraxx 2013-09-10 20:41:57 +00:00
parent 095d5a58c1
commit cbca9404e3
17 changed files with 317 additions and 39 deletions

View File

@ -0,0 +1,22 @@
<stkgui>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
<div x="1%" y="2%" width="98%" height="96%" layout="vertical-row" >
<header id="title" text_align="center" width="80%" align="center" text="..."/>
<spacer height="25" width="10"/>
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_overview" width="128" height="128" icon="gui/options_ui.png" />
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png"/>
<icon-button id="tab_achievements" width="128" height="128" icon="gui/options_players.png" I18N="Section in the profile menu" text="Achievements"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row" padding="6">
<list id="achievements_list" x="0" y="0" width="100%" height="100%"/>
</box>
</div>
</stkgui>

View File

@ -11,6 +11,7 @@
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_overview" width="128" height="128" icon="gui/options_ui.png" />
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png" I18N="Section in the profile menu" text="Friends"/>
<icon-button id="tab_achievements" width="128" height="128" icon="gui/options_players.png"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row" padding="6">

View File

@ -9,6 +9,7 @@
<tabs id="profile_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_overview" width="128" height="128" icon="gui/options_ui.png" I18N="Section in the profile menu" text="Overview"/>
<icon-button id="tab_friends" width="128" height="128" icon="gui/options_players.png" />
<icon-button id="tab_achievements" width="128" height="128" icon="gui/options_players.png"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row">

View File

@ -236,6 +236,7 @@ src/states_screens/main_menu_screen.cpp
src/states_screens/networking_lobby.cpp
src/states_screens/network_kart_selection.cpp
src/states_screens/offline_kart_selection.cpp
src/states_screens/online_profile_achievements.cpp
src/states_screens/online_profile_base.cpp
src/states_screens/online_profile_friends.cpp
src/states_screens/online_profile_overview.cpp
@ -543,6 +544,7 @@ src/states_screens/main_menu_screen.hpp
src/states_screens/networking_lobby.hpp
src/states_screens/network_kart_selection.hpp
src/states_screens/offline_kart_selection.hpp
src/states_screens/online_profile_achievements.hpp
src/states_screens/online_profile_base.hpp
src/states_screens/online_profile_friends.hpp
src/states_screens/online_profile_overview.hpp

View File

@ -50,6 +50,12 @@ void AchievementsManager::deallocate()
AchievementsManager::AchievementsManager()
{
parseDataFile();
}
// ============================================================================
void AchievementsManager::init()
{
parseConfigFile();
updateCurrentPlayer();
}
@ -59,7 +65,11 @@ AchievementsManager::~AchievementsManager()
{
save();
m_slots.clearAndDeleteAll();
m_achievements_info.clearAndDeleteAll();
std::map<uint32_t, AchievementInfo *>::iterator it;
for ( it = m_achievements_info.begin(); it != m_achievements_info.end(); ++it ) {
delete it->second;
}
m_achievements_info.clear();
}
// ============================================================================
@ -67,8 +77,8 @@ void AchievementsManager::parseDataFile()
{
const std::string file_name = file_manager->getDataFile("achievements.xml");
const XMLNode *root = file_manager->createXMLTree(file_name);
int num_nodes = root->getNumNodes();
for(int i = 0; i < num_nodes; i++)
unsigned int num_nodes = root->getNumNodes();
for(unsigned int i = 0; i < num_nodes; i++)
{
const XMLNode *node = root->getNode(i);
std::string type("");
@ -87,7 +97,7 @@ void AchievementsManager::parseDataFile()
Log::error("AchievementsManager::parseAchievements","Non-existent achievement type. Skipping - definitely results in unwanted behaviour.");
continue;
}
m_achievements_info.push_back(achievement_info);
m_achievements_info[achievement_info->getID()] = achievement_info;
}
if(num_nodes != m_achievements_info.size())
Log::error("AchievementsManager::parseAchievements","Multiple achievements with the same id!");
@ -101,8 +111,7 @@ void AchievementsManager::parseConfigFile()
XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "achievements")
{
Log::info("AchievementsManager", "Achievements file '%s' will be created.",
filename.c_str());
Log::info("AchievementsManager", "Achievements file '%s' will be created.",filename.c_str());
createSlotsIfNeeded();
if (root) delete root;
return;
@ -112,7 +121,7 @@ void AchievementsManager::parseConfigFile()
root->getNodes("slot", xml_slots);
for (unsigned int n=0; n < xml_slots.size(); n++)
{
AchievementsSlot * slot = new AchievementsSlot(xml_slots[n], m_achievements_info);
AchievementsSlot * slot = new AchievementsSlot(xml_slots[n]);
if(!slot->isValid())
{
Log::warn("AchievementsManager", "Found game slot with faulty or missing information. Discarding it.");
@ -127,7 +136,7 @@ void AchievementsManager::parseConfigFile()
AchievementsSlot * AchievementsManager::createNewSlot(std::string id, bool online)
{
AchievementsSlot* slot = new AchievementsSlot(id, online, m_achievements_info);
AchievementsSlot* slot = new AchievementsSlot(id, online);
m_slots.push_back(slot);
return slot;
}
@ -228,3 +237,12 @@ void AchievementsManager::updateCurrentPlayer()
}
}
}
// ============================================================================
AchievementInfo * AchievementsManager::getAchievementInfo(uint32_t id)
{
if ( m_achievements_info.find(id) != m_achievements_info.end())
return m_achievements_info[id];
return NULL;
}

View File

@ -42,24 +42,27 @@ class AchievementsManager
private :
AchievementsSlot * m_active_slot;
PtrVector<AchievementsSlot> m_slots;
PtrVector<AchievementInfo> m_achievements_info;
std::map<uint32_t, AchievementInfo *> m_achievements_info;
AchievementsManager ();
~AchievementsManager ();
AchievementsSlot * createNewSlot(std::string id, bool online);
void parseDataFile();
void parseConfigFile();
public:
/**Singleton */
static AchievementsManager * get();
static void deallocate();
void parseDataFile();
void parseConfigFile();
void init();
void save();
void onRaceEnd();
void updateCurrentPlayer();
AchievementsSlot * getActive() const { return m_active_slot; }
AchievementsSlot * getSlot(const std::string & id, bool online);
void createSlotsIfNeeded();
AchievementInfo * getAchievementInfo(uint32_t id);
const std::map<uint32_t, AchievementInfo *> & getAllInfo() { return m_achievements_info;}
}; // class AchievementsManager
#endif

View File

@ -31,7 +31,7 @@
#include <stdlib.h>
#include <assert.h>
// ============================================================================
AchievementsSlot::AchievementsSlot(const XMLNode * input, const PtrVector<AchievementInfo> & info)
AchievementsSlot::AchievementsSlot(const XMLNode * input)
{
int fetched_user_id = input->get("user_id", &m_id);
std::string online;
@ -43,7 +43,7 @@ AchievementsSlot::AchievementsSlot(const XMLNode * input, const PtrVector<Achie
m_valid = true;
m_online = online == "true";
createFreshSlot(info);
createFreshSlot();
std::vector<XMLNode*> xml_achievements;
input->getNodes("achievement", xml_achievements);
@ -62,31 +62,47 @@ AchievementsSlot::AchievementsSlot(const XMLNode * input, const PtrVector<Achie
}
// ============================================================================
AchievementsSlot::AchievementsSlot(std::string id, bool online, const PtrVector<AchievementInfo> & info)
AchievementsSlot::AchievementsSlot(std::string id, bool online)
{
m_valid = true;
m_online = online;
m_id = id;
createFreshSlot(info);
createFreshSlot();
}
// ============================================================================
void AchievementsSlot::createFreshSlot( const PtrVector<AchievementInfo> & all_info)
AchievementsSlot::~AchievementsSlot()
{
deleteAchievements();
}
// ============================================================================
void AchievementsSlot::deleteAchievements()
{
std::map<uint32_t, Achievement *>::iterator it;
for ( it = m_achievements.begin(); it != m_achievements.end(); ++it ) {
delete it->second;
}
m_achievements.clear();
for(int i=0; i < all_info.size(); i++)
{
const AchievementInfo * info = all_info.get(i);
Achievement::AchievementType achievement_type = info->getType();
}
// ============================================================================
void AchievementsSlot::createFreshSlot()
{
deleteAchievements();
const std::map<uint32_t, AchievementInfo *> all_info = AchievementsManager::get()->getAllInfo();
std::map<uint32_t, AchievementInfo *>::const_iterator it;
for ( it = all_info.begin(); it != all_info.end(); ++it ) {
Achievement::AchievementType achievement_type = it->second->getType();
Achievement * achievement;
if(achievement_type == Achievement::AT_SINGLE)
{
achievement = new SingleAchievement(info);
achievement = new SingleAchievement(it->second);
}
else if(achievement_type == Achievement::AT_MAP)
{
achievement = new MapAchievement(info);
achievement = new MapAchievement(it->second);
}
m_achievements[achievement->getID()] = achievement;
}

View File

@ -36,7 +36,8 @@ private:
bool m_valid;
std::string m_id;
void createFreshSlot( const PtrVector<AchievementInfo> & info);
void createFreshSlot();
void deleteAchievements();
class SyncAchievementsRequest : public Online::XMLRequest {
virtual void callback ();
@ -45,8 +46,9 @@ private:
};
public :
AchievementsSlot(const XMLNode * input, const PtrVector<AchievementInfo> & info);
AchievementsSlot(std::string id, bool online, const PtrVector<AchievementInfo> & info);
AchievementsSlot(const XMLNode * input);
AchievementsSlot(std::string id, bool online);
~AchievementsSlot();
bool isValid() const { return m_valid;}
void save(std::ofstream & out);
bool isOnline() const {return m_online;}

View File

@ -1523,7 +1523,7 @@ int main(int argc, char *argv[] )
// Go straight to the race
StateManager::get()->enterGameState();
}
AchievementsManager::get();
AchievementsManager::get()->init();
// If an important news message exists it is shown in a popup dialog.

View File

@ -84,6 +84,13 @@ namespace Online
// ------------------------------------------------------------------------
irr::core::stringw fetchingAchievements()
{
return irr::core::stringw(_("Fetching achievements")) + loadingDots();
}
// ------------------------------------------------------------------------
irr::core::stringw processing()
{
return irr::core::stringw(_("Processing")) + loadingDots();

View File

@ -36,6 +36,7 @@ namespace Online
irr::core::stringw creatingServer ();
irr::core::stringw fetchingServers ();
irr::core::stringw fetchingFriends ();
irr::core::stringw fetchingAchievements ();
irr::core::stringw processing ();
irr::core::stringw signedInAs (const irr::core::stringw & name);
} // namespace Messages

View File

@ -0,0 +1,124 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/online_profile_achievements.hpp"
#include "achievements/achievements_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "utils/translation.hpp"
#include "online/messages.hpp"
#include <IGUIButton.h>
#include <iostream>
#include <sstream>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr::gui;
using namespace Online;
DEFINE_SCREEN_SINGLETON( OnlineProfileAchievements );
// -----------------------------------------------------------------------------
OnlineProfileAchievements::OnlineProfileAchievements() : OnlineProfileBase("online/profile_achievements.stkgui")
{
m_selected_achievement_index = -1;
} // OnlineProfileAchievements
// -----------------------------------------------------------------------------
void OnlineProfileAchievements::loadedFromFile()
{
OnlineProfileBase::loadedFromFile();
m_achievements_list_widget = getWidget<GUIEngine::ListWidget>("achievements_list");
assert(m_achievements_list_widget != NULL);
} // loadedFromFile
// ----------------------------------------------------------------------------
void OnlineProfileAchievements::beforeAddingWidget()
{
OnlineProfileBase::beforeAddingWidget();
m_achievements_list_widget->clearColumns();
m_achievements_list_widget->addColumn( _("Name"), 2 );
if(m_visiting_profile->isCurrentUser())
{
m_achievements_list_widget->addColumn( _("Progress"), 1 );
}
}
// -----------------------------------------------------------------------------
void OnlineProfileAchievements::init()
{
OnlineProfileBase::init();
m_profile_tabs->select( m_achievements_tab->m_properties[PROP_ID], PLAYER_ID_GAME_MASTER );
assert(m_visiting_profile != NULL);
if(m_visiting_profile->isCurrentUser())
{
//fill with local FIXME
}
else
{
m_visiting_profile->fetchAchievements();
m_waiting_for_achievements = true;
m_achievements_list_widget->clear();
m_achievements_list_widget->addItem("loading", Messages::fetchingAchievements());
}
} // init
// -----------------------------------------------------------------------------
void OnlineProfileAchievements::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
OnlineProfileBase::eventCallback( widget, name, playerID);
if (name == m_achievements_list_widget->m_properties[GUIEngine::PROP_ID])
{
m_selected_achievement_index = m_achievements_list_widget->getSelectionID();
//new achievementInfoDialog(atoi(m_achievements_list_widget->getSelectionInternalName().c_str())); //FIXME dialog
}
} // eventCallback
// ----------------------------------------------------------------------------
void OnlineProfileAchievements::onUpdate(float delta, irr::video::IVideoDriver* driver)
{
if(m_waiting_for_achievements)
{
if(m_visiting_profile->isReady())
{
m_achievements_list_widget->clear();
for(unsigned int i = 0; i < m_visiting_profile->getAchievements().size(); i++)
{
AchievementInfo * info = AchievementsManager::get()->getAchievementInfo(m_visiting_profile->getAchievements()[i]);
m_achievements_list_widget->addItem(StringUtils::toString(info->getID()), info->getTitle());
}
m_waiting_for_achievements = false;
}
else
{
m_achievements_list_widget->renameItem("loading", Messages::fetchingFriends());
}
}
}

View File

@ -0,0 +1,67 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// 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_ONLINE_PROFILE_ACHIEVEMENTS_HPP__
#define __HEADER_ONLINE_PROFILE_ACHIEVEMENTS_HPP__
#include <string>
#include <irrString.h>
#include "guiengine/screen.hpp"
#include "guiengine/widgets.hpp"
#include "states_screens/online_profile_base.hpp"
#include "online/profile_manager.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Online profiel overview screen
* \ingroup states_screens
*/
class OnlineProfileAchievements : public OnlineProfileBase, public GUIEngine::ScreenSingleton<OnlineProfileAchievements>
{
private:
OnlineProfileAchievements();
GUIEngine::ListWidget * m_achievements_list_widget;
int m_selected_achievement_index;
bool m_waiting_for_achievements;
public:
friend class GUIEngine::ScreenSingleton<OnlineProfileAchievements>;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
virtual void onUpdate(float delta, irr::video::IVideoDriver* driver) OVERRIDE;
virtual void beforeAddingWidget() OVERRIDE;
virtual void refreshAchievementsList() { m_waiting_for_achievements = true; }
};
#endif

View File

@ -25,6 +25,7 @@
#include "utils/translation.hpp"
#include "states_screens/online_profile_overview.hpp"
#include "states_screens/online_profile_friends.hpp"
#include "states_screens/online_profile_achievements.hpp"
#include <iostream>
#include <sstream>
@ -37,6 +38,7 @@ using namespace Online;
OnlineProfileBase::OnlineProfileBase(const char* filename) : Screen(filename)
{
m_visiting_profile = ProfileManager::get()->getVisitingProfile();
} // OnlineProfileBase
// -----------------------------------------------------------------------------
@ -52,19 +54,35 @@ void OnlineProfileBase::loadedFromFile()
assert(m_overview_tab != NULL);
m_friends_tab = (IconButtonWidget *) m_profile_tabs->findWidgetNamed("tab_friends");
assert(m_friends_tab != NULL);
m_achievements_tab = (IconButtonWidget *) m_profile_tabs->findWidgetNamed("tab_achievements");
assert(m_achievements_tab != NULL);
} // loadedFromFile
// -----------------------------------------------------------------------------
void OnlineProfileBase::beforeAddingWidget()
{
}
// -----------------------------------------------------------------------------
void OnlineProfileBase::init()
{
Profile * previous_profile = m_visiting_profile;
m_visiting_profile = ProfileManager::get()->getVisitingProfile();
if(previous_profile->isCurrentUser() != m_visiting_profile->isCurrentUser())
{
GUIEngine::reshowCurrentScreen();
return;
}
Screen::init();
m_overview_tab->setTooltip( _("Overview") );
m_friends_tab->setTooltip( _("Friends") );
m_achievements_tab->setTooltip( _("Achievements") );
m_visiting_profile = ProfileManager::get()->getVisitingProfile();
if (m_visiting_profile->isCurrentUser())
m_header->setText(_("Your profile"), false);
else
@ -82,6 +100,7 @@ void OnlineProfileBase::eventCallback(Widget* widget, const std::string& name, c
if (selection == m_overview_tab->m_properties[PROP_ID]) StateManager::get()->replaceTopMostScreen(OnlineProfileOverview::getInstance());
else if (selection == m_friends_tab->m_properties[PROP_ID]) StateManager::get()->replaceTopMostScreen(OnlineProfileFriends::getInstance());
else if (selection == m_achievements_tab->m_properties[PROP_ID]) StateManager::get()->replaceTopMostScreen(OnlineProfileAchievements::getInstance());
}
else if (name == "back")
{

View File

@ -24,13 +24,13 @@
#include "guiengine/screen.hpp"
#include "guiengine/widgets.hpp"
#include "online/profile.hpp"
#include "online/profile_manager.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Online profiel overview screen
* \brief Online profile base screen
* \ingroup states_screens
*/
class OnlineProfileBase : public GUIEngine::Screen
@ -41,6 +41,7 @@ protected:
GUIEngine::RibbonWidget* m_profile_tabs;
GUIEngine::IconButtonWidget * m_overview_tab;
GUIEngine::IconButtonWidget * m_friends_tab;
GUIEngine::IconButtonWidget * m_achievements_tab;
Online::Profile * m_visiting_profile;
@ -54,6 +55,8 @@ public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
virtual void beforeAddingWidget() OVERRIDE;
};
#endif

View File

@ -44,7 +44,6 @@ DEFINE_SCREEN_SINGLETON( OnlineProfileFriends );
OnlineProfileFriends::OnlineProfileFriends() : OnlineProfileBase("online/profile_friends.stkgui")
{
m_selected_friend_index = -1;
m_own_profile = true;
} // OnlineProfileFriends
// -----------------------------------------------------------------------------
@ -65,9 +64,10 @@ void OnlineProfileFriends::loadedFromFile()
void OnlineProfileFriends::beforeAddingWidget()
{
OnlineProfileBase::beforeAddingWidget();
m_friends_list_widget->clearColumns();
m_friends_list_widget->addColumn( _("Username"), 2 );
if(m_own_profile)
if(m_visiting_profile->isCurrentUser())
{
m_friends_list_widget->addColumn( _("Since"), 1 );
m_friends_list_widget->addColumn( _("Status"), 2 );
@ -79,12 +79,6 @@ void OnlineProfileFriends::beforeAddingWidget()
void OnlineProfileFriends::init()
{
OnlineProfileBase::init();
if(m_own_profile != m_visiting_profile->isCurrentUser())
{
m_own_profile = m_visiting_profile->isCurrentUser();
GUIEngine::reshowCurrentScreen();
return;
}
m_profile_tabs->select( m_friends_tab->m_properties[PROP_ID], PLAYER_ID_GAME_MASTER );
assert(m_visiting_profile != NULL);
m_visiting_profile->fetchFriends();

View File

@ -46,8 +46,6 @@ private:
int m_selected_friend_index;
bool m_waiting_for_friends;
bool m_own_profile;
bool m_refresh_screen;
public:
friend class GUIEngine::ScreenSingleton<OnlineProfileFriends>;