Changeset 6358 in orxonox.OLD for branches/network/src/story_entities/single_player_world.cc
- Timestamp:
- Dec 30, 2005, 10:49:00 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/network/src/story_entities/single_player_world.cc
r6354 r6358 11 11 ### File Specific: 12 12 main-programmer: Patrick Boenzli 13 co-programmer: Christian Meyer14 co-programmer: Benjamin Grauer15 13 */ 16 14 17 15 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD 18 16 19 #include " world.h"17 #include "single_player_world.h" 20 18 21 #include "shell_command.h"22 #include "resource_manager.h"23 19 #include "state.h" 20 #include "class_list.h" 24 21 25 #include "p_node.h"26 #include "world_entity.h"27 #include "player.h"28 #include "camera.h"29 #include "environment.h"30 #include "terrain.h"31 32 #include "test_entity.h"33 #include "terrain.h"34 #include "light.h"35 22 #include "load_param.h" 36 #include "shell.h"37 38 23 #include "fast_factory.h" 39 #include "animation_player.h"40 #include "particle_engine.h"41 #include "graphics_engine.h"42 #include "physics_engine.h"43 #include "fields.h"44 45 #include "md2Model.h"46 47 #include "glmenu_imagescreen.h"48 #include "game_loader.h"49 50 #include "animation3d.h"51 52 #include "substring.h"53 54 24 #include "factory.h" 55 25 56 #include "weapons/projectile.h"57 #include "event_handler.h"58 #include "sound_engine.h"59 #include "ogg_player.h"60 26 61 #include "class_list.h"62 63 #include "cd_engine.h"64 #include "npcs/npc_test1.h"65 #include "shader.h"66 67 #include "playable.h"68 #include "network_manager.h"69 #include "playable.h"70 71 72 SHELL_COMMAND(speed, World, setSpeed);73 SHELL_COMMAND(togglePNodeVisibility, World, togglePNodeVisibility);74 SHELL_COMMAND(toggleBVVisibility, World, toggleBVVisibility);75 27 76 28 using namespace std; 77 29 78 //! This creates a Factory to fabricate a World79 CREATE_FACTORY( World, CL_WORLD);30 //! This creates a Factory to fabricate a SinglePlayerWorld 31 CREATE_FACTORY(SinglePlayerSinglePlayerWorld, CL_SINGLE_PLAYER_WORLD); 80 32 81 World::World(const TiXmlElement* root) 33 34 35 SinglePlayerWorld::SinglePlayerWorld(const TiXmlElement* root) 36 : GameWorld(root) 82 37 { 83 this->constuctorInit("", -1);84 this->path = NULL;85 86 38 this->loadParams(root); 87 39 } 88 40 41 89 42 /** 90 * remove the World from memory43 * remove the SinglePlayerWorld from memory 91 44 * 92 45 * delete everything explicitly, that isn't contained in the parenting tree! 93 46 * things contained in the tree are deleted automaticaly 94 47 */ 95 World::~World ()48 SinglePlayerWorld::~SinglePlayerWorld () 96 49 { 97 delete this->shell;98 PRINTF(3)("World::~World() - deleting current world\n"); 50 PRINTF(3)("SinglePlayerWorld::~SinglePlayerWorld() - deleting current world\n"); 51 } 99 52 100 delete this->localPlayer;101 102 // delete all the initialized Engines.103 FastFactory::flushAll(true);104 delete LightManager::getInstance();105 delete ParticleEngine::getInstance();106 delete AnimationPlayer::getInstance();107 delete PhysicsEngine::getInstance();108 109 // external engines initialized by the orxonox-class get deleted110 SoundEngine::getInstance()->flushAllBuffers();111 SoundEngine::getInstance()->flushAllSources();112 113 if (State::getObjectManager() == &this->objectManager)114 State::setObjectManager(NULL);115 // erease everything that is left.116 delete PNode::getNullParent();117 118 //secondary cleanup of PNodes;119 const std::list<BaseObject*>* nodeList = ClassList::getList(CL_PARENT_NODE);120 if (nodeList != NULL)121 while (!nodeList->empty())122 delete nodeList->front();123 124 Shader::suspendShader();125 126 // unload the resources !!127 ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);128 }129 53 130 54 /** … … 139 63 * NO LEVEL LOADING HERE - NEVER! 140 64 */ 141 void World::constuctorInit(const char* name, int worldID)65 void SinglePlayerWorld::constuctorInit(const char* name, int worldID) 142 66 { 143 this->setClassID(CL_WORLD, "World"); 67 this->setClassID(CL_SINGLE_PLAYER_WORLD, "SinglePlayerSinglePlayerWorld"); 68 this->setName(name); 144 69 145 this->setName(name);146 70 this->gameTime = 0.0f; 147 71 this->setSpeed(1.0); … … 155 79 } 156 80 81 157 82 /** 158 * loads the parameters of a World from an XML-element83 * loads the parameters of a SinglePlayerWorld from an XML-element 159 84 * @param root the XML-element to load from 160 85 */ 161 void World::loadParams(const TiXmlElement* root)86 void SinglePlayerWorld::loadParams(const TiXmlElement* root) 162 87 { 163 PRINTF(4)("Creating a World\n");88 static_cast<GameWorld*>(this)->loadParams(root); 164 89 165 LoadParam(root, "identifier", this, World, setStoryID)166 .describe("Sets the StoryID of this world"); 90 PRINTF(4)("Creating a SinglePlayerWorld\n"); 91 } 167 92 168 LoadParam(root, "nextid", this, World, setNextStoryID)169 .describe("Sets the ID of the next world");170 93 171 LoadParam(root, "path", this, World, setPath)172 .describe("The Filename of this World (relative from the data-dir)");173 }174 94 175 95 /** … … 178 98 * since the load function sometimes needs data, that has been initialized 179 99 * before the load and after the proceeding storyentity has finished 180 */181 ErrorMessage World::preLoad()100 */ 101 ErrorMessage GameWorld::preLoad() 182 102 { 183 State::setObjectManager(&this->objectManager); 184 this->cycle = 0; 103 static_cast<GameWorld*>(this)->preLoad(); 185 104 186 /* init the world interface */ 187 this->shell = new Shell(); 188 189 LightManager::getInstance(); 190 PNode::getNullParent(); 191 192 AnimationPlayer::getInstance(); // initializes the animationPlayer 193 ParticleEngine::getInstance(); 194 PhysicsEngine::getInstance(); 195 196 this->localCamera = new Camera(); 197 this->localCamera->setName ("World-Camera"); 198 199 State::setCamera(this->localCamera, this->localCamera->getTarget()); 200 201 GraphicsEngine::getInstance()->displayFPS(true); 202 this->displayLoadScreen(); 105 /* the the single player specific stuff */ 203 106 } 204 107 205 108 206 109 /** 207 * loads the World by initializing all resources, and set their default values.110 * loads the GameWorld by initializing all resources, and set their default values. 208 111 */ 209 ErrorMessage World::load()112 ErrorMessage GameWorld::load() 210 113 { 211 PRINTF(3)("> Loading world: '%s'\n", getPath()); 212 TiXmlElement* element; 213 GameLoader* loader = GameLoader::getInstance(); 114 static_cast<GameWorld*>(this)->load(); 214 115 215 if( getPath() == NULL) 216 { 217 PRINTF(1)("World has no path specified for loading"); 218 return (ErrorMessage){213,"Path not specified","World::load()"}; 219 } 116 /* the the single player specific stuff here */ 220 117 221 TiXmlDocument* XMLDoc = new TiXmlDocument( getPath()); 222 // load the campaign document 223 if( !XMLDoc->LoadFile()) 224 { 225 // report an error 226 PRINTF(1)("loading XML File: %s @ %s:l%d:c%d\n", XMLDoc->ErrorDesc(), this->getPath(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol()); 227 delete XMLDoc; 228 return (ErrorMessage){213,"XML File parsing error","World::load()"}; 229 } 230 231 // check basic validity 232 TiXmlElement* root = XMLDoc->RootElement(); 233 assert( root != NULL); 234 235 if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile")) 236 { 237 // report an error 238 PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n"); 239 delete XMLDoc; 240 return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"}; 241 } 242 243 // load the parameters 244 // name 245 const char* string = grabParameter( root, "name"); 246 if( string == NULL) 247 { 248 PRINTF(2)("World is missing a proper 'name'\n"); 249 this->setName("Unknown"); 250 } 251 else 252 { 253 this->setName(string); 254 } 255 256 //////////////// 257 // LOADSCREEN // 258 //////////////// 259 element = root->FirstChildElement("LoadScreen"); 260 if (element == NULL) 261 { 262 PRINTF(2)("no LoadScreen specified, loading default\n"); 263 264 glmis->setBackgroundImage("pictures/load_screen.jpg"); 265 this->glmis->setMaximum(8); 266 this->glmis->draw(); 267 } 268 else 269 { 270 this->glmis->loadParams(element); 271 this->glmis->draw(); 272 } 273 this->glmis->draw(); 274 275 //////////////////////// 276 // find WorldEntities // 277 //////////////////////// 278 279 element = root->FirstChildElement("WorldEntities"); 280 281 if( element == NULL) 282 { 283 PRINTF(1)("World is missing 'WorldEntities'\n"); 284 } 285 else 286 { 287 element = element->FirstChildElement(); 288 // load Players/Objects/Whatever 289 PRINTF(4)("Loading WorldEntities\n"); 290 while( element != NULL) 291 { 292 BaseObject* created = Factory::fabricate(element); 293 if( created != NULL ) 294 { 295 if(created->isA(CL_WORLD_ENTITY)) 296 this->spawn(dynamic_cast<WorldEntity*>(created)); 297 printf("Created a %s: %s\n", created->getClassName(), created->getName()); 298 } 299 300 // if we load a 'Player' we use it as localPlayer 301 302 303 //todo do this more elegant 304 if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) 305 this->sky = dynamic_cast<WorldEntity*>(created); 306 if( element->Value() != NULL && !strcmp( element->Value(), "Terrain")) 307 { 308 terrain = dynamic_cast<Terrain*>(created); 309 CDEngine::getInstance()->setTerrain(terrain); 310 } 311 element = element->NextSiblingElement(); 312 glmis->step(); //! @todo temporary 313 } 314 PRINTF(4)("Done loading WorldEntities\n"); 315 } 316 317 ////////////////////////////// 318 // LOADING ADDITIONAL STUFF // 319 ////////////////////////////// 320 321 LoadParamXML(root, "LightManager", LightManager::getInstance(), LightManager, loadParams); 322 323 LoadParamXML(root, "ParticleEngine", ParticleEngine::getInstance(), ParticleEngine, loadParams); 324 // LoadParamXML(root, "PhysicsEngine", PhysicsEngine::getInstance(), PhysicsEngine, loadParams); 325 326 // free the XML data 327 328 delete XMLDoc; 329 /* GENERIC LOADING PROCESS FINISHED */ 330 331 332 // Create a Player 333 this->localPlayer = new Player(); 334 335 Playable* playable; 336 const list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE); 337 if (playableList != NULL) 338 { 339 playable = dynamic_cast<Playable*>(playableList->front()); 340 this->localPlayer->setControllable(playable); 341 } 342 343 344 // //localCamera->setParent(TrackNode::getInstance()); 345 // tn->addChild(this->localCamera); 346 localCamera->setClipRegion(1, 10000.0); 347 // localCamera->lookAt(playable); 348 // this->localPlayer->setParentMode(PNODE_ALL); 349 if (this->sky != NULL) 350 { 351 this->localCamera->addChild(sky); 352 } 353 SoundEngine::getInstance()->setListener(this->localCamera); 354 355 356 357 //////////// 358 // STATIC // 359 //////////// 360 361 362 // TestEntity* testEntity = new TestEntity(); 363 // testEntity->setRelCoor(Vector(570, 10, -15)); 364 // testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0))); 365 // this->spawn(testEntity); 366 118 /* some static world entities */ 367 119 for(int i = 0; i < 100; i++) 368 120 { … … 370 122 char npcChar[10]; 371 123 sprintf (npcChar, "NPC_%d", i); 372 124 tmp->setName(npcChar); 373 125 tmp->setAbsCoor(((float)rand()/RAND_MAX) * 5000, 50/*+ (float)rand()/RAND_MAX*20*/, ((float)rand()/RAND_MAX -.5) *30); 374 126 this->spawn(tmp); 375 127 } 376 377 this->music = NULL;378 //(OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);379 //music->playback();380 }381 382 ErrorMessage World::postLoad()383 {384 this->releaseLoadScreen();385 128 } 386 129 387 130 388 131 /** 389 * initializes a new World shortly before start 390 * 391 * this is the function, that will be loaded shortly before the world is 392 * started 393 */ 394 ErrorMessage World::preStart() 132 * post loads the GameWorld by initializing all resources, and set their default values. 133 */ 134 ErrorMessage GameWorld::postLoad() 395 135 { 396 this->bPause = false;136 static_cast<GameWorld*>(this)->postLoad(); 397 137 398 /* update the object position before game start - so there are no wrong coordinates used in the first processing */ 399 PNode::getNullParent()->updateNode (0.001f); 400 PNode::getNullParent()->updateNode (0.001f); 138 /* the single player specific stuff here */ 401 139 } 402 403 404 /**405 * starts the World406 */407 ErrorMessage World::start()408 {409 this->bQuitWorld = false;410 this->mainLoop();411 }412 413 /**414 * stops the world.415 416 This happens, when the player decides to end the Level.417 */418 ErrorMessage World::stop()419 {420 PRINTF(3)("World::stop() - got stop signal\n");421 this->bQuitWorld= true;422 }423 424 /**425 * pauses the Game426 */427 ErrorMessage World::pause()428 {429 this->isPaused = true;430 }431 432 /**433 * ends the pause Phase434 */435 ErrorMessage World::resume()436 {437 this->isPaused = false;438 }439 440 /**441 * destroys the World442 */443 ErrorMessage World::destroy()444 {445 446 }447 448 /**449 * shows the loading screen450 */451 void World::displayLoadScreen ()452 {453 PRINTF(3)("World::displayLoadScreen - start\n");454 455 //GLMenuImageScreen*456 this->glmis = new GLMenuImageScreen();457 this->glmis->setMaximum(8);458 459 PRINTF(3)("World::displayLoadScreen - end\n");460 }461 462 /**463 * @brief removes the loadscreen, and changes over to the game464 *465 * @todo take out the delay466 */467 void World::releaseLoadScreen ()468 {469 PRINTF(3)("World::releaseLoadScreen - start\n");470 this->glmis->setValue(this->glmis->getMaximum());471 PRINTF(3)("World::releaseLoadScreen - end\n");472 delete this->glmis;473 }474 475 476 /**477 * this returns the current game time478 * @returns elapsed game time479 */480 double World::getGameTime()481 {482 return this->gameTime;483 }484 485 486 487 /**488 * synchronize local data with remote data489 */490 void World::synchronize ()491 {492 // Get remote input493 // Update synchronizables494 /* NetworkManager::getInstance()->synchronize();*/495 }496 497 498 /**499 * run all input processing500 501 the command node is the central input event dispatcher. the node uses the even-queue from502 sdl and has its own event-passing-queue.503 */504 void World::handleInput ()505 {506 EventHandler::getInstance()->process();507 508 // remoteinput509 }510 511 void World::tick(std::list<WorldEntity*> entityList, float dt)512 {513 std::list<WorldEntity*>::iterator entity;514 for (entity = entityList.begin(); entity != entityList.end(); entity++)515 (*entity)->tick(dt);516 517 }518 519 /**520 * advance the timeline521 522 this calculates the time used to process one frame (with all input handling, drawing, etc)523 the time is mesured in ms and passed to all world-entities and other classes that need524 a heart-beat.525 */526 void World::tick ()527 {528 Uint32 currentFrame = SDL_GetTicks();529 if(!this->bPause)530 {531 this->dt = currentFrame - this->lastFrame;532 533 if( this->dt > 10)534 {535 float fps = 1000/dt;536 537 // temporary, only for showing how fast the text-engine is538 char tmpChar[20];539 sprintf(tmpChar, "fps: %4.0f", fps);540 }541 else542 {543 /* the frame-rate is limited to 100 frames per second, all other things are for544 nothing.545 */546 PRINTF(3)("fps = 1000 - frame rate is adjusted\n");547 SDL_Delay(10-dt);548 this->dt = 10;549 }550 551 this->dtS = (float)this->dt / 1000.0 * this->speed;552 this->gameTime += this->dtS;553 554 this->tick(this->objectManager.getObjectList(OM_DEAD_TICK), this->dtS);555 this->tick(this->objectManager.getObjectList(OM_COMMON), this->dtS);556 this->tick(this->objectManager.getObjectList(OM_GROUP_00), this->dtS);557 this->tick(this->objectManager.getObjectList(OM_GROUP_01), this->dtS);558 this->tick(this->objectManager.getObjectList(OM_GROUP_01_PROJ), this->dtS);559 560 /* update tick the rest */561 this->localCamera->tick(this->dtS);562 // tick the engines563 AnimationPlayer::getInstance()->tick(this->dtS);564 // if (this->cycle > 5)565 PhysicsEngine::getInstance()->tick(this->dtS);566 567 ParticleEngine::getInstance()->tick(this->dtS);568 569 570 /** actualy the Graphics Engine should tick the world not the other way around...571 but since we like the things not too complicated we got it this way around572 until there is need or time to do it the other way around.573 @todo: GraphicsEngine ticks world: separation of processes and data...574 575 bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,576 beceause graphics have nothing(or at least not much) to do with Motion.577 */578 GraphicsEngine::getInstance()->tick(this->dtS);579 }580 this->lastFrame = currentFrame;581 }582 583 584 /**585 * this function gives the world a consistant state586 587 after ticking (updating the world state) this will give a constistant588 state to the whole system.589 */590 void World::update()591 {592 GraphicsEngine::getInstance()->update(this->dtS);593 PNode::getNullParent()->updateNode (this->dtS);594 SoundEngine::getInstance()->update();595 //music->update();596 }597 598 599 void World::collide()600 {601 CDEngine::getInstance()->checkCollisions(this->objectManager.getObjectList(OM_GROUP_00),602 this->objectManager.getObjectList(OM_GROUP_01_PROJ));603 CDEngine::getInstance()->checkCollisions(this->objectManager.getObjectList(OM_GROUP_01),604 this->objectManager.getObjectList(OM_COMMON));605 }606 607 /**608 * render the current frame609 610 clear all buffers and draw the world611 */612 void World::display ()613 {614 // clear buffer615 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);616 // set camera617 this->localCamera->apply ();618 // draw world619 this->draw();620 // draw HUD621 /** @todo draw HUD */622 // flip buffers623 GraphicsEngine::swapBuffers();624 //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();625 //SDL_Flip (screen);626 }627 628 629 /**630 * runs through all entities calling their draw() methods631 */632 void World::draw ()633 {634 GraphicsEngine* engine = GraphicsEngine::getInstance();635 engine->draw(State::getObjectManager()->getObjectList(OM_ENVIRON_NOTICK));636 engine->draw(State::getObjectManager()->getObjectList(OM_ENVIRON));637 engine->draw(State::getObjectManager()->getObjectList(OM_COMMON));638 engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_00));639 engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_01));640 engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_01_PROJ));641 642 if( unlikely( this->showBV)) // to draw the bounding boxes of the objects at level 2 for debug purp643 {644 CDEngine* engine = CDEngine::getInstance();645 engine->drawBV(State::getObjectManager()->getObjectList(OM_ENVIRON_NOTICK));646 engine->drawBV(State::getObjectManager()->getObjectList(OM_ENVIRON));647 engine->drawBV(State::getObjectManager()->getObjectList(OM_COMMON));648 engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_00));649 engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_01));650 engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_01_PROJ));651 }652 653 // {654 // if( entity->isVisible() ) entity->draw();655 //FIXME656 // entity = iterator->nextElement();657 // }658 659 ParticleEngine::getInstance()->draw();660 661 if (unlikely(this->showPNodes))662 PNode::getNullParent()->debugDraw(0);663 664 engine->draw();665 //TextEngine::getInstance()->draw();666 }667 668 669 /**670 * \brief main loop of the world: executing all world relevant function671 *672 * in this loop we synchronize (if networked), handle input events, give the heart-beat to673 * all other member-entities of the world (tick to player, enemies etc.), checking for674 * collisions drawing everything to the screen.675 */676 void World::mainLoop()677 {678 this->lastFrame = SDL_GetTicks ();679 PRINTF(3)("World::mainLoop() - Entering main loop\n");680 681 while(!this->bQuitWorld) /* @todo implement pause */682 {683 ++this->cycle;684 // Network685 this->synchronize ();686 // Process input687 this->handleInput ();688 if( this->bQuitWorld)689 break;690 // Process time691 this->tick ();692 // Process collision693 this->collide ();694 // Update the state695 this->update ();696 // Draw697 this->display ();698 }699 700 PRINTF(3)("World::mainLoop() - Exiting the main loop\n");701 }702 703 704 705 /**706 * add and spawn a new entity to this world707 * @param entity to be added708 */709 void World::spawn(WorldEntity* entity)710 {711 // this->entities->add (entity);712 entity->postSpawn ();713 }714 715 void World::setPath( const char* name)716 {717 if (this->path)718 delete this->path;719 if (ResourceManager::isFile(name))720 {721 this->path = new char[strlen(name)+1];722 strcpy(this->path, name);723 }724 else725 {726 this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];727 sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);728 }729 }730 731 const char* World::getPath( void)732 {733 return path;734 }
Note: See TracChangeset
for help on using the changeset viewer.