diff --git a/data/challenges/unlock_supertux.challenge b/data/challenges/unlock_supertux.challenge index 4b25f6320..c225b8054 100644 --- a/data/challenges/unlock_supertux.challenge +++ b/data/challenges/unlock_supertux.challenge @@ -4,5 +4,6 @@ + diff --git a/src/challenges/challenge_data.cpp b/src/challenges/challenge_data.cpp index d797da5c1..24be6e120 100644 --- a/src/challenges/challenge_data.cpp +++ b/src/challenges/challenge_data.cpp @@ -47,6 +47,8 @@ ChallengeData::ChallengeData(const std::string& filename) m_num_completed_challenges = 0; m_is_unlock_list = false; m_is_ghost_replay = false; + m_unlock_special_type = SPECIAL_NONE; + m_unlock_special_value = -1; for (int d=0; dget("challenges", &m_num_completed_challenges); + if (m_is_unlock_list) + { + requirements_node = root->getNode("alt_requirements"); + if (requirements_node != NULL) + { + if(requirements_node->get("max-req-in-lower-diff", &m_unlock_special_value)) + m_unlock_special_type = SPECIAL_MAX_REQ_IN_LOWER_DIFF; + } + } + //Don't check further if this is an unlock list if(m_is_unlock_list) return; @@ -271,7 +283,6 @@ ChallengeData::ChallengeData(const std::string& filename) // This is optional int energy = -1; if (requirements_node->get("energy", &energy)) m_energy[d] = energy; - } } // ChallengeData diff --git a/src/challenges/challenge_data.hpp b/src/challenges/challenge_data.hpp index 5e50e4795..88afc80cd 100644 --- a/src/challenges/challenge_data.hpp +++ b/src/challenges/challenge_data.hpp @@ -84,6 +84,13 @@ public: CM_ANY }; + /** The type of value stored by m_unlock_special_value */ + enum SpecialUnlockType + { + SPECIAL_NONE, + SPECIAL_MAX_REQ_IN_LOWER_DIFF + }; + private: @@ -126,6 +133,10 @@ private: * (esp. useful for the final challenge) */ int m_num_completed_challenges; + /** Variables only used by unlock lists */ + SpecialUnlockType m_unlock_special_type; + int m_unlock_special_value; + public: ChallengeData(const std::string& filename); @@ -210,6 +221,12 @@ public: /** Returns if this challenge is an unlock list. */ bool isUnlockList() const { return m_is_unlock_list; } // ------------------------------------------------------------------------ + /** Returns the special unlock list value */ + SpecialUnlockType getSpecialType() const { return m_unlock_special_type; } + // ------------------------------------------------------------------------ + /** Returns the special unlock list value */ + int getSpecialValue() const { return m_unlock_special_value; } + // ------------------------------------------------------------------------ /** Returns the challenge mode of this challenge. */ ChallengeModeType getMode() const { return m_mode; } // ------------------------------------------------------------------------ diff --git a/src/challenges/story_mode_status.cpp b/src/challenges/story_mode_status.cpp index 7f1bc4426..fefad60e1 100644 --- a/src/challenges/story_mode_status.cpp +++ b/src/challenges/story_mode_status.cpp @@ -223,6 +223,7 @@ void StoryModeStatus::unlockFeatureByList() continue; bool newly_solved = unlock_manager->unlockByPoints(m_points,i->second); + newly_solved = newly_solved || unlock_manager->unlockSpecial(i->second, getNumReqMetInLowerDiff()); // Add to list of recently unlocked features if(newly_solved) @@ -380,3 +381,15 @@ void StoryModeStatus::save(UTFWriter &out) } out << " \n"; } // save + +int StoryModeStatus::getNumReqMetInLowerDiff() const +{ + int counter = 0; + for ( const auto &c : m_challenges_state) + { + counter += (c.second->areMaxReqMetInLowerDiff()) ? 1 : 0; + } + return counter; +} // getNumReqMetInLowerDiff + +/* EOF */ diff --git a/src/challenges/story_mode_status.hpp b/src/challenges/story_mode_status.hpp index 61fd6a9c9..29509e5fc 100644 --- a/src/challenges/story_mode_status.hpp +++ b/src/challenges/story_mode_status.hpp @@ -103,6 +103,9 @@ public: int getNumCompletedChallenges () const { return (m_easy_challenges + m_medium_challenges + m_hard_challenges + m_best_challenges); } // ------------------------------------------------------------------------ + /** Returns the number of challenges with the superTux time beaten in a lower difficulty. */ + int getNumReqMetInLowerDiff () const; + // ------------------------------------------------------------------------ /** Returns the number of points accumulated. */ int getPoints () const { return m_points; } // ------------------------------------------------------------------------ diff --git a/src/challenges/unlock_manager.cpp b/src/challenges/unlock_manager.cpp index a29688a26..816ffe582 100644 --- a/src/challenges/unlock_manager.cpp +++ b/src/challenges/unlock_manager.cpp @@ -297,7 +297,6 @@ void UnlockManager::findWhatWasUnlocked(int points_before, int points_now, */ bool UnlockManager::unlockByPoints(int points, ChallengeStatus* unlock_list) { - //TODO : add support for other conditions (achievements...) for alternative unlock paths if( unlock_list!=NULL && unlock_list->getData()->getNumTrophies() <= points) { unlock_list->setSolved(RaceManager::DIFFICULTY_BEST); @@ -306,4 +305,24 @@ bool UnlockManager::unlockByPoints(int points, ChallengeStatus* unlock_list) return false; } // unlockByPoints +//----------------------------------------------------------------------------- +/** This functions sets as completed the "challenges" requiring some special conditions + * Returns true if the challenge has been completed + */ +bool UnlockManager::unlockSpecial(ChallengeStatus* unlock_list, int max_req_in_lower_diff) +{ + if ( unlock_list!=NULL && unlock_list->getData()->getSpecialType() != ChallengeData::SPECIAL_NONE) + { + if (unlock_list->getData()->getSpecialType() == ChallengeData::SPECIAL_MAX_REQ_IN_LOWER_DIFF) + { + if (max_req_in_lower_diff >= unlock_list->getData()->getSpecialValue()) + { + unlock_list->setSolved(RaceManager::DIFFICULTY_BEST); + return true; + } + } + } + return false; +} // unlockSpecial + /* EOF */ diff --git a/src/challenges/unlock_manager.hpp b/src/challenges/unlock_manager.hpp index cb382e002..e5dd063b2 100644 --- a/src/challenges/unlock_manager.hpp +++ b/src/challenges/unlock_manager.hpp @@ -69,6 +69,7 @@ public: std::vector& karts, std::vector& unlocked); bool unlockByPoints(int points, ChallengeStatus* unlock_list); + bool unlockSpecial(ChallengeStatus* unlock_list, int max_req_in_lower_diff); StoryModeStatus *createStoryModeStatus(const XMLNode *node=NULL);