Merge pull request #1252 from mcsab/master

Reset-per-lap achievement support
This commit is contained in:
Unitraxx 2014-03-22 01:12:28 +01:00
commit c647fa5081
10 changed files with 70 additions and 27 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<achievements> <achievements>
<achievement id="1" check-type="all-at-least" reset-after-race="no" <achievement id="1" check-type="all-at-least" reset-type="never"
title="Christoffel Columbus" description="Play every official track at least once." > title="Christoffel Columbus" description="Play every official track at least once." >
<farm goal="1"/> <farm goal="1"/>
<scotland goal="1"/> <scotland goal="1"/>
@ -13,36 +13,35 @@
<hacienda goal="1"/> <hacienda goal="1"/>
<jungle goal="1"/> <jungle goal="1"/>
</achievement> </achievement>
<achievement id="2" check-type="all-at-least" reset-after-race="no" <achievement id="2" check-type="all-at-least" reset-type="never"
title="Strike!" description="Hit 10 karts with a bowling-ball."> title="Strike!" description="Hit 10 karts with a bowling-ball.">
<ball goal="10"/> <ball goal="10"/>
</achievement> </achievement>
<achievement id="3" check-type="one-at-least" reset-after-race="yes" <achievement id="3" check-type="one-at-least" reset-type="race"
title="Arch Enemy" description="Hit the same kart at least 5 times in one race"> title="Arch Enemy" description="Hit the same kart at least 5 times in one race">
<hit goal="5"/> <hit goal="5"/>
</achievement> </achievement>
<achievement id="4" check-type="all-at-least" reset-after-race="yes" <achievement id="4" check-type="all-at-least" reset-type="race"
title="Marathoner" description="Make a race with 5 laps or more"> title="Marathoner" description="Make a race with 5 laps or more">
<laps goal="5"/> <laps goal="5"/>
</achievement> </achievement>
<achievement id="5" check-type="all-at-least" reset-after-race="yes" <achievement id="5" check-type="all-at-least" reset-type="lap"
title="Skid-row" description="Make 5 skidding in a single race"> title="Skid-row" description="Make 5 skidding in a single lap">
<skidding goal="5"/> <skidding goal="5"/>
</achievement> </achievement>
<achievement id="6" check-type="all-at-least" reset-after-race="no" <achievement id="6" check-type="all-at-least" reset-type="never"
title="Gold driver" description="Win in all single player modes, against at least 3 opponents."> title="Gold driver" description="Win in all single player modes, against at least 3 opponents.">
<standard goal="1"/> <standard goal="1"/>
<std_timetrial goal="1"/> <std_timetrial goal="1"/>
<follow_leader goal="1"/> <follow_leader goal="1"/>
<opponents goal="3"/> <opponents goal="3"/>
</achievement> </achievement>
<achievement id="7" check-type="all-at-least" reset-after-race="yes" <achievement id="7" check-type="all-at-least" reset-type="race"
title="Powerup Love" description="Use 10 or more powerups in a race"> title="Powerup Love" description="Use 10 or more powerups in a race">
<poweruplover goal="10"/> <poweruplover goal="10"/>
</achievement> </achievement>
<achievement id="8" check-type="all-at-least" reset-after-race="no" <achievement id="8" check-type="all-at-least" reset-type="never"
title="Unstoppable" description="Win 5 single races in a row"> title="Unstoppable" description="Win 5 single races in a row">
<wins goal="5"/> <wins goal="5"/>
</achievement> </achievement>
</achievements> </achievements>

View File

@ -179,6 +179,15 @@ void Achievement::onRaceEnd()
reset(); reset();
} // onRaceEnd } // onRaceEnd
// ----------------------------------------------------------------------------
/** Called at the end of a lap to potentially reset values.
*/
void Achievement::onLapEnd()
{
if (m_achievement_info->needsResetAfterLap())
reset();
} // onLapEnd
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Checks if this achievement has been achieved. /** Checks if this achievement has been achieved.
*/ */

View File

@ -70,6 +70,7 @@ public:
virtual void reset(); virtual void reset();
virtual irr::core::stringw getProgressAsString() const; virtual irr::core::stringw getProgressAsString() const;
void onRaceEnd(); void onRaceEnd();
void onLapEnd();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the id of this achievement. */ /** Returns the id of this achievement. */
uint32_t getID() const { return m_id; } uint32_t getID() const { return m_id; }

View File

@ -31,7 +31,7 @@
*/ */
AchievementInfo::AchievementInfo(const XMLNode * input) AchievementInfo::AchievementInfo(const XMLNode * input)
{ {
m_reset_after_race = false; m_reset_type = NEVER;
m_id = 0; m_id = 0;
m_title = ""; m_title = "";
m_description = ""; m_description = "";
@ -47,10 +47,20 @@ AchievementInfo::AchievementInfo(const XMLNode * input)
"ID %d title '%s' description '%s'", m_id, m_title.c_str(), "ID %d title '%s' description '%s'", m_id, m_title.c_str(),
m_description.c_str()); m_description.c_str());
} }
input->get("reset-after-race", &m_reset_after_race);
m_check_type = AC_ALL_AT_LEAST; // Load the reset-type
std::string s; std::string s;
input->get("reset-type", &s);
if (s == "race")
m_reset_type = AFTER_RACE;
else if (s == "lap")
m_reset_type = AFTER_LAP;
else if (s != "never")
Log::warn("AchievementInfo", "Achievement check type '%s' unknown.",
s.c_str());
// Load check-type
m_check_type = AC_ALL_AT_LEAST;
input->get("check-type", &s); input->get("check-type", &s);
if (s == "all-at-least") if (s == "all-at-least")
m_check_type = AC_ALL_AT_LEAST; m_check_type = AC_ALL_AT_LEAST;

