Check and remember if a challenge's supertux requirement (esp. time) have been met at a lower difficulty

This commit is contained in:
Alayan
2018-10-10 22:50:27 +02:00
parent ef62e48e89
commit 7471d215db
7 changed files with 68 additions and 18 deletions

View File

@@ -457,8 +457,12 @@ void ChallengeData::setRace(RaceManager::Difficulty d) const
// ----------------------------------------------------------------------------
/** Returns true if this (non-GP) challenge is fulfilled.
* \param check_best : if true, check if the requirement
* for the best difficulty are met at a lower one.
* (requires SuperTux challenges to have a time
ù requirement to make sense)
*/
bool ChallengeData::isChallengeFulfilled() const
bool ChallengeData::isChallengeFulfilled(bool check_best) const
{
// GP's use the grandPrixFinished() function,
// so they can't be fulfilled here.
@@ -469,15 +473,16 @@ bool ChallengeData::isChallengeFulfilled() const
World *world = World::getWorld();
std::string track_name = Track::getCurrentTrack()->getIdent();
int d = race_manager->getDifficulty();
int d = (check_best) ? RaceManager::DIFFICULTY_BEST :
race_manager->getDifficulty();
AbstractKart* kart = world->getPlayerKart(0);
if (kart->isEliminated() ) return false;
if (track_name != m_track_id ) return false;
if ((int)world->getNumKarts() < m_default_num_karts[d] ) return false;
if (m_energy[d] > 0 && kart->getEnergy() < m_energy[d] ) return false;
if (m_position[d] > 0 && kart->getPosition() > m_position[d]) return false;
if (kart->isEliminated() ) return false;
if (track_name != m_track_id ) return false;
if (((int)world->getNumKarts() < m_default_num_karts[d]) && !check_best) return false;
if (m_energy[d] > 0 && kart->getEnergy() < m_energy[d] ) return false;
if (m_position[d] > 0 && kart->getPosition() > m_position[d] ) return false;
// Follow the leader
// -----------------
@@ -501,6 +506,17 @@ bool ChallengeData::isChallengeFulfilled() const
// too slow
if (m_time[d] > 0.0f && kart->getFinishTime() > m_time[d]) return false;
// too slow
if (m_is_ghost_replay)
{
ReplayPlay::get()->addReplayFile(file_manager
->getAsset(FileManager::REPLAY, m_replay_files[d]),
true/*custom_replay*/);
const ReplayPlay::ReplayData& rd = ReplayPlay::get()->getCurrentReplayData();
if (kart->getFinishTime() > rd.m_min_time)
return false;
}
if (m_ai_superpower[d] != RaceManager::SUPERPOWER_NONE &&
race_manager->getAISuperPower() != m_ai_superpower[d])
{

View File

@@ -135,7 +135,7 @@ public:
void setRace(RaceManager::Difficulty d) const;
virtual void check() const;
virtual bool isChallengeFulfilled() const;
virtual bool isChallengeFulfilled(bool check_best=false) const;
virtual GPLevel isGPFulfilled() const;
void addUnlockTrackReward(const std::string &track_name);
void addUnlockModeReward(const std::string &internal_mode_name,
@@ -238,10 +238,10 @@ public:
// ------------------------------------------------------------------------
/** Returns the maximum time in which the kart must finish.
*/
float getTime(RaceManager::Difficulty difficulty) const
float getTimeRequirement(RaceManager::Difficulty difficulty) const
{
return m_time[difficulty];
} // getTime
} // getTimeRequirement
// ------------------------------------------------------------------------
/** Return the energy that a kart must at least have at the end of a race.
*/

View File

@@ -73,7 +73,8 @@ void ChallengeStatus::load(const XMLNode* challenges_node)
m_state[3] = CH_SOLVED;
}
} // if has 'solved' attribute
if (!node->get("best_while_slower", &m_max_req_in_lower_diff))
m_max_req_in_lower_diff = false;
} // load
//-----------------------------------------------------------------------------
@@ -106,13 +107,15 @@ void ChallengeStatus::save(UTFWriter& writer)
{
writer << " <" << m_data->getChallengeId();
if (isSolved(RaceManager::DIFFICULTY_BEST))
writer << " solved=\"best\"/>\n";
writer << " solved=\"best\"";
else if (isSolved(RaceManager::DIFFICULTY_HARD))
writer << " solved=\"hard\"/>\n";
writer << " solved=\"hard\"";
else if (isSolved(RaceManager::DIFFICULTY_MEDIUM))
writer << " solved=\"medium\"/>\n";
writer << " solved=\"medium\"";
else if (isSolved(RaceManager::DIFFICULTY_EASY))
writer << " solved=\"easy\"/>\n";
writer << " solved=\"easy\"";
else
writer << " solved=\"none\"/>\n";
writer << " solved=\"none\"";
writer << " best_while_slower=\"" << m_max_req_in_lower_diff << "\"/>\n";
} // save

