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) {