View File

@ -61,6 +61,17 @@ public:
AC_ALL_AT_LEAST, AC_ALL_AT_LEAST,
AC_ONE_AT_LEAST AC_ONE_AT_LEAST
}; };
/** Achievement reset type:
* AFTER_LAP: Achievement needs to be reset after each lap.
* AFTER_RACE: Achievement needs to be reset after each race.
* NEVER: Achievement does not need to be reset
*/
enum ResetType
{
AFTER_LAP = 1,
AFTER_RACE = 2,
NEVER = 3
};
private: private:
/** The id of this Achievement. */ /** The id of this Achievement. */
@ -78,8 +89,8 @@ private:
/** The target values needed to be reached. */ /** The target values needed to be reached. */
std::map<std::string, int> m_goal_values; std::map<std::string, int> m_goal_values;
/** True if the achievement needs to be reset after each race. */ /** Determines when the achievement needs to be reset */
bool m_reset_after_race; ResetType m_reset_type;
public: public:
AchievementInfo(const XMLNode * input); AchievementInfo(const XMLNode * input);
@ -99,7 +110,9 @@ public:
/** Returns the title of this achievement. */ /** Returns the title of this achievement. */
irr::core::stringw getTitle() const { return m_title; } irr::core::stringw getTitle() const { return m_title; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool needsResetAfterRace() const { return m_reset_after_race; } bool needsResetAfterRace() const { return m_reset_type == AFTER_RACE; }
// ------------------------------------------------------------------------
bool needsResetAfterLap() const { return m_reset_type == AFTER_LAP; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the check type for this achievement. */ /** Returns the check type for this achievement. */
AchievementCheckType getCheckType() const { return m_check_type; } AchievementCheckType getCheckType() const { return m_check_type; }

View File

@ -95,14 +95,6 @@ AchievementsStatus*
return status; return status;
} // createAchievementStatus } // createAchievementStatus
// ----------------------------------------------------------------------------
void AchievementsManager::onRaceEnd()
{
//reset all values that need to be reset
PlayerManager::get()->getCurrentPlayer()
->getAchievementsStatus()->onRaceEnd();
} // onRaceEnd
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AchievementInfo * AchievementsManager::getAchievementInfo(uint32_t id) const AchievementInfo * AchievementsManager::getAchievementInfo(uint32_t id) const
{ {

View File

@ -71,7 +71,6 @@ public:
} // destroy } // destroy
// ======================================================================== // ========================================================================
void onRaceEnd();
AchievementInfo* getAchievementInfo(uint32_t id) const; AchievementInfo* getAchievementInfo(uint32_t id) const;
AchievementsStatus* createAchievementsStatus(const XMLNode *node=NULL); AchievementsStatus* createAchievementsStatus(const XMLNode *node=NULL);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -132,3 +132,12 @@ void AchievementsStatus::onRaceEnd()
iter->second->onRaceEnd(); iter->second->onRaceEnd();
} }
} // onRaceEnd } // onRaceEnd
void AchievementsStatus::onLapEnd()
{
//reset all values that need to be reset
std::map<uint32_t, Achievement *>::iterator iter;
for (iter = m_achievements.begin(); iter != m_achievements.end(); ++iter) {
iter->second->onLapEnd();
}
} // onLapEnd

View File

@ -60,6 +60,7 @@ public :
void add(Achievement *achievement); void add(Achievement *achievement);
void sync(const std::vector<uint32_t> & achieved_ids); void sync(const std::vector<uint32_t> & achieved_ids);
void onRaceEnd(); void onRaceEnd();
void onLapEnd();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
const std::map<uint32_t, Achievement *>& getAllAchievements() const std::map<uint32_t, Achievement *>& getAllAchievements()
{ {

View File

@ -17,6 +17,8 @@
#include "modes/linear_world.hpp" #include "modes/linear_world.hpp"
#include "achievements/achievements_manager.hpp"
#include "config/player_manager.hpp"
#include "audio/music_manager.hpp" #include "audio/music_manager.hpp"
#include "audio/sfx_base.hpp" #include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp" #include "audio/sfx_manager.hpp"
@ -236,6 +238,14 @@ void LinearWorld::newLap(unsigned int kart_index)
KartInfo &kart_info = m_kart_info[kart_index]; KartInfo &kart_info = m_kart_info[kart_index];
AbstractKart *kart = m_karts[kart_index]; AbstractKart *kart = m_karts[kart_index];
// Reset reset-after-lap achievements
StateManager::ActivePlayer *c = kart->getController()->getPlayer();
PlayerProfile *p = PlayerManager::get()->getCurrentPlayer();
if (c && c->getConstProfile() == p)
{
p->getAchievementsStatus()->onLapEnd();
}
// Only update the kart controller if a kart that has already finished // Only update the kart controller if a kart that has already finished
// the race crosses the start line again. This avoids 'fastest lap' // the race crosses the start line again. This avoids 'fastest lap'
// messages if the end controller does a fastest lap, but especially // messages if the end controller does a fastest lap, but especially