1) Added support for new --trackdir command line parameter (which specifies a directory with more

tracks).
2) Challenges are now saved in its own file (not in user config file anymore).
3) The TRACKNAME.{irrtrack,scene,graph,quads} files are now called {track,scene,graph,quads}.xml
   (so not containing the name of the track anymore). Beach and lighthouse tracks have been
   updated.
4) Track exporter uses the new filenames above.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3915 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2009-08-25 11:58:25 +00:00
parent abbd8bd618
commit 4ce732574a
20 changed files with 232 additions and 204 deletions

View File

@ -25,7 +25,7 @@
#include "animations/three_d_animation.hpp"
#include "io/xml_node.hpp"
AnimationManager::AnimationManager(const std::string &track_name, const XMLNode &node)
AnimationManager::AnimationManager(const Track &track, const XMLNode &node)
{
for(unsigned int i=0; i<node.getNumNodes(); i++)
{
@ -34,9 +34,9 @@ AnimationManager::AnimationManager(const std::string &track_name, const XMLNode
float fps=25;
anim_node->get("fps", &fps);
if(type=="anim_billboard")
m_all_animations.push_back(new BillboardAnimation(track_name, *anim_node, fps));
m_all_animations.push_back(new BillboardAnimation(track, *anim_node, fps));
else if(type=="animations-IPO")
m_all_animations.push_back(new ThreeDAnimation(track_name, *anim_node, fps));
m_all_animations.push_back(new ThreeDAnimation(track, *anim_node, fps));
else
fprintf(stderr, "Unknown animation type '%s' - ignored.\n",
type.c_str());

View File

@ -24,6 +24,7 @@
#include <vector>
class AnimationBase;
class Track;
class XMLNode;
/** Controls all animations of a track. */
@ -33,7 +34,7 @@ private:
std::vector<AnimationBase*> m_all_animations;
public:
AnimationManager(const std::string &track_name, const XMLNode &node);
AnimationManager(const Track &track, const XMLNode &node);
~AnimationManager();
void update(float dt);
void reset();

View File

@ -22,7 +22,7 @@
class XMLNode;
/** A 2d billboard animation. */
BillboardAnimation::BillboardAnimation(const std::string &track_name,
BillboardAnimation::BillboardAnimation(const Track &track_name,
const XMLNode &node, float fps)
: AnimationBase(node, fps)
{

View File

@ -24,6 +24,7 @@
#include "animations/animation_base.hpp"
class Track;
class XMLNode;
/** A 2d billboard animation. */
@ -32,7 +33,7 @@ class BillboardAnimation : public AnimationBase
private:
public:
BillboardAnimation(const std::string &track, const XMLNode &node, float fps);
BillboardAnimation(const Track &track, const XMLNode &node, float fps);
virtual ~BillboardAnimation(){}
virtual void update(float dt);

View File

@ -24,23 +24,23 @@
#include "animations/ipo.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/mesh_tools.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "modes/world.hpp"
#include "physics/physics.hpp"
#include "physics/kart_motion_state.hpp"
#include "race/race_manager.hpp"
#include "tracks/bezier_curve.hpp"
#include "tracks/track.hpp"
#include "utils/constants.hpp"
ThreeDAnimation::ThreeDAnimation(const std::string &track_name,
ThreeDAnimation::ThreeDAnimation(const Track &track,
const XMLNode &node, float fps)
: AnimationBase(node, fps)
{
std::string model_name;
node.get("obj", &model_name);
std::string full_path = file_manager->getTrackFile(model_name, track_name);
std::string full_path = track.getTrackFile(model_name);
m_mesh = irr_driver->getAnimatedMesh(full_path);
if(!m_mesh)
{

View File

@ -30,8 +30,9 @@ using namespace irr;
#include "animations/animation_base.hpp"
#include "physics/user_pointer.hpp"
class XMLNode;
class BezierCurve;
class Track;
class XMLNode;
/** A virtual base class for all animations. */
class ThreeDAnimation : public AnimationBase
@ -58,7 +59,7 @@ private:
void createPhysicsBody(const std::string &shape);
public:
ThreeDAnimation(const std::string &track_name,
ThreeDAnimation(const Track &track,
const XMLNode &node, float fps);
virtual ~ThreeDAnimation();
virtual void update(float dt);

View File

@ -149,11 +149,8 @@ void Challenge::load(const XMLNode* challengesNode)
// See if the challenge is solved (it's activated later from the
// unlock_manager).
std::string solvedString;
node->get("solved", &solvedString);
bool finished = (solvedString == "true");
bool finished=false;
node->get("solved", &finished);
m_state = finished ? CH_SOLVED : CH_INACTIVE;
if(m_state == CH_SOLVED)

View File

@ -21,12 +21,14 @@
#include <set>
#include <string>
#include <vector>
#include <stdio.h>
#include "config/user_config.hpp"
#include "challenges/challenge_data.hpp"
#include "io/file_manager.hpp"
#include "race/race_manager.hpp"
#include "tracks/track_manager.hpp"
#include "utils/string_utils.hpp"
UnlockManager* unlock_manager=0;
@ -52,35 +54,29 @@ UnlockManager::UnlockManager()
// Read challenges from .../data/tracks/*
// --------------------------------------
std::set<std::string> dirs;
file_manager->listFiles(dirs, file_manager->getTrackDir(), /*is_full_path*/ true);
for(std::set<std::string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++)
const std::vector<std::string> *all_track_dirs = track_manager->getAllTrackDirs();
for(std::vector<std::string>::const_iterator dir=all_track_dirs->begin();
dir!=all_track_dirs->end(); dir++)
{
if(*dir=="." || *dir=="..") continue;
std::string config_file;
try
std::set<std::string> all_files;
file_manager->listFiles(all_files, *dir, /*is_full_path*/ true);
for(std::set<std::string>::iterator file=all_files.begin();
file!=all_files.end(); file++)
{
// getTrackFile appends dir, so it's opening: *dir/*dir.track
config_file = file_manager->getTrackFile((*dir)+".track");
}
catch (std::exception& e)
{
(void)e; // remove warning about unused variable
continue;
}
// Check for a challenge file
std::string challenge_file =
StringUtils::removeExtension(config_file)+".challenge";
FILE *f=fopen(challenge_file.c_str(), "r");
if(f)
{
fclose(f);
addChallenge(new ChallengeData(challenge_file));
}
} // for dirs
if(!StringUtils::hasSuffix(*file,".challenge")) continue;
std::string filename=*dir+"/"+*file;
FILE *f=fopen(filename.c_str(), "r");
if(f)
{
fclose(f);
addChallenge(new ChallengeData(filename));
} // if file
} // for file in files
} // for dir in all_track_dirs
// Load challenges from .../data/karts
// -----------------------------------
std::set<std::string> dirs;
file_manager->listFiles(dirs, file_manager->getKartDir(),
/*is_full_path*/ true);
@ -117,19 +113,31 @@ UnlockManager::UnlockManager()
// Hard coded challenges can be added here.
computeActive();
load();
// Disable challenges that can not be done - e.g. due to missing tracks...
check();
} // UnlockManager
//-----------------------------------------------------------------------------
/** Saves the challenge status.
*/
UnlockManager::~UnlockManager()
{
save();
} // ~UnlockManager
//-----------------------------------------------------------------------------
void UnlockManager::addChallenge(Challenge *c)
{
m_all_challenges[c->getId()]=c;
} // addChallenge
//-----------------------------------------------------------------------------
void UnlockManager::addChallenge(const std::string& filename)
{
addChallenge(new ChallengeData(filename));
} // addChallenge
//-----------------------------------------------------------------------------
/** Checks if all challenges are valid, i.e. contain a valid track or GP.
* If not, STK is aborted with an error message.
@ -167,32 +175,49 @@ Challenge* UnlockManager::getChallenge(const std::string& id)
//-----------------------------------------------------------------------------
/** This is called from user_config when reading the config file
*/
void UnlockManager::load(const XMLNode* configRoot)
void UnlockManager::load()
{
const XMLNode* challengesNode = configRoot->getNode("challenges");
if(challengesNode == NULL) return;
const std::string filename=file_manager->getChallengeFile("challenges.xml");
XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "challenges")
{
std::cerr << "Challenge file '" << filename << "' will be created."
<< std::endl;
return;
}
for(AllChallengesType::iterator i =m_all_challenges.begin();
i!=m_all_challenges.end(); i++)
{
i->second->load(challengesNode);
i->second->load(root);
}
computeActive();
} // load
//-----------------------------------------------------------------------------
void UnlockManager::save(std::ofstream& writer)
void UnlockManager::save()
{
writer << " <challenges>\n";
std::ofstream challenge_file;
std::string filename = file_manager->getChallengeFile("challenges.xml");
challenge_file.open(filename.c_str());
if(!challenge_file.is_open())
{
std::cerr << "Failed to open " << filename << " for writing, challenges won't be saved\n";
return;
}
challenge_file << "<?xml version=\"1.0\"?>\n";
challenge_file << "<challenges>\n";
for(AllChallengesType::iterator i = m_all_challenges.begin();
i!= m_all_challenges.end(); i++)
{
i->second->save(writer);
i->second->save(challenge_file);
}
writer << " </challenges>\n\n";
challenge_file << "</challenges>\n\n";
challenge_file.close();
} // save
//-----------------------------------------------------------------------------
@ -282,7 +307,7 @@ void UnlockManager::lockFeature(Challenge* challenge)
//-----------------------------------------------------------------------------
void UnlockManager::unlockFeature(Challenge* c, bool save)
void UnlockManager::unlockFeature(Challenge* c, bool do_save)
{
const unsigned int amount = (unsigned int)c->getFeatures().size();
for(unsigned int n=0; n<amount; n++)
@ -303,7 +328,7 @@ void UnlockManager::unlockFeature(Challenge* c, bool save)
c->setSolved(); // reset isActive flag
// Save the new unlock information
if(save) user_config->saveConfig();
if(do_save) save();
} // unlockFeature
//-----------------------------------------------------------------------------

View File

@ -36,24 +36,25 @@ private:
std::vector<const Challenge*> m_unlocked_features;
Challenge *getChallenge (const std::string& id);
void computeActive ();
void load ();
public:
UnlockManager ();
void addChallenge (Challenge *c);
void addChallenge (const std::string& filename);
void load (const XMLNode*);
void save (std::ofstream& writer);
UnlockManager ();
~UnlockManager ();
void addChallenge (Challenge *c);
void addChallenge (const std::string& filename);
void save ();
std::vector<const Challenge*>
getActiveChallenges();
const std::vector<const Challenge*>
getUnlockedFeatures() {return m_unlocked_features;}
void clearUnlocked () {m_unlocked_features.clear(); }
void raceFinished ();
void grandPrixFinished ();
void unlockFeature (Challenge* c, bool save=true);
void lockFeature (Challenge* challenge);
bool isLocked (const std::string& feature);
void check () const;
void clearUnlocked () {m_unlocked_features.clear(); }
void raceFinished ();
void grandPrixFinished ();
void unlockFeature (Challenge* c, bool do_save=true);
void lockFeature (Challenge* challenge);
bool isLocked (const std::string& feature);
void check () const;
}; // UnlockManager
extern UnlockManager* unlock_manager;

View File

@ -46,7 +46,6 @@ static ptr_vector<UserConfigParam, REF> all_params;
#define PARAM_DEFAULT(X) = X
#include "config/user_config.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player.hpp"
#include "config/stk_config.hpp"
#include "io/file_manager.hpp"
@ -524,15 +523,9 @@ bool UserConfig::loadConfig(const std::string& filename)
std::string name;
players[i]->get("name", &name);
UserConfigParams::m_all_players.push_back( new PlayerProfile(name.c_str()) );
}
// --- Read challenges
unlock_manager->load(root);
}
delete root;
return true;
} // loadConfig
// -----------------------------------------------------------------------------
@ -569,9 +562,7 @@ void UserConfig::saveConfig(const std::string& filepath)
//std::cout << "saving parameter " << i << " to file\n";
all_params[i].write(configfile);
}
unlock_manager->save(configfile);
configfile << "</stkconfig>\n";
configfile.close();

