Lots of additions to achievements! core almost done.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13616 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
e21ef8d40b
commit
91e77a14c3
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<achievements>
|
<achievements>
|
||||||
<achievement id="1" type="map" title="Christoffel Columbus" description="Play every official track at least once." >
|
<achievement id="1" type="map" title="Christoffel Columbus" description="Play every official track at least once." >
|
||||||
<entry key="mapid1" />
|
<entry key="mapid1" goal="1"/>
|
||||||
<entry key="mapid2" />
|
<entry key="mapid2" goal="1"/>
|
||||||
</achievement>
|
</achievement>
|
||||||
<achievement id="2" type="single" goal="1" title="Strike!" description="Hit a kart with a bowling-ball." />
|
<achievement id="2" type="single" goal="1" title="Strike!" description="Hit a kart with a bowling-ball." />
|
||||||
</achievements>
|
</achievements>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
# Generated by ./update_file_list.sh. Do not edit this file manually.
|
# Generated by ./update_file_list.sh. Do not edit this file manually.
|
||||||
set(STK_SOURCES
|
set(STK_SOURCES
|
||||||
src/achievements/achievement.cpp
|
src/achievements/achievement.cpp
|
||||||
|
src/achievements/achievement_info.cpp
|
||||||
src/achievements/achievements_manager.cpp
|
src/achievements/achievements_manager.cpp
|
||||||
|
src/achievements/achievements_slot.cpp
|
||||||
src/addons/addon.cpp
|
src/addons/addon.cpp
|
||||||
src/addons/addons_manager.cpp
|
src/addons/addons_manager.cpp
|
||||||
src/addons/inetwork_http.cpp
|
src/addons/inetwork_http.cpp
|
||||||
@ -296,7 +298,9 @@ src/utils/vec3.cpp
|
|||||||
)
|
)
|
||||||
set(STK_HEADERS
|
set(STK_HEADERS
|
||||||
src/achievements/achievement.hpp
|
src/achievements/achievement.hpp
|
||||||
|
src/achievements/achievement_info.hpp
|
||||||
src/achievements/achievements_manager.hpp
|
src/achievements/achievements_manager.hpp
|
||||||
|
src/achievements/achievements_slot.hpp
|
||||||
src/addons/addon.hpp
|
src/addons/addon.hpp
|
||||||
src/addons/addons_manager.hpp
|
src/addons/addons_manager.hpp
|
||||||
src/addons/dummy_network_http.hpp
|
src/addons/dummy_network_http.hpp
|
||||||
|
@ -29,9 +29,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
Achievement::Achievement(const XMLNode * input)
|
Achievement::Achievement(AchievementInfo * info)
|
||||||
{
|
{
|
||||||
input->get("id", &m_id);
|
m_id = info->getID();
|
||||||
m_achieved = false;
|
m_achieved = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,9 +42,12 @@ Achievement::~Achievement()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
void Achievement::onAchieving()
|
void Achievement::check()
|
||||||
{
|
{
|
||||||
if(!m_achieved)
|
if(m_achieved)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(m_achievement_info->checkCompletion(this))
|
||||||
{
|
{
|
||||||
//show achievement
|
//show achievement
|
||||||
//send to server
|
//send to server
|
||||||
@ -53,38 +56,77 @@ void Achievement::onAchieving()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
SingleAchievement::SingleAchievement(const XMLNode * input)
|
SingleAchievement::SingleAchievement(AchievementInfo * info)
|
||||||
: Achievement(input)
|
: Achievement(info)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
void SingleAchievement::check()
|
void SingleAchievement::load(XMLNode * input)
|
||||||
{
|
{
|
||||||
if(m_achieved)
|
std::string achieved("");
|
||||||
return;
|
input->get("achieved", &achieved);
|
||||||
if(m_progress >= m_goal)
|
if(achieved == "true")
|
||||||
onAchieving();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
MapAchievement::MapAchievement(const XMLNode * input)
|
|
||||||
: Achievement(input)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
void MapAchievement::check()
|
|
||||||
{
|
|
||||||
if(m_achieved)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ProgressMap::iterator iter;
|
|
||||||
for (iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
if (!iter->second)
|
m_achieved = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onAchieving();
|
input->get("value", &m_progress);
|
||||||
}
|
}
|
||||||
|
// ============================================================================
|
||||||
|
void SingleAchievement::save(std::ofstream & out)
|
||||||
|
{
|
||||||
|
out << "<achievement id=\"" << m_id << "\""
|
||||||
|
<< "achieved=\"" << StringUtils::boolstr(m_achieved) << "\""
|
||||||
|
<< "value=\"" << StringUtils::toString(m_progress) << "\""
|
||||||
|
<< "/>\n";
|
||||||
|
} // save
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
MapAchievement::MapAchievement(AchievementInfo * info)
|
||||||
|
: Achievement(info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
void MapAchievement::load(XMLNode * input)
|
||||||
|
{
|
||||||
|
std::string achieved("");
|
||||||
|
input->get("achieved", &achieved);
|
||||||
|
if(achieved == "true")
|
||||||
|
{
|
||||||
|
m_achieved = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<XMLNode*> xml_entries;
|
||||||
|
input->getNodes("entry", xml_entries);
|
||||||
|
for (unsigned int n=0; n < xml_entries.size(); n++)
|
||||||
|
{
|
||||||
|
std::string key("");
|
||||||
|
xml_entries[n]->get("key", &key);
|
||||||
|
int value(0);
|
||||||
|
xml_entries[n]->get("value", &value);
|
||||||
|
m_progress_map[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
void MapAchievement::save(std::ofstream & out)
|
||||||
|
{
|
||||||
|
out << "<achievement id=\"" << m_id << "\" achieved=\"" << StringUtils::boolstr(m_achieved) << "\">\n";
|
||||||
|
std::map<std::string, int>::iterator iter;
|
||||||
|
for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) {
|
||||||
|
out << " <entry key=\"" << iter->first.c_str() << "\" value=\"" << StringUtils::toString(iter->second) << "\"/>\n";
|
||||||
|
}
|
||||||
|
out << "</achievement>\n";
|
||||||
|
} // save
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
int MapAchievement::getValue(const std::string & key)
|
||||||
|
{
|
||||||
|
if ( m_progress_map.find(key) != m_progress_map.end())
|
||||||
|
return m_progress_map[key];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <irrString.h>
|
#include <irrString.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "io/xml_node.hpp"
|
#include "io/xml_node.hpp"
|
||||||
|
#include "achievements/achievement_info.hpp"
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -32,43 +33,58 @@
|
|||||||
* \brief
|
* \brief
|
||||||
* \ingroup
|
* \ingroup
|
||||||
*/
|
*/
|
||||||
|
class AchievementInfo;
|
||||||
|
|
||||||
class Achievement
|
class Achievement
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
bool m_achieved;
|
bool m_achieved;
|
||||||
virtual void check() = 0;
|
AchievementInfo * m_achievement_info;
|
||||||
void onAchieving();
|
void check ();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Achievement (const XMLNode * input);
|
Achievement (AchievementInfo * info);
|
||||||
virtual ~Achievement ();
|
virtual ~Achievement ();
|
||||||
uint32_t getID() const { return m_id; }
|
uint32_t getID () const { return m_id; }
|
||||||
|
virtual void load (XMLNode * input) = 0;
|
||||||
|
virtual void save (std::ofstream & out) = 0;
|
||||||
|
|
||||||
|
enum AchievementType
|
||||||
|
{
|
||||||
|
AT_SINGLE,
|
||||||
|
AT_MAP
|
||||||
|
};
|
||||||
|
|
||||||
}; // class Achievement
|
}; // class Achievement
|
||||||
|
|
||||||
class SingleAchievement : public Achievement
|
class SingleAchievement : public Achievement
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
virtual void check();
|
|
||||||
int m_goal;
|
|
||||||
int m_progress;
|
int m_progress;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SingleAchievement (const XMLNode * input);
|
SingleAchievement (AchievementInfo * info);
|
||||||
virtual ~SingleAchievement () {};
|
virtual ~SingleAchievement () {};
|
||||||
}; // class Achievement
|
|
||||||
|
void load (XMLNode * input);
|
||||||
|
int getValue () const { return m_progress; }
|
||||||
|
void save (std::ofstream & out);
|
||||||
|
}; // class SingleAchievement
|
||||||
|
|
||||||
class MapAchievement : public Achievement
|
class MapAchievement : public Achievement
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
virtual void check();
|
std::map<std::string, int> m_progress_map;
|
||||||
typedef std::map<std::string, bool> ProgressMap;
|
|
||||||
ProgressMap m_progress_map;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MapAchievement (const XMLNode * input);
|
MapAchievement (AchievementInfo * info);
|
||||||
virtual ~MapAchievement () {};
|
virtual ~MapAchievement () {};
|
||||||
}; // class Achievement
|
|
||||||
|
void load (XMLNode * input);
|
||||||
|
int getValue (const std::string & key);
|
||||||
|
void save (std::ofstream & out);
|
||||||
|
}; // class MapAchievement
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
87
src/achievements/achievement_info.cpp
Normal file
87
src/achievements/achievement_info.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
//
|
||||||
|
// 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 "achievements/achievement_info.hpp"
|
||||||
|
|
||||||
|
#include "utils/log.hpp"
|
||||||
|
#include "utils/translation.hpp"
|
||||||
|
#include "io/xml_writer.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
AchievementInfo::AchievementInfo(const XMLNode * input)
|
||||||
|
{
|
||||||
|
input->get("id", &m_id);
|
||||||
|
input->get("title", &m_title);
|
||||||
|
input->get("description", &m_description);
|
||||||
|
|
||||||
|
std::string reset_after_race("");
|
||||||
|
input->get("reset_after_race", &reset_after_race);
|
||||||
|
m_reset_after_race = reset_after_race == "true";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
SingleAchievementInfo::SingleAchievementInfo(const XMLNode * input)
|
||||||
|
: AchievementInfo(input)
|
||||||
|
{
|
||||||
|
input->get("goal", &m_goal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
bool SingleAchievementInfo::checkCompletion(Achievement * achievement) const
|
||||||
|
{
|
||||||
|
SingleAchievement * single_achievement = (SingleAchievement *) achievement;
|
||||||
|
if(single_achievement->getValue() >= m_goal_value)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
MapAchievementInfo::MapAchievementInfo(const XMLNode * input)
|
||||||
|
: AchievementInfo(input)
|
||||||
|
{
|
||||||
|
std::vector<XMLNode*> xml_entries;
|
||||||
|
input->getNodes("entry", xml_entries);
|
||||||
|
for (unsigned int n=0; n < xml_entries.size(); n++)
|
||||||
|
{
|
||||||
|
std::string key("");
|
||||||
|
xml_entries[n]->get("key", &key);
|
||||||
|
int goal(0);
|
||||||
|
xml_entries[n]->get("goal", &goal);
|
||||||
|
m_goal_values[key] = goal;
|
||||||
|
}
|
||||||
|
if(m_goal_values.size() != xml_entries.size())
|
||||||
|
Log::error("MapAchievementInfo","Duplicate keys for the entries of a MapAchievement found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
bool MapAchievementInfo::checkCompletion(Achievement * achievement) const
|
||||||
|
{
|
||||||
|
MapAchievement * map_achievement = (MapAchievement *) achievement;
|
||||||
|
std::map<std::string, int>::iterator iter;
|
||||||
|
for ( iter = m_goal_values.begin(); iter != m_goal_values.end(); iter++ ) {
|
||||||
|
if(map_achievement->getValue(iter->first) < iter->second)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
85
src/achievements/achievement_info.hpp
Normal file
85
src/achievements/achievement_info.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
//
|
||||||
|
// 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_ACHIEVEMENT_INFO_HPP
|
||||||
|
#define HEADER_ACHIEVEMENT_INFO_HPP
|
||||||
|
|
||||||
|
#include "utils/types.hpp"
|
||||||
|
|
||||||
|
#include <irrString.h>
|
||||||
|
#include <string>
|
||||||
|
#include "io/xml_node.hpp"
|
||||||
|
#include "achievements/achievement.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
class Achievement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief
|
||||||
|
* \ingroup
|
||||||
|
*/
|
||||||
|
class AchievementInfo
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint32_t m_id;
|
||||||
|
irr::core::stringw m_title;
|
||||||
|
irr::core::stringw m_description;
|
||||||
|
bool m_reset_after_race;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AchievementInfo (const XMLNode * input);
|
||||||
|
virtual ~AchievementInfo () {};
|
||||||
|
uint32_t getID () const { return m_id; }
|
||||||
|
irr::core::stringw getDescription () const { return m_description; }
|
||||||
|
virtual Achievement::AchievementType getType () = 0;
|
||||||
|
virtual bool checkCompletion (Achievement * achievement) const = 0;
|
||||||
|
}; // class AchievementInfo
|
||||||
|
|
||||||
|
class SingleAchievementInfo : public AchievementInfo
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
int m_goal_value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SingleAchievementInfo (const XMLNode * input);
|
||||||
|
virtual ~SingleAchievementInfo () {};
|
||||||
|
int getGoalValue () const { return m_goal_value; }
|
||||||
|
virtual bool checkCompletion (Achievement * achievement) const;
|
||||||
|
|
||||||
|
virtual Achievement::AchievementType getType() { return Achievement::AT_SINGLE; };
|
||||||
|
}; // class SingleAchievementInfo
|
||||||
|
|
||||||
|
class MapAchievementInfo : public AchievementInfo
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::map<std::string, int> m_goal_values;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MapAchievementInfo (const XMLNode * input);
|
||||||
|
virtual ~MapAchievementInfo () {};
|
||||||
|
int getGoalValue (const std::string & key) { return m_goal_values[key];}
|
||||||
|
virtual bool checkCompletion (Achievement * achievement) const;
|
||||||
|
|
||||||
|
virtual Achievement::AchievementType getType() { return Achievement::AT_MAP; };
|
||||||
|
}; // class MapAchievementInfo
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*EOF*/
|
@ -18,11 +18,12 @@
|
|||||||
|
|
||||||
#include "achievements/achievements_manager.hpp"
|
#include "achievements/achievements_manager.hpp"
|
||||||
|
|
||||||
#include "achievements/achievement.hpp"
|
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
#include "utils/translation.hpp"
|
#include "utils/translation.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "io/xml_writer.hpp"
|
#include "io/xml_writer.hpp"
|
||||||
|
#include "config/player.hpp"
|
||||||
|
#include "config/user_config.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -46,7 +47,8 @@ void AchievementsManager::deallocate()
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
AchievementsManager::AchievementsManager()
|
AchievementsManager::AchievementsManager()
|
||||||
{
|
{
|
||||||
parse();
|
parseDataFile();
|
||||||
|
parseConfigFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -55,15 +57,110 @@ AchievementsManager::~AchievementsManager()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
void AchievementsManager::parse()
|
void AchievementsManager::parseDataFile()
|
||||||
{
|
{
|
||||||
|
const std::string file_name = file_manager->getDataFile("achievements.xml");
|
||||||
|
const XMLNode *root = file_manager->createXMLTree(file_name);
|
||||||
|
unsigned int num_nodes = root->getNumNodes();
|
||||||
|
for(unsigned int i = 0; i < num_nodes; i++)
|
||||||
|
{
|
||||||
|
const XMLNode *node = root->getNode(i);
|
||||||
|
std::string type("");
|
||||||
|
node->get("type", &type);
|
||||||
|
AchievementInfo * achievement_info;
|
||||||
|
if(type == "single")
|
||||||
|
{
|
||||||
|
achievement_info = new SingleAchievementInfo(node);
|
||||||
|
}
|
||||||
|
else if(type == "map")
|
||||||
|
{
|
||||||
|
achievement_info = new MapAchievementInfo(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::error("AchievementsManager::parseAchievements","Non-existent achievement type. Skipping - definitely results in unwanted behaviour.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_achievements_info.push_back(achievement_info);
|
||||||
|
}
|
||||||
|
if(num_nodes != m_achievements_info.size())
|
||||||
|
Log::error("AchievementsManager::parseAchievements","Multiple achievements with the same id!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
void AchievementsManager::load()
|
void AchievementsManager::parseConfigFile()
|
||||||
{
|
{
|
||||||
|
const std::string filename=file_manager->getConfigFile("achievements.xml");
|
||||||
|
XMLNode* root = file_manager->createXMLTree(filename);
|
||||||
|
if(!root || root->getName() != "achievements")
|
||||||
|
{
|
||||||
|
Log::info("AchievementsManager", "Achievements file '%s' will be created.",
|
||||||
|
filename.c_str());
|
||||||
|
createSlotsIfNeeded();
|
||||||
|
save();
|
||||||
|
|
||||||
|
if (root) delete root;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<XMLNode*> xml_slots;
|
||||||
|
root->getNodes("slot", xml_slots);
|
||||||
|
for (unsigned int n=0; n < xml_slots.size(); n++)
|
||||||
|
{
|
||||||
|
AchievementsSlot * slot = new AchievementsSlot(xml_slots[n]);
|
||||||
|
if(!slot->isValid())
|
||||||
|
{
|
||||||
|
Log::warn("AchievementsManager", "Found game slot with faulty or missing information. Discarding it.");
|
||||||
|
delete slot;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_slots.push_back(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool something_changed = createSlotsIfNeeded();
|
||||||
|
if (something_changed) save();
|
||||||
|
|
||||||
|
delete root;
|
||||||
|
} // load
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Creates a slot for players that don't have one yet
|
||||||
|
* \return true if any were created
|
||||||
|
*/
|
||||||
|
bool AchievementsManager::createSlotsIfNeeded()
|
||||||
|
{
|
||||||
|
bool something_changed = false;
|
||||||
|
|
||||||
|
// make sure all players have at least one game slot associated
|
||||||
|
PtrVector<PlayerProfile>& players = UserConfigParams::m_all_players;
|
||||||
|
for (int n=0; n<players.size(); n++)
|
||||||
|
{
|
||||||
|
bool exists = false;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < m_slots.size(); i++)
|
||||||
|
{
|
||||||
|
if(!m_slots[i]->isOnline() && m_slots[i]->getID() == players[n].getUniqueID())
|
||||||
|
{
|
||||||
|
exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exists)
|
||||||
|
{
|
||||||
|
AchievementsSlot* slot = new AchievementsSlot(players[n].getUniqueID(), false);
|
||||||
|
m_slots.push_back(slot);
|
||||||
|
something_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return something_changed;
|
||||||
|
} // UnlockManager::createSlotsIfNeeded
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
void AchievementsManager::save()
|
void AchievementsManager::save()
|
||||||
{
|
{
|
||||||
@ -84,54 +181,10 @@ void AchievementsManager::save()
|
|||||||
|
|
||||||
for (unsigned int i = 0; i < m_slots.size(); i++)
|
for (unsigned int i = 0; i < m_slots.size(); i++)
|
||||||
{
|
{
|
||||||
m_slots[i].save();
|
m_slots[i]->save(achievements_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
achievements_file << "</achievements>\n\n";
|
achievements_file << "</achievements>\n\n";
|
||||||
achievements_file.close();
|
achievements_file.close();
|
||||||
}
|
}
|
||||||
// ============================================================================
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
void AchievementsManager::AchievementsSlot::parse()
|
|
||||||
{
|
|
||||||
const std::string file_name = file_manager->getDataFile("achievements.xml");
|
|
||||||
const XMLNode *root = file_manager->createXMLTree(file_name);
|
|
||||||
unsigned int num_nodes = root->getNumNodes();
|
|
||||||
for(unsigned int i = 0; i < num_nodes; i++)
|
|
||||||
{
|
|
||||||
const XMLNode *node = root->getNode(i);
|
|
||||||
std::string type("");
|
|
||||||
node->get("type", &type);
|
|
||||||
Achievement * achievement;
|
|
||||||
if(type == "single")
|
|
||||||
{
|
|
||||||
achievement = new SingleAchievement(node);
|
|
||||||
}
|
|
||||||
else if(type == "map")
|
|
||||||
{
|
|
||||||
achievement = new MapAchievement(node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log::error("AchievementsManager::parseAchievements","Non-existent achievement type. Skipping - definitely results in unwanted behaviour.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_achievements[achievement->getID()] = achievement;
|
|
||||||
}
|
|
||||||
if(num_nodes != m_achievements.size())
|
|
||||||
Log::error("AchievementsManager::parseAchievements","Multiple achievements with the same id!");
|
|
||||||
} // parseAchievements
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
void AchievementsManager::AchievementsSlot::load()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
void AchievementsManager::AchievementsSlot::save()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
#define HEADER_ACHIEVEMENTS_MANAGER_HPP
|
#define HEADER_ACHIEVEMENTS_MANAGER_HPP
|
||||||
|
|
||||||
#include "utils/types.hpp"
|
#include "utils/types.hpp"
|
||||||
#include "achievements/achievement.hpp"
|
#include "achievements/achievement_info.hpp"
|
||||||
|
#include "achievements/achievements_slot.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <irrString.h>
|
#include <irrString.h>
|
||||||
@ -38,29 +39,22 @@
|
|||||||
class AchievementsManager
|
class AchievementsManager
|
||||||
{
|
{
|
||||||
private :
|
private :
|
||||||
|
std::vector<AchievementsSlot*> m_slots;
|
||||||
class AchievementsSlot
|
std::vector<AchievementInfo *> m_achievements_info;
|
||||||
{
|
|
||||||
std::map<uint32_t, Achievement *> m_achievements;
|
|
||||||
public :
|
|
||||||
void parse();
|
|
||||||
void load();
|
|
||||||
void save();
|
|
||||||
};
|
|
||||||
std::vector<AchievementsSlot> m_slots;
|
|
||||||
AchievementsManager ();
|
AchievementsManager ();
|
||||||
~AchievementsManager ();
|
~AchievementsManager ();
|
||||||
|
bool createSlotsIfNeeded();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**Singleton */
|
/**Singleton */
|
||||||
static AchievementsManager * get();
|
static AchievementsManager * get();
|
||||||
static void deallocate();
|
static void deallocate();
|
||||||
|
|
||||||
void parse();
|
const std::vector<AchievementInfo *> & getAllInfo() const { return m_achievements_info;};
|
||||||
|
|
||||||
|
void parseDataFile();
|
||||||
|
void parseConfigFile();
|
||||||
void save();
|
void save();
|
||||||
void load();
|
|
||||||
}; // class AchievementsManager
|
}; // class AchievementsManager
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
115
src/achievements/achievements_slot.cpp
Normal file
115
src/achievements/achievements_slot.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// 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 "achievements/achievements_slot.hpp"
|
||||||
|
|
||||||
|
#include "achievements/achievement_info.hpp"
|
||||||
|
#include "achievements/achievements_manager.hpp"
|
||||||
|
#include "utils/log.hpp"
|
||||||
|
#include "utils/translation.hpp"
|
||||||
|
#include "io/xml_writer.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
// ============================================================================
|
||||||
|
AchievementsSlot::AchievementsSlot(const XMLNode * input)
|
||||||
|
{
|
||||||
|
int fetched_user_id = input->get("user_id", &m_id);
|
||||||
|
std::string online;
|
||||||
|
int fetched_online = input->get("online", &online);
|
||||||
|
if(!fetched_user_id || !fetched_online || !(online == "true" || online == "false"))
|
||||||
|
{
|
||||||
|
m_valid = false;
|
||||||
|
}
|
||||||
|
m_valid = true;
|
||||||
|
m_online = online == "true";
|
||||||
|
|
||||||
|
createFreshSlot();
|
||||||
|
|
||||||
|
std::vector<XMLNode*> xml_achievements;
|
||||||
|
input->getNodes("achievement", xml_achievements);
|
||||||
|
for( unsigned int i=0; i<xml_achievements.size(); i++)
|
||||||
|
{
|
||||||
|
uint32_t achievement_id(0);
|
||||||
|
xml_achievements[i]->get("id", &achievement_id);
|
||||||
|
Achievement * achievement = findAchievement(achievement_id);
|
||||||
|
if(achievement == NULL)
|
||||||
|
{
|
||||||
|
Log::warn("AchievementsSlot", "Found saved achievement data for a non-existent achievement. Discarding.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
achievement->load(xml_achievements[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
AchievementsSlot::AchievementsSlot(std::string id, bool online)
|
||||||
|
{
|
||||||
|
m_valid = true;
|
||||||
|
m_online = online;
|
||||||
|
m_id = id;
|
||||||
|
|
||||||
|
createFreshSlot();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
void AchievementsSlot::createFreshSlot()
|
||||||
|
{
|
||||||
|
m_achievements.clear();
|
||||||
|
std::vector<AchievementInfo *> all_info = AchievementsManager::get()->getAllInfo();
|
||||||
|
for( unsigned int i=0; i < all_info.size(); i++)
|
||||||
|
{
|
||||||
|
AchievementInfo * info = all_info[i];
|
||||||
|
Achievement::AchievementType achievement_type = info->getType();
|
||||||
|
Achievement * achievement;
|
||||||
|
if(achievement_type == Achievement::AT_SINGLE)
|
||||||
|
{
|
||||||
|
achievement = new SingleAchievement(info);
|
||||||
|
}
|
||||||
|
else if(achievement_type == Achievement::AT_MAP)
|
||||||
|
{
|
||||||
|
achievement = new MapAchievement(info);
|
||||||
|
}
|
||||||
|
m_achievements[achievement->getID()] = achievement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
void AchievementsSlot::save(std::ofstream & out)
|
||||||
|
{
|
||||||
|
out << " <slot user_id=\"" << m_id.c_str()
|
||||||
|
<< "\" online=\"" << StringUtils::boolstr(m_online)
|
||||||
|
<< "\"> \n";
|
||||||
|
std::map<uint32_t, Achievement*>::const_iterator i;
|
||||||
|
for(i = m_achievements.begin(); i != m_achievements.end(); i++)
|
||||||
|
{
|
||||||
|
if (i->second != NULL)
|
||||||
|
i->second->save(out);
|
||||||
|
}
|
||||||
|
out << " </slot>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
Achievement * AchievementsSlot::findAchievement(uint32_t id)
|
||||||
|
{
|
||||||
|
if ( m_achievements.find(id) != m_achievements.end())
|
||||||
|
return m_achievements[id];
|
||||||
|
return NULL;
|
||||||
|
}
|
52
src/achievements/achievements_slot.hpp
Normal file
52
src/achievements/achievements_slot.hpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// 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_ACHIEVEMENTS_SLOT_HPP
|
||||||
|
#define HEADER_ACHIEVEMENTS_SLOT_HPP
|
||||||
|
|
||||||
|
#include "utils/types.hpp"
|
||||||
|
#include "achievements/achievement.hpp"
|
||||||
|
|
||||||
|
#include <irrString.h>
|
||||||
|
#include <string>
|
||||||
|
#include "io/xml_node.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
class AchievementsSlot
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<uint32_t, Achievement *> m_achievements;
|
||||||
|
bool m_online;
|
||||||
|
bool m_valid;
|
||||||
|
std::string m_id;
|
||||||
|
|
||||||
|
void createFreshSlot();
|
||||||
|
|
||||||
|
public :
|
||||||
|
AchievementsSlot(const XMLNode * input);
|
||||||
|
AchievementsSlot(std::string id, bool online);
|
||||||
|
bool isValid() const { return m_valid;}
|
||||||
|
void save(std::ofstream & out);
|
||||||
|
bool isOnline() const {return m_online;}
|
||||||
|
const std::string & getID() const {return m_id;}
|
||||||
|
Achievement * findAchievement(uint32_t id);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*EOF*/
|
@ -90,17 +90,11 @@ void Challenge::setSolved(RaceManager::Difficulty d)
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
const char* boolstr(bool b)
|
|
||||||
{
|
|
||||||
return (b ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Challenge::save(std::ofstream& writer)
|
void Challenge::save(std::ofstream& writer)
|
||||||
{
|
{
|
||||||
writer << " <" << m_data->getId().c_str() << ">\n"
|
writer << " <" << m_data->getId().c_str() << ">\n"
|
||||||
<< " <easy solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_EASY)) << "\"/>\n"
|
<< " <easy solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_EASY)) << "\"/>\n"
|
||||||
<< " <medium solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_MEDIUM)) << "\"/>\n"
|
<< " <medium solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_MEDIUM)) << "\"/>\n"
|
||||||
<< " <hard solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_HARD)) << "\"/>\n"
|
<< " <hard solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_HARD)) << "\"/>\n"
|
||||||
<< " </" << m_data->getId().c_str() << ">\n";
|
<< " </" << m_data->getId().c_str() << ">\n";
|
||||||
} // save
|
} // save
|
||||||
|
@ -139,6 +139,7 @@
|
|||||||
#include <IEventReceiver.h>
|
#include <IEventReceiver.h>
|
||||||
|
|
||||||
#include "main_loop.hpp"
|
#include "main_loop.hpp"
|
||||||
|
#include "achievements/achievements_manager.hpp"
|
||||||
#include "addons/addons_manager.hpp"
|
#include "addons/addons_manager.hpp"
|
||||||
#include "addons/inetwork_http.hpp"
|
#include "addons/inetwork_http.hpp"
|
||||||
#include "addons/news_manager.hpp"
|
#include "addons/news_manager.hpp"
|
||||||
|
@ -413,6 +413,11 @@ namespace StringUtils
|
|||||||
|
|
||||||
/** Compute a simple hash of a string */
|
/** Compute a simple hash of a string */
|
||||||
unsigned int simpleHash(const char* input);
|
unsigned int simpleHash(const char* input);
|
||||||
|
|
||||||
|
const char* boolstr(bool b)
|
||||||
|
{
|
||||||
|
return (b ? "true" : "false");
|
||||||
|
}
|
||||||
} // namespace StringUtils
|
} // namespace StringUtils
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user