Removed Single and MapAchievent (and Singe/MapAchievementInfo), instead
using the generic key-value mapping Map* has provided for everything. Changed format of achievements.xml to be more compact.
This commit is contained in:
parent
b4099b5354
commit
5fc300d7bb
@ -1,17 +1,19 @@
|
|||||||
<?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="farm" goal="1"/>
|
<farm goal="1"/>
|
||||||
<entry key="scotland" goal="1"/>
|
<scotland goal="1"/>
|
||||||
<entry key="lighthouse" goal="1"/>
|
<lighthouse goal="1"/>
|
||||||
<entry key="sandtrack" goal="1"/>
|
<sandtrack goal="1"/>
|
||||||
<entry key="olivermath" goal="1"/>
|
<olivermath goal="1"/>
|
||||||
<entry key="subsea" goal="1"/>
|
<subsea goal="1"/>
|
||||||
<entry key="mansion" goal="1"/>
|
<mansion goal="1"/>
|
||||||
<entry key="minigolf" goal="1"/>
|
<minigolf goal="1"/>
|
||||||
<entry key="hacienda" goal="1"/>
|
<hacienda goal="1"/>
|
||||||
<entry key="jungle" goal="1"/>
|
<jungle goal="1"/>
|
||||||
|
</achievement>
|
||||||
|
<achievement id="2" type="single" title="Strike!" description="Hit 10 karts with a bowling-ball.">
|
||||||
|
<ball goal="10"/>
|
||||||
</achievement>
|
</achievement>
|
||||||
<achievement id="2" type="single" goal="10" title="Strike!" description="Hit 10 karts with a bowling-ball." />
|
|
||||||
</achievements>
|
</achievements>
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
// Copyright (C) 2013 Glenn De Jonghe
|
// Copyright (C) 2013-2014 Glenn De Jonghe
|
||||||
|
// 2014 Joerg Henrichs
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
@ -26,17 +27,15 @@
|
|||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
#include "utils/translation.hpp"
|
#include "utils/translation.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/** Constructur, initialises this object with the data from the
|
||||||
|
* corresponding AchievementInfo.
|
||||||
|
*/
|
||||||
Achievement::Achievement(const AchievementInfo * info)
|
Achievement::Achievement(const AchievementInfo * info)
|
||||||
:m_achievement_info(info)
|
: m_achievement_info(info)
|
||||||
{
|
{
|
||||||
m_id = info->getID();
|
m_id = info->getID();
|
||||||
m_achieved = false;
|
m_achieved = false;
|
||||||
} // Achievement
|
} // Achievement
|
||||||
|
|
||||||
@ -52,6 +51,15 @@ void Achievement::load(const XMLNode *node)
|
|||||||
{
|
{
|
||||||
node->get("id", &m_id );
|
node->get("id", &m_id );
|
||||||
node->get("achieved", &m_achieved);
|
node->get("achieved", &m_achieved);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < node->getNumNodes(); i++)
|
||||||
|
{
|
||||||
|
const XMLNode *n = node->getNode(i);
|
||||||
|
std::string key = n->getName();
|
||||||
|
int value = 0;
|
||||||
|
n->get("value", &value);
|
||||||
|
m_progress_map[key] = value;
|
||||||
|
}
|
||||||
} // load
|
} // load
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -62,16 +70,88 @@ void Achievement::save(UTFWriter &out)
|
|||||||
{
|
{
|
||||||
out << L" <achievement id=\"" << m_id << L"\" "
|
out << L" <achievement id=\"" << m_id << L"\" "
|
||||||
<< L"achieved=\"" << m_achieved << "\"";
|
<< L"achieved=\"" << m_achieved << "\"";
|
||||||
|
if (isAchieved())
|
||||||
|
{
|
||||||
|
out << "/>\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << ">\n";
|
||||||
|
std::map<std::string, int>::iterator i;
|
||||||
|
for (i = m_progress_map.begin(); i != m_progress_map.end(); ++i)
|
||||||
|
{
|
||||||
|
out << " <" << i->first
|
||||||
|
<< " value=\"" << i->second << "\"/>\n";
|
||||||
|
}
|
||||||
|
out << " </achievement>\n";
|
||||||
} // save
|
} // save
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Returns the value for a key.
|
||||||
|
*/
|
||||||
|
int Achievement::getValue(const std::string & key)
|
||||||
|
{
|
||||||
|
if (m_progress_map.find(key) != m_progress_map.end())
|
||||||
|
return m_progress_map[key];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Resets all currently key values to 0. Called if the reset-after-race flag
|
||||||
|
* is set for the corresponding AchievementInfo.
|
||||||
|
*/
|
||||||
|
void Achievement::reset()
|
||||||
|
{
|
||||||
|
std::map<std::string, int>::iterator iter;
|
||||||
|
for (iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter)
|
||||||
|
{
|
||||||
|
iter->second = 0;
|
||||||
|
}
|
||||||
|
} // reset
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Returns how much of an achievement has been achieved in the form n/m.
|
||||||
|
* The AchievementInfo adds up all goal values to get 'm', and this
|
||||||
|
* this class end up all current key values for 'n'.
|
||||||
|
*/
|
||||||
|
irr::core::stringw Achievement::getProgressAsString()
|
||||||
|
{
|
||||||
|
int progress = 0;
|
||||||
|
std::map<std::string, int>::const_iterator iter;
|
||||||
|
for (iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter)
|
||||||
|
{
|
||||||
|
progress += iter->second;
|
||||||
|
}
|
||||||
|
return StringUtils::toWString(progress) + "/" + getInfo()->toString();
|
||||||
|
} // getProgressAsString
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Increases the value of a key by a specified amount.
|
||||||
|
* \param key The key whose value is increased.
|
||||||
|
* \param increase Amount to add to the value of this key.
|
||||||
|
*/
|
||||||
|
void Achievement::increase(const std::string & key, int increase)
|
||||||
|
{
|
||||||
|
if (m_progress_map.find(key) != m_progress_map.end())
|
||||||
|
{
|
||||||
|
m_progress_map[key] += increase;
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_progress_map[key] = increase;
|
||||||
|
} // increase
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Called at the end of a race to potentially reset values.
|
||||||
|
*/
|
||||||
void Achievement::onRaceEnd()
|
void Achievement::onRaceEnd()
|
||||||
{
|
{
|
||||||
if(m_achievement_info->needsResetAfterRace())
|
if(m_achievement_info->needsResetAfterRace())
|
||||||
this->reset();
|
reset();
|
||||||
}
|
} // onRaceEnd
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Checks if this achievement has been achieved.
|
||||||
|
*/
|
||||||
void Achievement::check()
|
void Achievement::check()
|
||||||
{
|
{
|
||||||
if(m_achieved)
|
if(m_achieved)
|
||||||
@ -88,161 +168,5 @@ void Achievement::check()
|
|||||||
Online::CurrentUser::get()->onAchieving(m_id);
|
Online::CurrentUser::get()->onAchieving(m_id);
|
||||||
m_achieved = true;
|
m_achieved = true;
|
||||||
}
|
}
|
||||||
}
|
} // check
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Constructor for a SingleAchievement.
|
|
||||||
*/
|
|
||||||
SingleAchievement::SingleAchievement(const AchievementInfo * info)
|
|
||||||
: Achievement(info)
|
|
||||||
{
|
|
||||||
m_progress = 0;
|
|
||||||
m_achieved = false;
|
|
||||||
} // SingleAchievement
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Loads the state from an xml node.
|
|
||||||
* \param node The XML data.
|
|
||||||
*/
|
|
||||||
void SingleAchievement::load(const XMLNode *node)
|
|
||||||
{
|
|
||||||
Achievement::load(node);
|
|
||||||
if (!isAchieved())
|
|
||||||
node->get("progress", &m_progress);
|
|
||||||
} // load
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Save the state to a file. The progress is only saved if the achievement
|
|
||||||
* has not been achieved yet.
|
|
||||||
* \param out The output file.
|
|
||||||
*/
|
|
||||||
void SingleAchievement::save(UTFWriter &out)
|
|
||||||
{
|
|
||||||
Achievement::save(out);
|
|
||||||
if (!m_achieved)
|
|
||||||
{
|
|
||||||
out << L" progress=\"" << m_progress << L"\"";
|
|
||||||
}
|
|
||||||
out << L"/>\n";
|
|
||||||
} // save
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Resets the challenge. Calls if necessary (i.e. if a challenge needs to
|
|
||||||
* be fulfilled in a single race).
|
|
||||||
*/
|
|
||||||
void SingleAchievement::reset()
|
|
||||||
{
|
|
||||||
m_progress = 0;
|
|
||||||
} // reset
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Adds a value to this counter.
|
|
||||||
* \param increase Value to add.
|
|
||||||
*/
|
|
||||||
void SingleAchievement::increase(int increase)
|
|
||||||
{
|
|
||||||
m_progress += increase;
|
|
||||||
check();
|
|
||||||
} // increase
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Returns a "k/n" string indicating how much of an achievement was achieved.
|
|
||||||
*/
|
|
||||||
irr::core::stringw SingleAchievement::getProgressAsString()
|
|
||||||
{
|
|
||||||
// The info class returns the goal value
|
|
||||||
return StringUtils::toWString(m_progress) + "/"
|
|
||||||
+getInfo()->toString();
|
|
||||||
} // getProgressAsString
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
/** Constructor for a MapAchievement.
|
|
||||||
*/
|
|
||||||
MapAchievement::MapAchievement(const AchievementInfo * info)
|
|
||||||
: Achievement(info)
|
|
||||||
{
|
|
||||||
} // MapAchievement
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Loads the status from an XML node.
|
|
||||||
* \param node The XML data to load the status from.
|
|
||||||
*/
|
|
||||||
void MapAchievement::load(const XMLNode *node)
|
|
||||||
{
|
|
||||||
Achievement::load(node);
|
|
||||||
for (unsigned int i = 0; i < node->getNumNodes(); i++)
|
|
||||||
{
|
|
||||||
const XMLNode *n = node->getNode(i);
|
|
||||||
std::string key = n->getName();
|
|
||||||
int value = 0;
|
|
||||||
n->get("value", &value);
|
|
||||||
m_progress_map[key] = value;
|
|
||||||
}
|
|
||||||
} // load
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Saves the status of this achievement to a file.
|
|
||||||
* \param out The file to write the state to.
|
|
||||||
*/
|
|
||||||
void MapAchievement::save(UTFWriter &out)
|
|
||||||
{
|
|
||||||
Achievement::save(out);
|
|
||||||
if (isAchieved())
|
|
||||||
{
|
|
||||||
out << "/>\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
out << ">\n";
|
|
||||||
std::map<std::string, int>::iterator i;
|
|
||||||
for (i = m_progress_map.begin(); i != m_progress_map.end(); ++i)
|
|
||||||
{
|
|
||||||
out << " <" << i->first
|
|
||||||
<< " value=\"" << i->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
void MapAchievement::reset()
|
|
||||||
{
|
|
||||||
std::map<std::string, int>::iterator iter;
|
|
||||||
for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter )
|
|
||||||
{
|
|
||||||
iter->second = 0;
|
|
||||||
}
|
|
||||||
} // reset
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
void MapAchievement::increase(const std::string & key, int increase)
|
|
||||||
{
|
|
||||||
if (m_progress_map.find(key) != m_progress_map.end())
|
|
||||||
{
|
|
||||||
m_progress_map[key] += increase;
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_progress_map[key] = increase;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
irr::core::stringw MapAchievement::getProgressAsString()
|
|
||||||
{
|
|
||||||
int progress = 0;
|
|
||||||
std::map<std::string, int>::const_iterator iter;
|
|
||||||
for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter)
|
|
||||||
{
|
|
||||||
progress += iter->second;
|
|
||||||
}
|
|
||||||
return StringUtils::toWString(progress) + "/" + getInfo()->toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -30,40 +30,45 @@ class UTFWriter;
|
|||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/** This is the base class for any achievement. It allows achievement status
|
/** This is the base class for any achievement. It allows achievement status
|
||||||
* to be saved, and detects when an achievement is fulfilled.
|
* to be saved, and detects when an achievement is fulfilled. It provides
|
||||||
|
* storage for state information by a generic key-value mapping. The values
|
||||||
|
* are stored as strings, but can be used to store numerical values. E.g.
|
||||||
|
* you can call increase("key", 10) for an achievement, which will convert
|
||||||
|
* the string to int, add 10, then convert the result back to string for
|
||||||
|
* storage.
|
||||||
* \ingroup achievements
|
* \ingroup achievements
|
||||||
*/
|
*/
|
||||||
class AchievementInfo;
|
class AchievementInfo;
|
||||||
|
|
||||||
class Achievement
|
class Achievement
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
/** The id of this achievement. */
|
/** The id of this achievement. */
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
|
|
||||||
/** True if this achievement has been achieved. */
|
/** True if this achievement has been achieved. */
|
||||||
bool m_achieved;
|
bool m_achieved;
|
||||||
|
|
||||||
|
/** The map of key-value pairs. */
|
||||||
|
std::map<std::string, int> m_progress_map;
|
||||||
|
|
||||||
/** A pointer to the corresponding AchievementInfo instance. */
|
/** A pointer to the corresponding AchievementInfo instance. */
|
||||||
const AchievementInfo *m_achievement_info;
|
const AchievementInfo *m_achievement_info;
|
||||||
|
|
||||||
void check();
|
void check();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum AchievementType
|
|
||||||
{
|
|
||||||
AT_SINGLE,
|
|
||||||
AT_MAP
|
|
||||||
};
|
|
||||||
|
|
||||||
Achievement(const AchievementInfo * info);
|
Achievement(const AchievementInfo * info);
|
||||||
virtual ~Achievement ();
|
virtual ~Achievement();
|
||||||
virtual void load (const XMLNode *node) ;
|
virtual void load(const XMLNode *node);
|
||||||
virtual void save (UTFWriter &out) ;
|
virtual void save(UTFWriter &out);
|
||||||
virtual void reset () = 0;
|
virtual int getValue(const std::string & key);
|
||||||
virtual irr::core::stringw getProgressAsString() = 0;
|
void increase(const std::string & key, int increase = 1);
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
virtual irr::core::stringw getProgressAsString();
|
||||||
void onRaceEnd();
|
void onRaceEnd();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the id of this achievement. */
|
/** Returns the id of this achievement. */
|
||||||
@ -79,54 +84,3 @@ public:
|
|||||||
bool isAchieved() const { return m_achieved; }
|
bool isAchieved() const { return m_achieved; }
|
||||||
|
|
||||||
}; // class Achievement
|
}; // class Achievement
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
/** This is a base class for an achievement that counts how often an event
|
|
||||||
* happened, and triggers the achievement to be fulfilled when a certain
|
|
||||||
* goal value is reached.
|
|
||||||
* \ingroup achievements
|
|
||||||
*/
|
|
||||||
class SingleAchievement : public Achievement
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int m_progress;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SingleAchievement (const AchievementInfo * info);
|
|
||||||
virtual ~SingleAchievement () {};
|
|
||||||
|
|
||||||
void load (const XMLNode *node);
|
|
||||||
int getValue () const { return m_progress; }
|
|
||||||
void save (UTFWriter &out);
|
|
||||||
void increase (int increase = 1);
|
|
||||||
void reset ();
|
|
||||||
virtual irr::core::stringw getProgressAsString ();
|
|
||||||
}; // class SingleAchievement
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
/** This achievement can keep track of a set of key-value pairs. Fulfillment is
|
|
||||||
* triggered when all values defined in the data/achievements.xml file have
|
|
||||||
* been reached.
|
|
||||||
* \ingroup achievements
|
|
||||||
*/
|
|
||||||
class MapAchievement : public Achievement
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
/** The map of key-value pairs. */
|
|
||||||
std::map<std::string, int> m_progress_map;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MapAchievement (const AchievementInfo * info);
|
|
||||||
virtual ~MapAchievement () {};
|
|
||||||
|
|
||||||
void load (const XMLNode *node);
|
|
||||||
int getValue (const std::string & key);
|
|
||||||
void increase (const std::string & key, int increase = 1);
|
|
||||||
void save (UTFWriter &out);
|
|
||||||
void reset ();
|
|
||||||
virtual irr::core::stringw getProgressAsString ();
|
|
||||||
}; // class MapAchievement
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*EOF*/
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
// Copyright (C) 2013 Glenn De Jonghe
|
// Copyright (C) 2013-2014 Glenn De Jonghe
|
||||||
|
// 2014 Joerg Henrichs
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
@ -45,49 +46,23 @@ AchievementInfo::AchievementInfo(const XMLNode * input)
|
|||||||
m_description.c_str());
|
m_description.c_str());
|
||||||
}
|
}
|
||||||
input->get("reset-after-race", &m_reset_after_race);
|
input->get("reset-after-race", &m_reset_after_race);
|
||||||
} // AchievementInfo
|
|
||||||
|
|
||||||
// ============================================================================
|
// Now load the goal nodes
|
||||||
SingleAchievementInfo::SingleAchievementInfo(const XMLNode * input)
|
for (unsigned int n = 0; n < input->getNumNodes(); n++)
|
||||||
: AchievementInfo(input)
|
|
||||||
{
|
|
||||||
input->get("goal", &m_goal_value);
|
|
||||||
} // SingleAchievementInfo
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
irr::core::stringw SingleAchievementInfo::toString() const
|
|
||||||
{
|
|
||||||
return StringUtils::toWString(m_goal_value);
|
|
||||||
} // toString
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
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("");
|
const XMLNode *node = input->getNode(n);
|
||||||
xml_entries[n]->get("key", &key);
|
std::string key = node->getName();
|
||||||
int goal(0);
|
int goal = 0;
|
||||||
xml_entries[n]->get("goal", &goal);
|
node->get("goal", &goal);
|
||||||
m_goal_values[key] = goal;
|
m_goal_values[key] = goal;
|
||||||
}
|
}
|
||||||
if(m_goal_values.size() != xml_entries.size())
|
if (m_goal_values.size() != input->getNumNodes())
|
||||||
Log::error("MapAchievementInfo","Duplicate keys for the entries of a MapAchievement found.");
|
Log::error("MapAchievementInfo",
|
||||||
}
|
"Duplicate keys for the entries of a MapAchievement found.");
|
||||||
|
} // AchievementInfo
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
irr::core::stringw MapAchievementInfo::toString() const
|
irr::core::stringw AchievementInfo::toString() const
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::map<std::string, int>::const_iterator iter;
|
std::map<std::string, int>::const_iterator iter;
|
||||||
@ -96,10 +71,11 @@ irr::core::stringw MapAchievementInfo::toString() const
|
|||||||
count += iter->second;
|
count += iter->second;
|
||||||
}
|
}
|
||||||
return StringUtils::toWString(count);
|
return StringUtils::toWString(count);
|
||||||
|
|
||||||
} // toString
|
} // toString
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
bool MapAchievementInfo::checkCompletion(Achievement * achievement) const
|
bool AchievementInfo::checkCompletion(Achievement * achievement) const
|
||||||
{
|
{
|
||||||
MapAchievement * map_achievement = (MapAchievement *) achievement;
|
MapAchievement * map_achievement = (MapAchievement *) achievement;
|
||||||
std::map<std::string, int>::const_iterator iter;
|
std::map<std::string, int>::const_iterator iter;
|
||||||
@ -110,3 +86,4 @@ bool MapAchievementInfo::checkCompletion(Achievement * achievement) const
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
//
|
//
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
// Copyright (C) 2013 Glenn De Jonghe
|
// Copyright (C) 2013-2014 Glenn De Jonghe
|
||||||
|
// 2014 Joerg Henrichs
|
||||||
|
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
@ -38,7 +40,13 @@ class Achievement;
|
|||||||
*/
|
*/
|
||||||
class AchievementInfo
|
class AchievementInfo
|
||||||
{
|
{
|
||||||
protected:
|
public:
|
||||||
|
/** Achievement types:
|
||||||
|
* SINGLE_AT_LEAST: a single value, which must at least be the
|
||||||
|
* goal value.
|
||||||
|
*/
|
||||||
|
enum AchievementType { AT_SINGLE_AT_LEAST};
|
||||||
|
private:
|
||||||
/** The id of this Achievement. */
|
/** The id of this Achievement. */
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
|
|
||||||
@ -48,15 +56,20 @@ protected:
|
|||||||
/** The description of this achievement. */
|
/** The description of this achievement. */
|
||||||
irr::core::stringw m_description;
|
irr::core::stringw m_description;
|
||||||
|
|
||||||
|
AchievementType m_type;
|
||||||
|
|
||||||
|
/** The target values needed to be reached. */
|
||||||
|
std::map<std::string, int> m_goal_values;
|
||||||
|
|
||||||
/** True if the achievement needs to be reset after each race. */
|
/** True if the achievement needs to be reset after each race. */
|
||||||
bool m_reset_after_race;
|
bool m_reset_after_race;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AchievementInfo (const XMLNode * input);
|
AchievementInfo (const XMLNode * input);
|
||||||
virtual ~AchievementInfo () {};
|
virtual ~AchievementInfo () {};
|
||||||
virtual Achievement::AchievementType getType() const = 0;
|
virtual AchievementType getType() const { return m_type; }
|
||||||
virtual irr::core::stringw toString() const = 0;
|
virtual irr::core::stringw toString() const;
|
||||||
virtual bool checkCompletion(Achievement * achievement) const = 0;
|
virtual bool checkCompletion(Achievement * achievement) const;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the id of this achievement. */
|
/** Returns the id of this achievement. */
|
||||||
@ -72,61 +85,6 @@ public:
|
|||||||
}; // class AchievementInfo
|
}; // class AchievementInfo
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
/** This class stores the information about an achievement that count a
|
|
||||||
* single value.
|
|
||||||
*/
|
|
||||||
class SingleAchievementInfo : public AchievementInfo
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/** Which value must be reached in order to achieve this achievement. */
|
|
||||||
int m_goal_value;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SingleAchievementInfo(const XMLNode * input);
|
|
||||||
virtual ~SingleAchievementInfo() {};
|
|
||||||
virtual irr::core::stringw toString() const;
|
|
||||||
virtual bool checkCompletion(Achievement * achievement) const;
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
int getGoalValue() const { return m_goal_value; }
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
virtual Achievement::AchievementType getType() const
|
|
||||||
{
|
|
||||||
return Achievement::AT_SINGLE;
|
|
||||||
} // getType
|
|
||||||
}; // class SingleAchievementInfo
|
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
/** This class stores a set of key-value pairs.
|
|
||||||
*/
|
|
||||||
class MapAchievementInfo : public AchievementInfo
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/** The target values needed to be reached. */
|
|
||||||
std::map<std::string, int> m_goal_values;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MapAchievementInfo(const XMLNode * input);
|
|
||||||
virtual ~MapAchievementInfo() {};
|
|
||||||
virtual bool checkCompletion(Achievement * achievement) const;
|
|
||||||
virtual irr::core::stringw toString() const;
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
int getGoalValue(const std::string & key) { return m_goal_values[key]; }
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
const std::map<std::string, int> & getGoalValues() const
|
|
||||||
{
|
|
||||||
return m_goal_values;
|
|
||||||
} // getGoalValues
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
virtual Achievement::AchievementType getType() const
|
|
||||||
{
|
|
||||||
return Achievement::AT_MAP;
|
|
||||||
} // getType
|
|
||||||
|
|
||||||
}; // class MapAchievementInfo
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*EOF*/
|
/*EOF*/
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
// Copyright (C) 2013 Glenn De Jonghe
|
// Copyright (C) 2013-2014 Glenn De Jonghe
|
||||||
|
// 2014 Joerg Henrichs
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
@ -69,11 +70,11 @@ void AchievementsManager::parseAssetFile()
|
|||||||
AchievementInfo * achievement_info;
|
AchievementInfo * achievement_info;
|
||||||
if(type == "single")
|
if(type == "single")
|
||||||
{
|
{
|
||||||
achievement_info = new SingleAchievementInfo(node);
|
achievement_info = new AchievementInfo(node);
|
||||||
}
|
}
|
||||||
else if(type == "map")
|
else if(type == "map")
|
||||||
{
|
{
|
||||||
achievement_info = new MapAchievementInfo(node);
|
achievement_info = new AchievementInfo(node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -107,16 +108,9 @@ AchievementsStatus*
|
|||||||
for (it = m_achievements_info.begin();
|
for (it = m_achievements_info.begin();
|
||||||
it != m_achievements_info.end(); ++it)
|
it != m_achievements_info.end(); ++it)
|
||||||
{
|
{
|
||||||
Achievement::AchievementType achievement_type = it->second->getType();
|
AchievementInfo::AchievementType achievement_type = it->second->getType();
|
||||||
Achievement * achievement;
|
Achievement * achievement;
|
||||||
if (achievement_type == Achievement::AT_SINGLE)
|
achievement = new Achievement(it->second);
|
||||||
{
|
|
||||||
achievement = new SingleAchievement(it->second);
|
|
||||||
}
|
|
||||||
else if (achievement_type == Achievement::AT_MAP)
|
|
||||||
{
|
|
||||||
achievement = new MapAchievement(it->second);
|
|
||||||
}
|
|
||||||
status->add(achievement);
|
status->add(achievement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,9 @@ class AchievementsStatus;
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/** This class manages the list of all achievements. It reads the
|
||||||
* \brief Class that takes care of online profiles
|
* data/achievements.xml file, which contains the conditions for
|
||||||
|
* each achievement.
|
||||||
* \ingroup online
|
* \ingroup online
|
||||||
*/
|
*/
|
||||||
class AchievementsManager
|
class AchievementsManager
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
// Copyright (C) 2013 Glenn De Jonghe
|
// Copyright (C) 2013-2014 Glenn De Jonghe
|
||||||
|
// 2014 Joerg Henrichs
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
@ -34,6 +35,8 @@
|
|||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Constructor for an Achievement.
|
||||||
|
*/
|
||||||
AchievementsStatus::AchievementsStatus()
|
AchievementsStatus::AchievementsStatus()
|
||||||
{
|
{
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
@ -41,9 +44,15 @@ AchievementsStatus::AchievementsStatus()
|
|||||||
} // AchievementsStatus
|
} // AchievementsStatus
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Removes all achievements.
|
||||||
|
*/
|
||||||
AchievementsStatus::~AchievementsStatus()
|
AchievementsStatus::~AchievementsStatus()
|
||||||
{
|
{
|
||||||
deleteAchievements();
|
std::map<uint32_t, Achievement *>::iterator it;
|
||||||
|
for (it = m_achievements.begin(); it != m_achievements.end(); ++it) {
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
m_achievements.clear();
|
||||||
} // ~AchievementsStatus
|
} // ~AchievementsStatus
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -80,11 +89,6 @@ void AchievementsStatus::add(Achievement *achievement)
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void AchievementsStatus::deleteAchievements()
|
void AchievementsStatus::deleteAchievements()
|
||||||
{
|
{
|
||||||
std::map<uint32_t, Achievement *>::iterator it;
|
|
||||||
for ( it = m_achievements.begin(); it != m_achievements.end(); ++it ) {
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
m_achievements.clear();
|
|
||||||
} // deleteAchievements
|
} // deleteAchievements
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
// Copyright (C) 2013 Glenn De Jonghe
|
// Copyright (C) 2013-2014 Glenn De Jonghe
|
||||||
|
// 2014 Joerg Henrichs
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
@ -30,6 +31,13 @@
|
|||||||
class UTFWriter;
|
class UTFWriter;
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
|
||||||
|
/** This class keeps tracks of all achievements of one player. One instance
|
||||||
|
* of this class is stored in each PlayerProfile. It stores a map of
|
||||||
|
* achievements ids to instances of Achievement. Each achievement in
|
||||||
|
* turn stores either fulfilled achievements, or the current state of
|
||||||
|
* an achievement (e.g. an achievement to race every track in STK needs
|
||||||
|
* to keep information about which tracks have already been used.)
|
||||||
|
*/
|
||||||
class AchievementsStatus
|
class AchievementsStatus
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -37,8 +45,6 @@ private:
|
|||||||
bool m_online;
|
bool m_online;
|
||||||
bool m_valid;
|
bool m_valid;
|
||||||
|
|
||||||
void deleteAchievements();
|
|
||||||
|
|
||||||
class SyncAchievementsRequest : public Online::XMLRequest {
|
class SyncAchievementsRequest : public Online::XMLRequest {
|
||||||
virtual void callback ();
|
virtual void callback ();
|
||||||
public:
|
public:
|
||||||
|
@ -44,9 +44,9 @@ class XMLNode;
|
|||||||
* the actual data about the challenge. The ChallengeStatus stores if the
|
* the actual data about the challenge. The ChallengeStatus stores if the
|
||||||
* challenge is not possible yet (inactive), active (i.e. user can try to
|
* challenge is not possible yet (inactive), active (i.e. user can try to
|
||||||
* solve it), or solved. This status is stored for each difficulty level.
|
* solve it), or solved. This status is stored for each difficulty level.
|
||||||
* This data is saved to and loaded from the player.xml file.
|
* This data is saved to and loaded from the players.xml file.
|
||||||
* A PlayerProfile will store an array of ChallengeStatuses, one for each
|
* A StoryModeStatus instance will store an array of ChallengeStatuses,
|
||||||
* Challenge in STK.
|
* one for each Challenge in STK.
|
||||||
*
|
*
|
||||||
* \ingroup challenges
|
* \ingroup challenges
|
||||||
*/
|
*/
|
||||||
|
@ -35,9 +35,12 @@ class XMLNode;
|
|||||||
|
|
||||||
const int CHALLENGE_POINTS[] = { 8, 9, 10 };
|
const int CHALLENGE_POINTS[] = { 8, 9, 10 };
|
||||||
|
|
||||||
/**
|
/** This class contains the progression through challenges for the story mode.
|
||||||
|
* It maintains a list of all challenges in a mapping of challenge id to
|
||||||
|
* an instance of ChallengeStatus. Each ChallengeStatus stores at which level
|
||||||
|
* a challenge was solved.
|
||||||
|
* This object also keeps track of the overall points a player has.
|
||||||
* \ingroup challenges
|
* \ingroup challenges
|
||||||
* This class contains the progression through challenges for the story mode.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class StoryModeStatus
|
class StoryModeStatus
|
||||||
|
@ -30,7 +30,11 @@
|
|||||||
class AchievementsStatus;
|
class AchievementsStatus;
|
||||||
class PlayerProfile;
|
class PlayerProfile;
|
||||||
|
|
||||||
/** A special class that manages all local player accounts.
|
/** A special class that manages all local player accounts. It reads all player
|
||||||
|
* accounts from the players.xml file in the user config directory. It also
|
||||||
|
* keeps track of the currently logged in player. For each player an instance
|
||||||
|
* of PlayerProfile is created, which keeps track of story mode progress,
|
||||||
|
* achievements and other data.
|
||||||
*/
|
*/
|
||||||
class PlayerManager : public NoCopy
|
class PlayerManager : public NoCopy
|
||||||
{
|
{
|
||||||
|
@ -32,12 +32,13 @@ using namespace irr;
|
|||||||
class UTFWriter;
|
class UTFWriter;
|
||||||
class AchievementsStatus;
|
class AchievementsStatus;
|
||||||
|
|
||||||
/**
|
/** Class for managing player profiles (name, usage frequency,
|
||||||
* \brief Class for managing player profiles (name, control configuration, etc.)
|
* etc.). All PlayerProfiles are managed by the PlayerManager.
|
||||||
* A list of all possible players is stored as PlayerProfiles in the user config.
|
* A PlayerProfile keeps track of the story mode progress using an instance
|
||||||
* A list of currently playing players will be stored somewhere else (FIXME : complete comment)
|
* of StoryModeStatus, and achievements with AchievementsStatus. All data
|
||||||
* \ingroup config
|
* is saved in the players.xml file.
|
||||||
*/
|
* \ingroup config
|
||||||
|
*/
|
||||||
class PlayerProfile : public NoCopy
|
class PlayerProfile : public NoCopy
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -263,7 +263,7 @@ void Physics::update(float dt)
|
|||||||
{
|
{
|
||||||
AchievementsStatus* status =
|
AchievementsStatus* status =
|
||||||
PlayerManager::getCurrentAchievementsStatus();
|
PlayerManager::getCurrentAchievementsStatus();
|
||||||
((SingleAchievement *) status->getAchievement(2))->increase(1);
|
status->getAchievement(2)->increase("ball", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user