View File

@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib user32.lib gdi32.lib winmm.lib advapi32.lib SDL.lib SDLmain.lib OpenAL32.lib libogg.lib libvorbis.lib libvorbisfile.lib intl.lib Irrlicht.lib ws2_32.lib"
AdditionalDependencies="opengl32.lib user32.lib gdi32.lib winmm.lib advapi32.lib OpenAL32.lib libogg.lib libvorbis.lib libvorbisfile.lib intl.lib Irrlicht.lib ws2_32.lib"
OutputFile="./../../../$(ProjectName)_d.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(STK_LIB)&quot;;&quot;$(IRR_LIB)&quot;"

View File

@ -42,6 +42,7 @@
#include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp"
#include "tracks/track_manager.hpp"
#include "utils/string_utils.hpp"
#ifdef __APPLE__
@ -128,6 +129,7 @@ FileManager::FileManager()
fprintf(stderr, "Data files will be fetched from: '%s'\n",
m_root_dir.c_str() );
TrackManager::addTrackDir(m_root_dir+"/data/tracks");
pushTextureSearchPath(m_root_dir+"/data/textures");
pushModelSearchPath (m_root_dir+"/data/models" );
pushMusicSearchPath (m_root_dir+"/data/music" );
@ -239,11 +241,6 @@ std::string FileManager::getModelFile(const std::string& FNAME) const
return path;
} // getModelFile
//-----------------------------------------------------------------------------
std::string FileManager::getTrackDir() const
{
return m_root_dir+"/data/tracks";
} // getTrackDir
//-----------------------------------------------------------------------------
std::string FileManager::getDataDir() const
{
@ -277,18 +274,6 @@ std::vector<std::string> FileManager::getMusicDirs() const
return m_music_search_path;
} // getMusicDirs
//-----------------------------------------------------------------------------
std::string FileManager::getTrackFile(const std::string& fname,
const std::string& track_name) const
{
// tracks file are in data/tracks/TRACKNAME/TRACKNAME.ext
// but if a track name is supplied use it (which is necessary
// e.g. to load a model from a track directory
std::string basename = (track_name!="") ? track_name
: StringUtils::removeExtension(fname);
return getTrackDir()+"/"+basename+"/"+fname;
} // getTrackFile
//-----------------------------------------------------------------------------
std::string FileManager::getKartFile(const std::string& fname,
const std::string& kart_name) const
@ -373,6 +358,13 @@ std::string FileManager::getHighscoreFile(const std::string& fname) const
return getHomeDir()+"/"+fname;
} // getHighscoreFile
//-----------------------------------------------------------------------------
/** Returns the full path of the challenge file. */
std::string FileManager::getChallengeFile(const std::string &fname) const
{
return getHomeDir()+"/"+fname;
} // getChallengeFile
//-----------------------------------------------------------------------------
void FileManager::listFiles(std::set<std::string>& result, const std::string& dir,
bool is_full_path, bool make_full_path) const

