diff --git a/data/achievements.xml b/data/achievements.xml
index e77929894..f759c9fc6 100644
--- a/data/achievements.xml
+++ b/data/achievements.xml
@@ -33,8 +33,8 @@
-
+ name="Marathoner" description="Finish a race with at least twice the track's default lap number.">
+
diff --git a/src/achievements/achievements_status.cpp b/src/achievements/achievements_status.cpp
index ddd0d8cc5..4c3919189 100644
--- a/src/achievements/achievements_status.cpp
+++ b/src/achievements/achievements_status.cpp
@@ -140,13 +140,16 @@ void AchievementsStatus::load(const XMLNode * input)
xml_achievement_tracks[i]->get("won",&m_track_stats[j].race_won);
xml_achievement_tracks[i]->get("finished_reverse",&m_track_stats[j].race_finished_reverse);
xml_achievement_tracks[i]->get("finished_alone",&m_track_stats[j].race_finished_alone);
+ xml_achievement_tracks[i]->get("less_laps",&m_track_stats[j].less_laps);
+ xml_achievement_tracks[i]->get("more_laps",&m_track_stats[j].more_laps);
+ xml_achievement_tracks[i]->get("twice_laps",&m_track_stats[j].min_twice_laps);
xml_achievement_tracks[i]->get("egg_hunt_started",&m_track_stats[j].egg_hunt_started);
xml_achievement_tracks[i]->get("egg_hunt_finished",&m_track_stats[j].egg_hunt_finished);
track_found = true;
break;
}
}
- // Useful if, e.g. an addon track get deleted
+ // Useful if, e.g. an addon track gets deleted
if (!track_found)
{
TrackStats new_track;
@@ -156,6 +159,9 @@ void AchievementsStatus::load(const XMLNode * input)
xml_achievement_tracks[i]->get("won",&new_track.race_won);
xml_achievement_tracks[i]->get("finished_reverse",&new_track.race_finished_reverse);
xml_achievement_tracks[i]->get("finished_alone",&new_track.race_finished_alone);
+ xml_achievement_tracks[i]->get("less_laps",&new_track.less_laps);
+ xml_achievement_tracks[i]->get("more_laps",&new_track.more_laps);
+ xml_achievement_tracks[i]->get("twice_laps",&new_track.min_twice_laps);
xml_achievement_tracks[i]->get("egg_hunt_started",&new_track.egg_hunt_started);
xml_achievement_tracks[i]->get("egg_hunt_finished",&new_track.egg_hunt_finished);
@@ -201,6 +207,9 @@ void AchievementsStatus::save(UTFWriter &out)
out << " won=\"" << m_track_stats[n].race_won << "\"";
out << " finished_reverse=\"" << m_track_stats[n].race_finished_reverse << "\"";
out << " finished_alone=\"" << m_track_stats[n].race_finished_alone << "\"";
+ out << " less_laps=\"" << m_track_stats[n].less_laps << "\"";
+ out << " more_laps=\"" << m_track_stats[n].more_laps << "\"";
+ out << " twice_laps=\"" << m_track_stats[n].min_twice_laps << "\"";
out << " egg_hunt_started=\"" << m_track_stats[n].egg_hunt_started << "\"";
out << " egg_hunt_finished=\"" << m_track_stats[n].egg_hunt_finished << "\"";
out << "/>\n";
@@ -326,6 +335,24 @@ void AchievementsStatus::updateAchievementsProgress(unsigned int achieve_data_id
mosquito->increase("swatter", "swatter", m_variables[SWATTER_HIT_1RACE].counter);
}
+ Achievement *marathoner = PlayerManager::getCurrentAchievementsStatus()->getAchievement(AchievementInfo::ACHIEVE_MARATHONER);
+ if (!marathoner->isAchieved())
+ {
+ marathoner->reset();
+ for (unsigned int i=0;i= 1)
+ {
+ marathoner->increase("laps", "laps", 1);
+ break;
+ }
+ }
+ }
+
Achievement *columbus = PlayerManager::getCurrentAchievementsStatus()->getAchievement(AchievementInfo::ACHIEVE_COLUMBUS);
if (!columbus->isAchieved())
{
@@ -443,6 +470,12 @@ void AchievementsStatus::trackEvent(std::string track_ident, AchievementsStatus:
m_track_stats[track_id].race_finished_reverse++;
else if (event==TR_FINISHED_ALONE)
m_track_stats[track_id].race_finished_alone++;
+ else if (event==TR_LESS_LAPS)
+ m_track_stats[track_id].less_laps++;
+ else if (event==TR_MORE_LAPS)
+ m_track_stats[track_id].more_laps++;
+ else if (event==TR_MIN_TWICE_LAPS)
+ m_track_stats[track_id].min_twice_laps++;
else if (event==TR_EGG_HUNT_STARTED)
m_track_stats[track_id].egg_hunt_started++;
else if (event==TR_EGG_HUNT_FINISHED)
diff --git a/src/achievements/achievements_status.hpp b/src/achievements/achievements_status.hpp
index d9361e77e..4bb401354 100644
--- a/src/achievements/achievements_status.hpp
+++ b/src/achievements/achievements_status.hpp
@@ -115,6 +115,11 @@ private:
int race_won; // doesn't count race without any other AI/player
int race_finished_reverse;
int race_finished_alone; // races against replays are counted, too
+ // counters for standard & TT races, apply to finished races only,
+ // lap number compared to track default.
+ int less_laps;
+ int more_laps;
+ int min_twice_laps; // at least twice the track's default lap count
// counters for egg hunts
int egg_hunt_started;
int egg_hunt_finished;
@@ -128,9 +133,12 @@ public:
TR_FINISHED = 1,
TR_WON = 2,
TR_FINISHED_REVERSE = 3,
- TR_FINISHED_ALONE = 4,
- TR_EGG_HUNT_STARTED = 5,
- TR_EGG_HUNT_FINISHED = 6
+ TR_LESS_LAPS = 4,
+ TR_MORE_LAPS = 5,
+ TR_MIN_TWICE_LAPS = 6,
+ TR_FINISHED_ALONE = 7,
+ TR_EGG_HUNT_STARTED = 8,
+ TR_EGG_HUNT_FINISHED = 9
};
private:
diff --git a/src/modes/world.cpp b/src/modes/world.cpp
index fd3450369..9027fa450 100644
--- a/src/modes/world.cpp
+++ b/src/modes/world.cpp
@@ -634,13 +634,6 @@ void World::terminateRace()
updateHighscores(&best_highscore_rank);
}
- // Check achievements
- if (raceHasLaps())
- {
- PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_MARATHONER,
- "laps", race_manager->getNumLaps());
- }
-
//TODO : move this stuff to a sub-function
// Increment won races counts and track finished counts
if (race_manager->isLinearRaceMode())
@@ -648,6 +641,7 @@ void World::terminateRace()
for(unsigned int i = 0; i < kart_amount; i++)
{
// TODO : does this work in multiplayer ?
+ // TODO : check what happens when abandonning a race in a GP
// Retrieve the current player
if (m_karts[i]->getController()->canGetAchievements())
{
@@ -661,8 +655,27 @@ void World::terminateRace()
PlayerManager::trackEvent(race_manager->getTrackName(), AchievementsStatus::TR_FINISHED);
if (race_manager->getReverseTrack())
PlayerManager::trackEvent(race_manager->getTrackName(), AchievementsStatus::TR_FINISHED_REVERSE);
+
+ if (race_manager->modeHasLaps())
+ {
+ Track* track = track_manager->getTrack(race_manager->getTrackName());
+ int default_lap_num = track->getDefaultNumberOfLaps();
+ if (race_manager->getNumLaps() < default_lap_num)
+ {
+ PlayerManager::trackEvent(race_manager->getTrackName(), AchievementsStatus::TR_LESS_LAPS);
+ }
+ else if (race_manager->getNumLaps() > default_lap_num)
+ {
+ PlayerManager::trackEvent(race_manager->getTrackName(), AchievementsStatus::TR_MORE_LAPS);
+ if (race_manager->getNumLaps() >= 2*default_lap_num)
+ PlayerManager::trackEvent(race_manager->getTrackName(), AchievementsStatus::TR_MIN_TWICE_LAPS);
+ }
+ }
+
int winner_position = 1;
- if (race_manager->isFollowMode()) winner_position = 2;//TODO : check this always work
+ //TODO : check this always work : what happens if the leader is overtaken between the last elimination
+ // and the results screen ?
+ if (race_manager->isFollowMode()) winner_position = 2;
// Check if the player has won
if (m_karts[i]->getPosition() == winner_position)
{