Add support for using ghost kart in challenge
Real challenge file added later.
This commit is contained in:
parent
33defa44b7
commit
11b119066c
@ -21,6 +21,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "race/grand_prix_data.hpp"
|
||||
#include "race/grand_prix_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "replay/replay_play.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "tracks/track_manager.hpp"
|
||||
|
||||
@ -41,6 +43,7 @@ ChallengeData::ChallengeData(const std::string& filename)
|
||||
m_gp_id = "";
|
||||
m_version = 0;
|
||||
m_num_trophies = 0;
|
||||
m_is_ghost_replay = false;
|
||||
|
||||
for (int d=0; d<RaceManager::DIFFICULTY_COUNT; d++)
|
||||
{
|
||||
@ -175,6 +178,13 @@ ChallengeData::ChallengeData(const std::string& filename)
|
||||
if (!karts_node->get("number", &num_karts)) error("karts");
|
||||
m_num_karts[d] = num_karts;
|
||||
|
||||
std::string replay_file;
|
||||
if (karts_node->get("replay_file", &replay_file))
|
||||
{
|
||||
m_is_ghost_replay = true;
|
||||
m_replay_files[d] = replay_file;
|
||||
}
|
||||
|
||||
std::string ai_kart_ident;
|
||||
if (karts_node->get("aiIdent", &ai_kart_ident))
|
||||
m_ai_kart_ident[d] = ai_kart_ident;
|
||||
@ -387,6 +397,16 @@ void ChallengeData::setRace(RaceManager::Difficulty d) const
|
||||
race_manager->setNumPlayers(1);
|
||||
}
|
||||
|
||||
if (m_is_ghost_replay)
|
||||
{
|
||||
const bool result = ReplayPlay::get()->addReplayFile(file_manager
|
||||
->getAsset(FileManager::CHALLENGE, m_replay_files[d]),
|
||||
true/*custom_replay*/);
|
||||
if (!result)
|
||||
Log::fatal("ChallengeData", "Can't open replay for challenge!");
|
||||
race_manager->setRaceGhostKarts(true);
|
||||
}
|
||||
|
||||
if (m_ai_kart_ident[d] != "")
|
||||
{
|
||||
race_manager->setAIKartOverride(m_ai_kart_ident[d]);
|
||||
|
@ -86,6 +86,7 @@ private:
|
||||
int m_position[RaceManager::DIFFICULTY_COUNT];
|
||||
int m_num_karts[RaceManager::DIFFICULTY_COUNT];
|
||||
std::string m_ai_kart_ident[RaceManager::DIFFICULTY_COUNT];
|
||||
std::string m_replay_files[RaceManager::DIFFICULTY_COUNT];
|
||||
float m_time[RaceManager::DIFFICULTY_COUNT];
|
||||
int m_energy[RaceManager::DIFFICULTY_COUNT];
|
||||
RaceManager::AISuperPower m_ai_superpower[RaceManager::DIFFICULTY_COUNT];
|
||||
@ -94,6 +95,7 @@ private:
|
||||
std::string m_filename;
|
||||
/** Version number of the challenge. */
|
||||
int m_version;
|
||||
bool m_is_ghost_replay;
|
||||
|
||||
void setUnlocks(const std::string &id,
|
||||
ChallengeData::RewardType reward);
|
||||
@ -182,6 +184,9 @@ public:
|
||||
/** Returns if this challenge is a grand prix. */
|
||||
bool isSingleRace() const { return m_mode == CM_SINGLE_RACE; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this challenge is using ghost replay. */
|
||||
bool isGhostReplay() const { return m_is_ghost_replay; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the challenge mode of this challenge. */
|
||||
ChallengeModeType getMode() const { return m_mode; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -26,12 +26,14 @@ ReplayBase::ReplayBase()
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Opens a replay file which is determined by sub classes.
|
||||
* \param writeable True if the file should be opened for writing.
|
||||
* \param full_path True if the file is full path.
|
||||
* \return A FILE *, or NULL if the file could not be opened.
|
||||
*/
|
||||
FILE* ReplayBase::openReplayFile(bool writeable)
|
||||
FILE* ReplayBase::openReplayFile(bool writeable, bool full_path)
|
||||
{
|
||||
FILE *fd = fopen((file_manager->getReplayDir() +
|
||||
getReplayFilename()).c_str(), writeable ? "w" : "r");
|
||||
FILE *fd = fopen(full_path ? getReplayFilename().c_str() :
|
||||
(file_manager->getReplayDir() + getReplayFilename()).c_str(),
|
||||
writeable ? "w" : "r");
|
||||
if (!fd)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -68,7 +68,7 @@ protected:
|
||||
}; // KartReplayEvent
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
FILE *openReplayFile(bool writeable);
|
||||
FILE *openReplayFile(bool writeable, bool full_path = false);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the filename that was opened. */
|
||||
virtual const std::string& getReplayFilename() const = 0;
|
||||
|
@ -40,6 +40,7 @@ ReplayPlay *ReplayPlay::m_replay_play = NULL;
|
||||
ReplayPlay::ReplayPlay()
|
||||
{
|
||||
m_current_replay_file = 0;
|
||||
m_custom_replay_file = false;
|
||||
} // ReplayPlay
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -67,113 +68,135 @@ void ReplayPlay::loadAllReplayFile()
|
||||
file_manager->listFiles(files, file_manager->getReplayDir(),
|
||||
/*is_full_path*/ false);
|
||||
|
||||
char s[1024], s1[1024];
|
||||
for (std::set<std::string>::iterator i = files.begin();
|
||||
i != files.end(); ++i)
|
||||
{
|
||||
if (StringUtils::getExtension(*i) != "replay") continue;
|
||||
FILE *fd = fopen((file_manager->getReplayDir() + (*i)).c_str(), "r");
|
||||
if (fd == NULL) continue;
|
||||
ReplayData rd;
|
||||
|
||||
rd.m_filename = *i;
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
unsigned int version;
|
||||
if (sscanf(s,"version: %u", &version) != 1)
|
||||
if (!addReplayFile(*i))
|
||||
{
|
||||
Log::warn("Replay", "No Version information "
|
||||
"found in replay file (bogus replay file).");
|
||||
fclose(fd);
|
||||
// Skip invalid replay file
|
||||
continue;
|
||||
}
|
||||
if (version != getReplayVersion())
|
||||
{
|
||||
Log::warn("Replay", "Replay is version '%d'", version);
|
||||
Log::warn("Replay", "STK version is '%d'", getReplayVersion());
|
||||
Log::warn("Replay", "Skipped '%s'", i->c_str());
|
||||
fclose(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
fgets(s, 1023, fd);
|
||||
core::stringc is_end(s);
|
||||
is_end.trim();
|
||||
if (is_end == "kart_list_end") break;
|
||||
char s1[1024];
|
||||
|
||||
if (sscanf(s,"kart: %s", s1) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Could not read ghost karts info!");
|
||||
break;
|
||||
}
|
||||
rd.m_kart_list.push_back(std::string(s1));
|
||||
}
|
||||
|
||||
int reverse = 0;
|
||||
fgets(s, 1023, fd);
|
||||
if(sscanf(s, "reverse: %d", &reverse) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Reverse info found in replay file.");
|
||||
fclose(fd);
|
||||
continue;
|
||||
}
|
||||
rd.m_reverse = reverse!=0;
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "difficulty: %u", &rd.m_difficulty) != 1)
|
||||
{
|
||||
Log::warn("Replay", " No difficulty found in replay file.");
|
||||
fclose(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "track: %s", s1) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Track info not found in replay file.");
|
||||
fclose(fd);
|
||||
continue;
|
||||
}
|
||||
rd.m_track_name = std::string(s1);
|
||||
Track* t = track_manager->getTrack(rd.m_track_name);
|
||||
if (t == NULL)
|
||||
{
|
||||
Log::warn("Replay", "Track '%s' used in replay not found in STK!",
|
||||
rd.m_track_name.c_str());
|
||||
fclose(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "laps: %u", &rd.m_laps) != 1)
|
||||
{
|
||||
Log::warn("Replay", "No number of laps found in replay file.");
|
||||
fclose(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "min_time: %f", &rd.m_min_time) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Finish time not found in replay file.");
|
||||
fclose(fd);
|
||||
continue;
|
||||
}
|
||||
fclose(fd);
|
||||
m_replay_file_list.push_back(rd);
|
||||
}
|
||||
} // loadAllReplayFile
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay)
|
||||
{
|
||||
// custom_replay is true when full path of filename is given
|
||||
m_custom_replay_file = custom_replay;
|
||||
|
||||
char s[1024], s1[1024];
|
||||
if (StringUtils::getExtension(fn) != "replay") return false;
|
||||
FILE *fd = fopen(custom_replay ? fn.c_str() :
|
||||
(file_manager->getReplayDir() + fn).c_str(), "r");
|
||||
if (fd == NULL) return false;
|
||||
ReplayData rd;
|
||||
|
||||
rd.m_filename = fn;
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
unsigned int version;
|
||||
if (sscanf(s,"version: %u", &version) != 1)
|
||||
{
|
||||
Log::warn("Replay", "No Version information "
|
||||
"found in replay file (bogus replay file).");
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
if (version != getReplayVersion())
|
||||
{
|
||||
Log::warn("Replay", "Replay is version '%d'", version);
|
||||
Log::warn("Replay", "STK version is '%d'", getReplayVersion());
|
||||
Log::warn("Replay", "Skipped '%s'", fn.c_str());
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
fgets(s, 1023, fd);
|
||||
core::stringc is_end(s);
|
||||
is_end.trim();
|
||||
if (is_end == "kart_list_end") break;
|
||||
char s1[1024];
|
||||
|
||||
if (sscanf(s,"kart: %s", s1) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Could not read ghost karts info!");
|
||||
break;
|
||||
}
|
||||
rd.m_kart_list.push_back(std::string(s1));
|
||||
}
|
||||
|
||||
int reverse = 0;
|
||||
fgets(s, 1023, fd);
|
||||
if(sscanf(s, "reverse: %d", &reverse) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Reverse info found in replay file.");
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
rd.m_reverse = reverse != 0;
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "difficulty: %u", &rd.m_difficulty) != 1)
|
||||
{
|
||||
Log::warn("Replay", " No difficulty found in replay file.");
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "track: %s", s1) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Track info not found in replay file.");
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
rd.m_track_name = std::string(s1);
|
||||
Track* t = track_manager->getTrack(rd.m_track_name);
|
||||
if (t == NULL)
|
||||
{
|
||||
Log::warn("Replay", "Track '%s' used in replay not found in STK!",
|
||||
rd.m_track_name.c_str());
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "laps: %u", &rd.m_laps) != 1)
|
||||
{
|
||||
Log::warn("Replay", "No number of laps found in replay file.");
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
fgets(s, 1023, fd);
|
||||
if (sscanf(s, "min_time: %f", &rd.m_min_time) != 1)
|
||||
{
|
||||
Log::warn("Replay", "Finish time not found in replay file.");
|
||||
fclose(fd);
|
||||
return false;
|
||||
}
|
||||
fclose(fd);
|
||||
m_replay_file_list.push_back(rd);
|
||||
|
||||
assert(m_replay_file_list.size() > 0);
|
||||
// Force to use custom replay file immediately
|
||||
if (custom_replay)
|
||||
m_current_replay_file = m_replay_file_list.size() - 1;
|
||||
|
||||
return true;
|
||||
|
||||
} // addReplayFile
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ReplayPlay::load()
|
||||
{
|
||||
m_ghost_karts.clearAndDeleteAll();
|
||||
char s[1024];
|
||||
|
||||
FILE *fd = openReplayFile(/*writeable*/false);
|
||||
FILE *fd = openReplayFile(/*writeable*/false, m_custom_replay_file);
|
||||
if(!fd)
|
||||
{
|
||||
Log::error("Replay", "Can't read '%s', ghost replay disabled.",
|
||||
|
@ -93,6 +93,8 @@ private:
|
||||
|
||||
unsigned int m_current_replay_file;
|
||||
|
||||
bool m_custom_replay_file;
|
||||
|
||||
std::vector<ReplayData> m_replay_file_list;
|
||||
|
||||
/** All ghost karts. */
|
||||
@ -118,6 +120,9 @@ public:
|
||||
void setReplayFile(unsigned int n)
|
||||
{ m_current_replay_file = n; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool addReplayFile(const std::string& fn,
|
||||
bool custom_replay = false);
|
||||
// ------------------------------------------------------------------------
|
||||
const ReplayData& getReplayData(unsigned int n) const
|
||||
{ return m_replay_file_list.at(n); }
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -63,8 +63,11 @@ core::stringw getLabel(RaceManager::Difficulty difficulty, const ChallengeData*
|
||||
label.append( _("Required Nitro Points: %i", c->getEnergy(difficulty)) );
|
||||
}
|
||||
|
||||
if (label.size() > 0) label.append(L"\n");
|
||||
label.append(_("Number of AI Karts: %i", c->getNumKarts(difficulty) - 1));
|
||||
if (!c->isGhostReplay())
|
||||
{
|
||||
if (label.size() > 0) label.append(L"\n");
|
||||
label.append(_("Number of AI Karts: %i", c->getNumKarts(difficulty) - 1));
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
@ -144,6 +147,8 @@ SelectChallengeDialog::SelectChallengeDialog(const float percentWidth,
|
||||
typeLbl->setText(_("Grand Prix"), false );
|
||||
else if (c->getData()->getEnergy(RaceManager::DIFFICULTY_EASY) > 0)
|
||||
typeLbl->setText(_("Nitro challenge"), false );
|
||||
else if (c->getData()->isGhostReplay())
|
||||
typeLbl->setText(_("Ghost replay race"), false );
|
||||
else
|
||||
typeLbl->setText( RaceManager::getNameOf(c->getData()->getMinorMode()), false );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user