2007-05-27 12:01:53 -04:00
|
|
|
//
|
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
2013-11-15 06:43:21 -05:00
|
|
|
// Copyright (C) 2004-2013 Ingo Ruhnke <grumbel@gmx.de>
|
|
|
|
// Copyright (C) 2006-2013 Joerg Henrichs
|
2007-05-27 12:01:53 -04:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
2008-06-12 20:53:52 -04:00
|
|
|
// as published by the Free Software Foundation; either version 3
|
2007-05-27 12:01:53 -04:00
|
|
|
// of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
2009-06-02 21:36:48 -04:00
|
|
|
#include "race/grand_prix_data.hpp"
|
|
|
|
|
2014-02-17 04:10:29 -05:00
|
|
|
#include "config/player_profile.hpp"
|
2012-11-27 07:09:16 -05:00
|
|
|
#include "challenges/unlock_manager.hpp"
|
2014-02-09 07:22:45 -05:00
|
|
|
#include "config/player_manager.hpp"
|
2009-03-11 23:49:31 -04:00
|
|
|
#include "io/file_manager.hpp"
|
2009-01-22 07:02:40 -05:00
|
|
|
#include "tracks/track_manager.hpp"
|
2012-03-25 18:51:39 -04:00
|
|
|
#include "tracks/track.hpp"
|
2009-01-22 17:27:13 -05:00
|
|
|
#include "utils/string_utils.hpp"
|
2009-08-30 14:21:59 -04:00
|
|
|
#include "utils/translation.hpp"
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2012-11-27 07:09:16 -05:00
|
|
|
#include <iostream>
|
|
|
|
#include <stdexcept>
|
|
|
|
|
2010-02-15 19:33:41 -05:00
|
|
|
GrandPrixData::GrandPrixData(const std::string filename) throw(std::logic_error)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-07-29 00:30:44 -04:00
|
|
|
m_filename = filename;
|
2009-08-24 01:56:53 -04:00
|
|
|
m_id = StringUtils::getBasename(StringUtils::removeExtension(filename));
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2013-12-17 18:48:47 -05:00
|
|
|
XMLNode* root = file_manager->createXMLTree(file_manager->getAsset(FileManager::GRANDPRIX,filename));
|
2010-02-15 19:33:41 -05:00
|
|
|
if (!root)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2013-12-17 18:48:47 -05:00
|
|
|
Log::error("GrandPrixData","Error while trying to read grandprix file '%s'",
|
|
|
|
filename.c_str());
|
2010-02-15 19:33:41 -05:00
|
|
|
throw std::logic_error("File not found");
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-02-15 19:33:41 -05:00
|
|
|
bool foundName = false;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-02-15 19:33:41 -05:00
|
|
|
if (root->getName() == "supertuxkart_grand_prix")
|
|
|
|
{
|
|
|
|
std::string temp_name;
|
|
|
|
if (root->get("name", &temp_name) == 0)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2013-04-19 02:53:17 -04:00
|
|
|
Log::error("GrandPrixData", "Error while trying to read grandprix file '%s' : "
|
2010-02-15 19:33:41 -05:00
|
|
|
"missing 'name' attribute\n", filename.c_str());
|
|
|
|
delete root;
|
|
|
|
throw std::logic_error("File contents are incomplete or corrupt");
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2011-06-16 21:46:30 -04:00
|
|
|
m_name = temp_name.c_str();
|
2013-05-29 18:04:35 -04:00
|
|
|
foundName = true;
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2010-02-15 19:33:41 -05:00
|
|
|
else
|
|
|
|
{
|
2013-04-19 02:53:17 -04:00
|
|
|
Log::error("GrandPrixData", "Error while trying to read grandprix file '%s' : "
|
2010-02-15 19:33:41 -05:00
|
|
|
"Root node has an unexpected name\n", filename.c_str());
|
|
|
|
delete root;
|
|
|
|
throw std::logic_error("File contents are incomplete or corrupt");
|
|
|
|
}
|
|
|
|
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-02-15 19:33:41 -05:00
|
|
|
const int amount = root->getNumNodes();
|
|
|
|
for (int i=0; i<amount; i++)
|
|
|
|
{
|
|
|
|
const XMLNode* node = root->getNode(i);
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-02-15 19:33:41 -05:00
|
|
|
// read a track entry
|
|
|
|
if (node->getName() == "track")
|
|
|
|
{
|
|
|
|
std::string trackID;
|
|
|
|
int numLaps;
|
2012-03-25 18:51:39 -04:00
|
|
|
bool reversed = false;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2012-03-25 18:15:20 -04:00
|
|
|
const int idFound = node->get("id", &trackID );
|
|
|
|
const int lapFound = node->get("laps", &numLaps );
|
2012-03-25 18:51:39 -04:00
|
|
|
// Will stay false if not found
|
|
|
|
node->get("reverse", &reversed );
|
2010-02-15 19:33:41 -05:00
|
|
|
|
2012-03-25 18:51:39 -04:00
|
|
|
if (!idFound || !lapFound)
|
2010-02-15 19:33:41 -05:00
|
|
|
{
|
2013-04-19 02:53:17 -04:00
|
|
|
Log::error("GrandPrixData", "Error while trying to read grandprix file '%s' : "
|
2012-03-25 18:51:39 -04:00
|
|
|
"<track> tag does not have idi and laps reverse attributes. \n",
|
2012-03-25 18:15:20 -04:00
|
|
|
filename.c_str());
|
2010-02-15 19:33:41 -05:00
|
|
|
delete root;
|
|
|
|
throw std::logic_error("File contents are incomplete or corrupt");
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2012-03-25 18:51:39 -04:00
|
|
|
// Make sure the track really is reversible
|
|
|
|
Track* t = track_manager->getTrack(trackID);
|
|
|
|
if (t != NULL && reversed)
|
|
|
|
{
|
|
|
|
reversed = t->reverseAvailable();
|
|
|
|
}
|
|
|
|
|
2010-02-15 19:33:41 -05:00
|
|
|
m_tracks.push_back(trackID);
|
|
|
|
m_laps.push_back(numLaps);
|
2012-03-25 18:15:20 -04:00
|
|
|
m_reversed.push_back(reversed);
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2012-03-25 18:15:20 -04:00
|
|
|
assert(m_tracks.size() == m_laps.size() );
|
|
|
|
assert(m_laps.size() == m_reversed.size());
|
2010-02-15 19:33:41 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "Unknown node in Grand Prix XML file : " << node->getName().c_str() << std::endl;
|
|
|
|
delete root;
|
|
|
|
throw std::runtime_error("Unknown node in sfx XML file");
|
|
|
|
}
|
|
|
|
}// nend for
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-02-15 19:33:41 -05:00
|
|
|
delete root;
|
|
|
|
|
|
|
|
// sanity checks
|
|
|
|
if (!foundName)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2013-04-19 02:53:17 -04:00
|
|
|
Log::error("GrandPrixData", "Error while trying to read grandprix file '%s' : "
|
2010-02-15 19:33:41 -05:00
|
|
|
"missing 'name' attribute\n", filename.c_str());
|
|
|
|
throw std::logic_error("File contents are incomplete or corrupt");
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2008-07-29 00:30:44 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
2010-05-07 13:49:04 -04:00
|
|
|
bool GrandPrixData::checkConsistency(bool chatty) const
|
2008-07-29 00:30:44 -04:00
|
|
|
{
|
|
|
|
for(unsigned int i=0; i<m_tracks.size(); i++)
|
|
|
|
{
|
2010-05-07 13:49:04 -04:00
|
|
|
Track* t = track_manager->getTrack(m_tracks[i]);
|
|
|
|
|
|
|
|
if (t == NULL)
|
2008-07-29 09:40:25 -04:00
|
|
|
{
|
2010-05-07 13:49:04 -04:00
|
|
|
if (chatty)
|
|
|
|
{
|
2013-04-19 02:53:17 -04:00
|
|
|
Log::error("GrandPrixData", "Grand Prix '%ls': Track '%s' does not exist!\n",
|
2010-05-07 13:49:04 -04:00
|
|
|
m_name.c_str(), m_tracks[i].c_str());
|
2013-04-19 02:53:17 -04:00
|
|
|
Log::error("GrandPrixData", "This Grand Prix will not be available.\n");
|
2010-05-07 13:49:04 -04:00
|
|
|
}
|
2008-07-29 09:40:25 -04:00
|
|
|
return false;
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2008-07-29 00:30:44 -04:00
|
|
|
} // for i
|
2008-07-29 09:40:25 -04:00
|
|
|
return true;
|
2012-11-27 07:09:16 -05:00
|
|
|
} // checkConsistency
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/** Returns true if the track is available. This is used to test if Fort Magma
|
2013-05-29 18:04:35 -04:00
|
|
|
* is available (this way FortMagma is not used in the last Grand Prix in
|
2012-11-27 07:09:16 -05:00
|
|
|
* story mode, but will be available once all challenges are done and nolok
|
|
|
|
* is unlocked).
|
|
|
|
*/
|
|
|
|
bool GrandPrixData::isTrackAvailable(const std::string &id) const
|
|
|
|
{
|
2013-05-29 18:04:35 -04:00
|
|
|
return id!="fortmagma" ||
|
2014-02-09 07:22:45 -05:00
|
|
|
!PlayerManager::get()->getCurrentPlayer()->isLocked("fortmagma");
|
2012-11-27 07:09:16 -05:00
|
|
|
} // isTrackAvailable
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2013-05-29 18:04:35 -04:00
|
|
|
void GrandPrixData::getLaps(std::vector<int> *laps) const
|
2012-11-27 07:09:16 -05:00
|
|
|
{
|
|
|
|
laps->clear();
|
|
|
|
for(unsigned int i=0; i< m_tracks.size(); i++)
|
|
|
|
if(isTrackAvailable(m_tracks[i]))
|
|
|
|
laps->push_back(m_laps[i]);
|
|
|
|
} // getLaps
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2013-05-29 18:04:35 -04:00
|
|
|
void GrandPrixData::getReverse(std::vector<bool> *reverse) const
|
2012-11-27 07:09:16 -05:00
|
|
|
{
|
|
|
|
reverse->clear();
|
|
|
|
for(unsigned int i=0; i< m_tracks.size(); i++)
|
|
|
|
if(isTrackAvailable(m_tracks[i]))
|
|
|
|
reverse->push_back(m_reversed[i]);
|
|
|
|
} // getReverse
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2013-05-29 18:04:35 -04:00
|
|
|
const std::vector<std::string>& GrandPrixData::getTrackNames() const
|
2012-11-27 07:09:16 -05:00
|
|
|
{
|
|
|
|
m_really_available_tracks.clear();
|
|
|
|
for(unsigned int i=0; i< m_tracks.size(); i++)
|
|
|
|
{
|
|
|
|
if(isTrackAvailable(m_tracks[i]))
|
|
|
|
m_really_available_tracks.push_back(m_tracks[i]);
|
|
|
|
} // for i
|
|
|
|
return m_really_available_tracks;
|
|
|
|
} // getTrackNames
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
/* EOF */
|