/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli co-programmer: ... */ #include "game_loader.h" #include "campaign.h" #include "world.h" #include "player.h" #include "orxonox.h" #include "camera.h" #include "command_node.h" #include "vector.h" #include "factory.h" #include using namespace std; GameLoader* GameLoader::singletonRef = 0; GameLoader::GameLoader () { first = NULL; } GameLoader::~GameLoader () {} /** \brief this class is a singleton class \returns an instance of itself if you are unsure about singleton classes, check the theory out on the internet :) */ GameLoader* GameLoader::getInstance() { if(singletonRef == NULL) singletonRef = new GameLoader(); return singletonRef; } ErrorMessage GameLoader::init() { if(this->currentCampaign != NULL) this->currentCampaign->init(); } /** \brief reads a campaign definition file into a campaign class \param filename to be loaded \returns the loaded campaign this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns */ ErrorMessage GameLoader::loadCampaign(char* name) { ErrorMessage errorCode; this->currentCampaign = this->fileToCampaign(name); } /** \brief loads a debug campaign for test purposes only. \param the identifier of the campaign. \returns error message if not able to do so. */ ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID) { switch(campaignID) { // Debug Level 0: Debug level used to test the base frame work. case DEBUG_CAMPAIGN_0: { Campaign* debugCampaign = new Campaign(); World* world0 = new World(DEBUG_WORLD_0); world0->setNextStoryID(WORLD_ID_1); debugCampaign->addEntity(world0, WORLD_ID_0); World* world1 = new World(DEBUG_WORLD_1); world1->setNextStoryID(WORLD_ID_GAMEEND); debugCampaign->addEntity(world1, WORLD_ID_1); this->currentCampaign = debugCampaign; break; } } } ErrorMessage GameLoader::start() { if(this->currentCampaign != NULL) this->currentCampaign->start(); } ErrorMessage GameLoader::stop() { if(this->currentCampaign != NULL) this->currentCampaign->stop(); this->currentCampaign = NULL; } ErrorMessage GameLoader::pause() { this->isPaused = true; if(this->currentCampaign != NULL) this->currentCampaign->pause(); } ErrorMessage GameLoader::resume() { this->isPaused = false; if(this->currentCampaign != NULL) this->currentCampaign->resume(); } /** \brief release the mem */ ErrorMessage GameLoader::destroy() {} /** \brief reads a campaign definition file into a campaign class \param filename to be loaded \returns the loaded campaign this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns */ Campaign* GameLoader::fileToCampaign(char *name) { /* do not entirely load the campaign. just the current world before start of each world, it has to be initialized so it can load everything it needs into memory then. */ if( name == NULL) { PRINTF0("No filename specified for loading"); return NULL; } TiXmlDocument* XMLDoc = new TiXmlDocument( name); // load the campaign document if( !XMLDoc->LoadFile()) { // report an error PRINTF0("Error loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol()); delete XMLDoc; return NULL; } // check basic validity TiXmlElement* root = XMLDoc->RootElement(); assert( root != NULL); if( strcmp( root->Value(), "Campaign")) { // report an error PRINTF0("Specified XML File is not an orxonox campaign file (Campaign element missing)\n"); delete XMLDoc; return NULL; } // construct campaign Campaign* c = new Campaign( root); // free the XML data delete XMLDoc; return c; } /** \brief handle keyboard commands \param cmd: the command to handle \returns true if the command was handled by the system */ bool GameLoader::worldCommand (Command* cmd) { if( !strcmp( cmd->cmd, "up_world")) { if( !cmd->bUp) { this->nextLevel(); } return true; } else if( !strcmp( cmd->cmd, "down_world")) { if( !cmd->bUp) { this->previousLevel(); } return true; } else if( !strcmp( cmd->cmd, "pause")) { if( !cmd->bUp) { if(this->isPaused) this->resume(); else this->pause(); } return true; } else if( !strcmp( cmd->cmd, "quit")) { if( !cmd->bUp) this->stop(); return true; } return false; } /* \brief this changes to the next level */ void GameLoader::nextLevel() { if(this->currentCampaign != NULL) this->currentCampaign->nextLevel(); } /* \brief change to the previous level - not implemented this propably useless */ void GameLoader::previousLevel() { if(this->currentCampaign != NULL) this->currentCampaign->previousLevel(); } /** \brief add a Factory to the Factory Q \param factory a Factory to be registered */ void GameLoader::registerFactory( Factory* factory) { assert( factory != NULL); PRINTF0("Registered factory for '%s'\n", factory->getClassname()); if( first == NULL) first = factory; else first->registerFactory( factory); } /** \brief load a StoryEntity \param element a XMLElement containing all the needed info */ BaseObject* GameLoader::fabricate( TiXmlElement* element) { assert( element != NULL); if( first == NULL) { PRINTF0("GameLoader does not know any factories, fabricate() failed\n"); return NULL; } if( element->Value() != NULL) { PRINTF0("Attempting fabrication of a '%s'\n", element->Value()); BaseObject* b = first->fabricate( element); if( b == NULL) PRINTF0("Failed to fabricate a '%s'\n", element->Value()); else PRINTF0("Successfully fabricated a '%s'\n", element->Value()); return b; } PRINTF0("Fabricate failed, TiXmlElement did not contain a value\n"); return NULL; }