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