View File

@@ -60,6 +60,10 @@ private:
m_state[RaceManager::DIFFICULTY_COUNT];
// If the challenge's SuperTux time requirement has been beaten
// in a (s)lower difficulty.
bool m_max_req_in_lower_diff;
/** Pointer to the original challenge data. */
const ChallengeData* m_data;
@@ -71,6 +75,7 @@ public:
m_state[RaceManager::DIFFICULTY_MEDIUM] = CH_INACTIVE;
m_state[RaceManager::DIFFICULTY_HARD] = CH_INACTIVE;
m_state[RaceManager::DIFFICULTY_BEST] = CH_INACTIVE;
m_max_req_in_lower_diff = false;
}
virtual ~ChallengeStatus() {};
void load(const XMLNode* config);
@@ -114,6 +119,21 @@ public:
/** Returns if this challenge is a grand prix */
bool isGrandPrix();
// ------------------------------------------------------------------------
/** Used when a challenge's requirement in the hardest difficulty are
* matched in a lower difficulty. Don't apply to GP */
void setMaxReqInLowerDiff()
{
if (!isGrandPrix() && !isUnlockList())
m_max_req_in_lower_diff = true;
} // setMaxReqInLowerDiff
// ------------------------------------------------------------------------
/** Returns if the hardest difficulty requirements have been met in a lower
* difficulty. */
bool areMaxReqMetInLowerDiff() const
{
return m_max_req_in_lower_diff;
} // areMaxReqMetInLowerDiff
// ------------------------------------------------------------------------
/** Returns a pointer to the actual Challenge data.
*/
const ChallengeData* getData() const { return m_data; }

View File

@@ -301,6 +301,14 @@ void StoryModeStatus::setCurrentChallenge(const std::string &challenge_id)
*/
void StoryModeStatus::raceFinished()
{
if(m_current_challenge &&
race_manager->getDifficulty() != RaceManager::DIFFICULTY_BEST &&
m_current_challenge->getData()->isChallengeFulfilled(true /*best*/))
{
ChallengeStatus* c = const_cast<ChallengeStatus*>(m_current_challenge);
c->setMaxReqInLowerDiff();
}
if(m_current_challenge &&
m_current_challenge->isActive(race_manager->getDifficulty()) &&
m_current_challenge->getData()->isChallengeFulfilled() )

View File

@@ -161,6 +161,9 @@ public:
const ReplayData& getReplayData(unsigned int n) const
{ return m_replay_file_list.at(n); }
// ------------------------------------------------------------------------
const ReplayData& getCurrentReplayData() const
{ return m_replay_file_list.at(m_current_replay_file); }
// ------------------------------------------------------------------------
const unsigned int getNumReplayFile() const
{ return (unsigned int)m_replay_file_list.size(); }
// ------------------------------------------------------------------------

View File

@@ -51,11 +51,11 @@ core::stringw getLabel(RaceManager::Difficulty difficulty, const ChallengeData*
if (label.size() > 0) label.append(L"\n");
label.append( _("Required Rank: %i", r) );
}
if (c->getTime(difficulty) > 0)
if (c->getTimeRequirement(difficulty) > 0)
{
if (label.size() > 0) label.append(L"\n");
label.append( _("Required Time: %i",
StringUtils::timeToString(c->getTime(difficulty)).c_str()) );
StringUtils::timeToString(c->getTimeRequirement(difficulty)).c_str()) );
}
if (c->getEnergy(difficulty) > 0)
{