/* 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 "campaign.h" #include "game_loader.h" #include "story_entity.h" #include "world.h" #include "camera.h" #include "list.h" #include "load_param.h" using namespace std; Campaign::Campaign () { this->setClassID(CL_CAMPAIGN, "Campaign"); this->entities = new tList(); this->isInit = false; } Campaign::Campaign ( TiXmlElement* root) { this->setClassID(CL_CAMPAIGN, "Campaign"); PRINTF(4)("Loading Campaign...\n"); assert( root != NULL); this->entities = new tList(); this->isInit = false; this->loadParams(root); //if( lastCreated != NULL) //lastCreated->setStoryID( WORLD_ID_GAMEEND); } Campaign::~Campaign () {} ErrorMessage Campaign::init() { this->isInit = true; } /** \brief loads the Parameters of a Campaign * @param root: The XML-element to load from */ void Campaign::loadParams(const TiXmlElement* root) { static_cast(this)->loadParams(root); LoadParam(root, "identifier", this, &Campaign::setStoryID) .describe("A Unique Identifier for this Campaign"); LoadParam(root, "WorldList", this, &Campaign::loadWorldListParams) .describe("A List of Worlds to be loaded in this Campaign"); } /** \brief loads a WorldList * @param root: the XML-element to load from */ void Campaign::loadWorldListParams(const TiXmlElement* root) { const TiXmlElement* element = root->FirstChildElement(); // load Worlds/Subcampaigns/Whatever StoryEntity* lastCreated = NULL; while( element != NULL) { PRINTF(5)("Campaign: Constructor: adding a world\n"); StoryEntity* created = (StoryEntity*) GameLoader::getInstance()->fabricate(element); /* if( lastCreated != NULL) created->setNextStoryID( lastCreated->getStoryID()); else created->setNextStoryID( WORLD_ID_GAMEEND); */ if( created != NULL) { this->addEntity( created); lastCreated = created; } element = element->NextSiblingElement(); } } ErrorMessage Campaign::start() { this->start(0); } //! @todo boky -> fix it ErrorMessage Campaign::start(int storyID = 0) { ErrorMessage errorCode; if( !this->isInit) return errorCode; if( storyID == WORLD_ID_GAMEEND) return errorCode; this->running = true; StoryEntity* se = this->getStoryEntity(storyID); this->currentEntity = se; while( se != NULL && this->running) { PRINTF(0)("Starting new StoryEntity Nr:%i\n", se->getStoryID()); se->displayLoadScreen(); se->preLoad(); se->load(); se->init(); se->releaseLoadScreen(); se->start(); se->destroy(); int nextWorldID = se->getNextStoryID(); this->entities->remove(se); delete se; //printf("Campaing::start() - got nextWorldID = %i\n", nextWorldID); se = this->getStoryEntity(nextWorldID); this->currentEntity = se; if( ( nextWorldID == WORLD_ID_GAMEEND) ||( se == NULL) ) { PRINTF(4)("Quitting campaing story loop\n"); if(se != NULL) delete se; return errorCode; } } /* clean up all world that have not been loaded and therefore are still in the world list - this probably does not belong into the start function. remove this later */ tIterator* it = this->entities->getIterator(); se = it->firstElement(); while( se != NULL) { delete se; se = it->nextElement(); } delete this->entities; delete it; } ErrorMessage Campaign::pause() { if(this->currentEntity != NULL) this->isPaused = true; } ErrorMessage Campaign::resume() { if(this->currentEntity != NULL) this->isPaused = false; } ErrorMessage Campaign::stop() { this->running = false; if(this->currentEntity != NULL) { this->currentEntity->stop(); } } ErrorMessage Campaign::destroy() { if(this->currentEntity != NULL) { this->currentEntity->destroy(); delete this->currentEntity; this->currentEntity = NULL; } } /** * adds an game stroy entity to the campaign * @param se: The entity * @param storyID: The number that identifies the entity in the campaign. Each ID only used once in a Campaign An entity can be a world (playable), a cinematic, a shop, sounds, whatever you want to queue up in the campaign. */ void Campaign::addEntity(StoryEntity* se, int storyID) { se->setStoryID(storyID); this->addEntity(se); } void Campaign::addEntity(StoryEntity* se) { this->entities->add(se); } void Campaign::removeEntity(int storyID) { this->removeEntity(this->getStoryEntity(storyID)); } void Campaign::removeEntity(StoryEntity* se) { this->entities->remove(se); } /* \brief this changes to the next level */ void Campaign::nextLevel() { PRINTF(4)("Campaign:nextLevel()\n"); this->currentEntity->stop(); } /* \brief change to the previous level - not implemented this propably useless */ void Campaign::previousLevel() {} /* \brief lookup a entity with a given id * @param story id to be lookuped @returns the entity found or NULL if search ended without match */ StoryEntity* Campaign::getStoryEntity(int storyID) { //printf("Campaing::getStoryEntity(%i) - getting next Entity\n", storyID); if( storyID == WORLD_ID_GAMEEND) return NULL; /* tList* l; StoryEntity* entity = NULL; l = this->entities->getNext(); while( l != NULL) { entity = l->getObject(); l = l->getNext(); int id = entity->getStoryID(); //printf("Campaing::getStoryEntity() - now looping, found entity nr=%i\n", id); if(id == storyID) { //printf("Campaing::getStoryEntity() - yea, this is what we where looking for: %id\n"); return entity; } } */ tIterator* iterator = this->entities->getIterator(); StoryEntity* entity = iterator->firstElement(); while( entity != NULL) { int id = entity->getStoryID(); //printf("Campaing::getStoryEntity() - now looping, found entity nr=%i\n", id); if(id == storyID) { //printf("Campaing::getStoryEntity() - yea, this is what we where looking for: %id\n"); delete iterator; return entity; } entity = iterator->nextElement(); } delete iterator; return NULL; }