View File

@ -60,7 +60,6 @@ public:
XMLNode *createXMLTree(const std::string &filename);
std::string getHomeDir () const;
std::string getTrackDir () const;
std::string getKartDir () const;
std::string getDataDir () const;
std::string getItemsDir () const;
@ -70,10 +69,9 @@ public:
std::string getTextureFile (const std::string& fname) const;
std::string getKartFile (const std::string& fname,
const std::string& kart="") const;
std::string getTrackFile (const std::string& fname,
const std::string& track="") const;
std::string getConfigFile (const std::string& fname) const;
std::string getHighscoreFile (const std::string& fname) const;
std::string getChallengeFile (const std::string& fname) const;
std::string getLogFile (const std::string& fname) const;
std::string getItemFile (const std::string& fname) const;
std::string getMusicFile (const std::string& fname) const;

View File

@ -271,7 +271,7 @@ int XMLNode::get(const std::string &attribute, bool *value) const
std::string s;
if(!get(attribute, &s)) return 0;
*value = s=="" || s[0]=='T' || s[0]=='t' || s[0]=='Y' || s[0]=='y' ||
s=="true" || s=="TRUE" || s=="#t" || s=="#T";
s=="#t" || s =="#T";
return 1;
} // get(bool)

View File

@ -139,6 +139,11 @@ int handleCmdLinePreliminary(int argc, char **argv)
cmdLineHelp(argv[0]);
exit(0);
}
else if( !strcmp(argv[i], "--trackdir") && i+1<argc )
{
TrackManager::addTrackDir(argv[i+1]);
i++;
}
#if !defined(WIN32) && !defined(__CYGWIN)
else if ( !strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f"))
{
@ -157,7 +162,8 @@ int handleCmdLinePreliminary(int argc, char **argv)
UserConfigParams::m_fullscreen = false;
}
#endif
else if ( !strcmp(argv[i], "--screensize") || !strcmp(argv[i], "-s") )
else if ( (!strcmp(argv[i], "--screensize") || !strcmp(argv[i], "-s") )
&& i+1<argc)
{
//Check if fullscreen and new res is blacklisted
int width, height;
@ -176,6 +182,7 @@ int handleCmdLinePreliminary(int argc, char **argv)
}
else
fprintf ( stdout, "Resolution %s has been blacklisted, so it is not available!\n", res.c_str());
i++;
}
else
{
@ -290,6 +297,7 @@ int handleCmdLine(int argc, char **argv)
race_manager->setDifficulty(RaceManager::RD_HARD);
break;
}
i++;
}
else if( (!strcmp(argv[i], "--track") || !strcmp(argv[i], "-t"))
&& i+1<argc )
@ -311,6 +319,7 @@ int handleCmdLine(int argc, char **argv)
{
stk_config->load(file_manager->getConfigFile(argv[i+1]));
fprintf ( stdout, "STK config will be read from %s.\n", argv[i+1] ) ;
i++;
}
else if( (!strcmp(argv[i], "--numkarts") || !strcmp(argv[i], "-k")) &&
i+1<argc )
@ -398,6 +407,7 @@ int handleCmdLine(int argc, char **argv)
return 0;
}
fprintf ( stdout, "You choose to have %d players.\n", atoi(argv[i+1]) ) ;
i++;
}
*/
else if( !strcmp(argv[i], "--log=terminal"))
@ -441,13 +451,12 @@ int handleCmdLine(int argc, char **argv)
item_manager->setUserFilename(argv[i+1]);
i++;
}
else if( !strcmp(argv[i], "--trackdir") && i+1<argc )
{
track_manager->addTrackDir(argv[i+1]);
i++;
}
// these commands are already processed in handleCmdLinePreliminary, but repeat this
// just so that we don't get error messages about unknown commands
else if( !strcmp(argv[i], "--trackdir") && i+1<argc )
{
i++;
}
else if ( !strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f"))
{
}
@ -481,10 +490,10 @@ void initPreliminary()
{
file_manager = new FileManager();
translations = new Translations();
// unlock manager is needed when reading the config file
unlock_manager = new UnlockManager();
user_config = new UserConfig();
}
} // initPreliminary
//=============================================================================
void initRest()
{
irr_driver = new IrrDriver();
@ -507,8 +516,7 @@ void initRest()
stk_config->load(file_manager->getConfigFile("stk_config.xml"));
track_manager->loadTrackList();
// unlock_manager->check needs GP and track manager.
unlock_manager->check();
unlock_manager = new UnlockManager();
sound_manager->addMusicToTracks();
race_manager = new RaceManager ();
@ -597,11 +605,6 @@ int main(int argc, char *argv[] )
input_manager->setMode(InputManager::MENU);
main_loop = new MainLoop();
// loadMaterials needs ssgLoadTextures (internally), which can
// only be called after ssgInit (since this adds the actual file_manager)
// so this next call can't be in InitTuxkart. And InitPlib needs
// config, which gets defined in InitTuxkart, so swapping those two
// calls is not possible either ... so loadMaterial has to be done here :(
material_manager -> loadMaterial ();
kart_properties_manager -> loadKartData ();
projectile_manager -> loadData ();

View File

@ -39,8 +39,7 @@ PhysicalObject::PhysicalObject(const XMLNode *xml_node)
std::string model_name;
const Track *track=RaceManager::getTrack();
xml_node->get("model", &model_name);
std::string full_path = file_manager->getTrackFile(model_name,
track->getIdent());
std::string full_path = track->getTrackFile(model_name);
scene::IAnimatedMesh *obj = irr_driver->getAnimatedMesh(full_path);
if(!obj)
{

View File

@ -54,9 +54,11 @@ using namespace irr;
const float Track::NOHIT = -99999.9f;
// ----------------------------------------------------------------------------
Track::Track( std::string filename)
Track::Track(std::string filename)
{
m_filename = filename;
m_root = StringUtils::getPath(StringUtils::removeExtension(m_filename));
m_ident = StringUtils::getBasename(m_root);
m_item_style = "";
m_description = "";
m_designer = "";
@ -71,7 +73,7 @@ Track::Track( std::string filename)
m_quad_graph = NULL;
m_animation_manager = NULL;
m_check_manager = NULL;
loadTrack(m_filename);
loadTrackInfo(m_filename);
} // Track
//-----------------------------------------------------------------------------
@ -187,12 +189,8 @@ btTransform Track::getStartTransform(unsigned int pos) const
} // getStartTransform
//-----------------------------------------------------------------------------
void Track::loadTrack(const std::string &filename)
void Track::loadTrackInfo(const std::string &filename)
{
m_filename = filename;
std::string path = StringUtils::removeExtension(m_filename);
m_ident = StringUtils::getBasename(path);
// Default values
m_use_fog = false;
m_fog_density = 1.0f/100.0f;
@ -292,10 +290,10 @@ void Track::loadTrack(const std::string &filename)
loadCurves(*xml_node);
// Set the correct paths
m_screenshot = file_manager->getTrackFile(m_screenshot, getIdent());
m_screenshot = m_root+"/"+m_screenshot;
delete root;
} // loadTrack
} // loadTrackInfo
//-----------------------------------------------------------------------------
void Track::loadCurves(const XMLNode &node)
@ -313,7 +311,7 @@ void Track::getMusicInformation(std::vector<std::string>& filenames,
{
for(int i=0; i<(int)filenames.size(); i++)
{
std::string full_path = file_manager->getTrackFile(filenames[i], getIdent());
std::string full_path = m_root+"/"+filenames[i];
MusicInformation* mi;
try
{
@ -321,7 +319,7 @@ void Track::getMusicInformation(std::vector<std::string>& filenames,
}
catch(std::runtime_error)
{
mi = sound_manager->getMusicInformation(file_manager->getMusicFile(filenames[i]));
mi = sound_manager->getMusicInformation(m_root+"/"+filenames[i]);
}
if(!mi)
{
@ -347,8 +345,7 @@ void Track::startMusic() const
*/
void Track::loadQuadGraph()
{
m_quad_graph = new QuadGraph(file_manager->getTrackFile(m_ident+".quads"),
file_manager->getTrackFile(m_ident+".graph"));
m_quad_graph = new QuadGraph(m_root+"/quads.xml", m_root+"/graph.xml");
m_mini_map = m_quad_graph->makeMiniMap(RaceManager::getWorld()->getRaceGUI()->getMiniMapSize(),
"minimap::"+m_ident);
if(m_quad_graph->getNumNodes()==0)
@ -439,8 +436,7 @@ bool Track::loadMainTrack(const XMLNode &xml_node)
{
std::string model_name;
xml_node.get("model", &model_name);
std::string full_path = file_manager->getTrackFile(model_name,
getIdent());
std::string full_path = m_root+"/"+model_name;
scene::IMesh *mesh = irr_driver->getAnimatedMesh(full_path);
if(!mesh)
{
@ -563,8 +559,7 @@ void Track::createWater(const XMLNode &node)
{
std::string model_name;
node.get("model", &model_name);
std::string full_path = file_manager->getTrackFile(model_name,
getIdent());
std::string full_path = m_root+"/"+model_name;
//scene::IMesh *mesh = irr_driver->getMesh(full_path);
scene::IAnimatedMesh *mesh = irr_driver->getSceneManager()->getMesh(full_path.c_str());
@ -621,12 +616,12 @@ void Track::loadTrackModel()
// map to.
loadQuadGraph();
// Add the track directory to the texture search path
file_manager->pushTextureSearchPath(file_manager->getTrackFile("",getIdent()));
file_manager->pushModelSearchPath (file_manager->getTrackFile("",getIdent()));
file_manager->pushTextureSearchPath(m_root);
file_manager->pushModelSearchPath (m_root);
// First read the temporary materials.dat file if it exists
try
{
std::string materials_file = file_manager->getTrackFile("materials.xml",getIdent());
std::string materials_file = m_root+"/materials.xml";
material_manager->pushTempMaterial(materials_file);
}
catch (std::exception& e)
@ -636,7 +631,7 @@ void Track::loadTrackModel()
}
// Start building the scene graph
std::string path = file_manager->getTrackFile(getIdent()+".scene");
std::string path = m_root+"/scene.xml";
XMLNode *root = file_manager->createXMLTree(path);
// Make sure that we have a track (which is used for raycasts to
@ -668,8 +663,7 @@ void Track::loadTrackModel()
{
std::string model_name;
node->get("model", &model_name);
std::string full_path = file_manager->getTrackFile(model_name,
getIdent());
std::string full_path = m_root+"/"+model_name;
scene::IMesh *mesh = irr_driver->getAnimatedMesh(full_path);
if(!mesh)
{
@ -704,7 +698,7 @@ void Track::loadTrackModel()
}
else if(name=="animations")
{
m_animation_manager = new AnimationManager(getIdent(), *node);
m_animation_manager = new AnimationManager(*this, *node);
}
else if(name=="checks")
{
@ -788,7 +782,7 @@ void Track::loadTrackModel()
createPhysicsModel();
if(UserConfigParams::m_track_debug)
m_quad_graph->createDebugMesh();
} // loadTrack
} // loadTrackModel
//-----------------------------------------------------------------------------
void Track::itemCommand(const Vec3 &xyz, Item::ItemType type,

View File

@ -60,7 +60,10 @@ private:
std::string m_item_style;
std::string m_description;
std::string m_designer;
/** The full filename of the config (xml) file. */
std::string m_filename;
/** The base dir of all files of this track. */
std::string m_root;
std::vector<std::string> m_groups;
std::vector<scene::ISceneNode*> m_all_nodes;
std::vector<scene::IMesh*> m_all_meshes;
@ -129,7 +132,7 @@ private:
/** Checkline manager. */
CheckManager *m_check_manager;
void loadTrack(const std::string &filename);
void loadTrackInfo(const std::string &filename);
void itemCommand(const Vec3 &xyz, Item::ItemType item_type,
int bNeedHeight);
void loadQuadGraph();
@ -220,6 +223,9 @@ public:
*/
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *draw_at) const
{ m_quad_graph->mapPoint2MiniMap(xyz, draw_at); }
/** Returns the full path of a given file inside this track directory. */
std::string getTrackFile(const std::string &s) const
{ return m_root+"/"+s; }
}; // class Track
#endif

View File

@ -30,6 +30,7 @@
#include "tracks/track.hpp"
TrackManager* track_manager = 0;
std::vector<std::string> TrackManager::m_track_search_path;
/** Constructor (currently empty). The real work happens in loadTrackList.
*/
@ -53,12 +54,12 @@ TrackManager::~TrackManager()
*/
void TrackManager::addTrackDir(const std::string &dir)
{
m_track_dirs.push_back(dir);
m_track_search_path.push_back(dir);
} // addTrackDir
//-----------------------------------------------------------------------------
/** Get TrackData by the track identifier.
* \param ident Identifier = filename without .track
* \param ident Identifier = basename of the directory the track is in.
*/
Track* TrackManager::getTrack(const std::string& ident) const
{
@ -73,25 +74,6 @@ Track* TrackManager::getTrack(const std::string& ident) const
throw std::runtime_error(msg.str());
} // getTrack
//-----------------------------------------------------------------------------
/** Marks the specified track as unavailable (i.e. not available on all
* clients and server.
* \param ident Track identifier (i.e. track name without .track)
*/
void TrackManager::unavailable(const std::string& ident)
{
for(Tracks::const_iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
{
if ((*i)->getIdent() == ident)
{
m_track_avail[i-m_tracks.begin()] = false;
return;
}
}
// Do nothing if the track does not exist here ... it's not available.
return;
} // unavailable
//-----------------------------------------------------------------------------
/** Sets all tracks that are not in the list a to be unavailable. This is used
* by the network manager upon receiving the list of available tracks from
@ -130,46 +112,60 @@ std::vector<std::string> TrackManager::getAllTrackIdentifiers()
//-----------------------------------------------------------------------------
/** Loads all tracks from the track directory (data/track).
*/
void TrackManager::loadTrackList ()
void TrackManager::loadTrackList()
{
// Load up a list of tracks - and their names
std::set<std::string> dirs;
file_manager->listFiles(dirs, file_manager->getTrackDir(), /*is_full_path*/ true);
for(std::set<std::string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++)
m_all_track_dirs.clear();
for(unsigned int i=0; i<m_track_search_path.size(); i++)
{
if(*dir=="." || *dir=="..") continue;
std::string config_file;
try
{
// getTrackFile appends dir, so it's opening: *dir/*dir.track
// FIXME: rename from .irrtrack to .track
config_file = file_manager->getTrackFile((*dir)+".irrtrack");
}
catch (std::exception& e)
{
(void)e; // remove warning about unused variable
continue;
}
FILE *f=fopen(config_file.c_str(),"r");
if(!f) continue;
fclose(f);
const std::string &dir = m_track_search_path[i];
Track *track = new Track(config_file);
if(track->getVersion()<stk_config->m_min_track_version ||
track->getVersion()>stk_config->m_max_track_version)
// First test if the directory itself contains a track:
// ----------------------------------------------------
if(loadTrack(dir)) continue; // track found, no more tests
// Then see if a subdir of this dir contains tracks
// ------------------------------------------------
std::set<std::string> dirs;
file_manager->listFiles(dirs, dir, /*is_ileull_path*/ true);
for(std::set<std::string>::iterator subdir = dirs.begin();
subdir != dirs.end(); subdir++)
{
fprintf(stderr, "Warning: track '%s' is not supported by this binary, ignored.\n",
track->getIdent().c_str());
delete track;
continue;
}
m_tracks.push_back(track);
m_track_avail.push_back(true);
updateGroups(track);
// Read music files in that dir as well
sound_manager->loadMusicFromOneDir(*dir);
}
if(*subdir=="." || *subdir=="..") continue;
loadTrack(dir+"/"+*subdir);
} // for dir in dirs
} // for i <m_track_search_path.size()
} // loadTrackList
// ----------------------------------------------------------------------------
/** Tries to load a track from a single directory. Returns true if a track was
* successfully loaded.
* \param dirname Name of the directory to load the track from.
*/
bool TrackManager::loadTrack(const std::string& dirname)
{
std::string config_file = dirname+"/track.xml";
FILE *f=fopen(config_file.c_str(),"r");
if(!f) return false;
fclose(f);
Track *track = new Track(config_file);
if(track->getVersion()<stk_config->m_min_track_version ||
track->getVersion()>stk_config->m_max_track_version)
{
fprintf(stderr, "Warning: track '%s' is not supported by this binary, ignored.\n",
track->getIdent().c_str());
delete track;
return false;
}
m_all_track_dirs.push_back(dirname);
m_tracks.push_back(track);
m_track_avail.push_back(true);
updateGroups(track);
// Read music files in that dir as well
sound_manager->loadMusicFromOneDir(dirname);
return true;
} // loadTrack
// ----------------------------------------------------------------------------
/** Updates the groups after a track was read in.
* \param track Pointer to the new track, whose groups are now analysed.

View File

@ -32,11 +32,17 @@ class TrackManager
{
private:
/** All directories in which tracks are searched. */
std::vector<std::string> m_track_dirs;
static std::vector<std::string> m_track_search_path;
/** All directories in which tracks were found. */
std::vector<std::string> m_all_track_dirs;
/** All track objects. */
typedef std::vector<Track*> Tracks;
Tracks m_tracks;
Tracks m_tracks;
/** List of all racing track groups. */
std::map<std::string, std::vector<int> > m_groups;
/** List of all arena groups. */
std::map<std::string, std::vector<int> > m_arena_groups;
/** List of all groups. */
std::vector<std::string> m_all_groups;
/** Flag if this track is available or not. Tracks are set unavailable
* if they are not available on all clients (applies only to network mode)
@ -44,27 +50,44 @@ private:
std::vector<bool> m_track_avail;
void updateGroups(const Track* track);
bool loadTrack(const std::string& dirname);
public:
TrackManager();
~TrackManager();
void addTrackDir(const std::string &dir);
static void addTrackDir(const std::string &dir);
/** Returns a list of all directories that contain a track. */
const std::vector<std::string>* getAllTrackDirs() const
{ return &m_all_track_dirs; }
/** Returns a list of all used track groups. */
const std::vector<std::string>&
getAllGroups() const { return m_all_groups; }
/** Returns the number of tracks. */
size_t getNumberOfTracks() const { return m_tracks.size(); }
Track *getTrack(size_t id) const { return m_tracks[id]; }
/** Returns the track with a given index number.
* \param index The index number of the track. */
Track *getTrack(unsigned int index) const { return m_tracks[index];}
Track *getTrack(const std::string& ident) const;
void unavailable(const std::string &ident);
/** Sets a list of track as being unavailable (e.g. in network mode the
* track is not on all connected machines.
* \param tracks List of tracks to mark as unavilable. */
void setUnavailableTracks(const std::vector<std::string> &tracks);
/** Checks if a certain track is available.
* \param n Index of the track to check. */
bool isAvailable(unsigned int n) const {return m_track_avail[n];}
/** Returns a list of all tracks in a given group.
* \param g Name of the group. */
const std::vector<int>&
getTracksInGroup(const std::string& g) {return m_groups[g];}
/** Returns a list of all arenas in a given group.
* \param g Name of the group. */
const std::vector<int>&
getArenasInGroup(const std::string& g) {return m_arena_groups[g];}
/** Returns a list of all track identifiers. */
std::vector<std::string> getAllTrackIdentifiers();
/** load all .track files from all directories */
void loadTrackList ();
/** Load all .track files from all directories */
void loadTrackList();
};
extern TrackManager* track_manager;