Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/story_entities/world.cc @ 5357

Last change on this file since 5357 was 5355, checked in by bensch, 19 years ago

orxonox/trunk: some build-efficiency-issues

File size: 29.2 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "shell_command.h"
23
24#include "state.h"
25
26#include "p_node.h"
27#include "null_parent.h"
28#include "pilot_node.h"
29#include "track_node.h"
30#include "world_entity.h"
31#include "player.h"
32#include "camera.h"
33#include "environment.h"
34#include "skysphere.h"
35#include "skybox.h"
36#include "satellite.h"
37#include "test_entity.h"
38#include "terrain.h"
39#include "light.h"
40#include "load_param.h"
41#include "shell.h"
42
43#include "track_manager.h"
44#include "garbage_collector.h"
45#include "fast_factory.h"
46#include "animation_player.h"
47#include "particle_engine.h"
48#include "graphics_engine.h"
49#include "physics_engine.h"
50#include "fields.h"
51
52#include "md2Model.h"
53
54#include "glmenu_imagescreen.h"
55#include "list.h"
56#include "game_loader.h"
57
58#include "animation3d.h"
59
60#include "substring.h"
61
62#include "factory.h"
63
64#include "projectile.h"
65#include "event_handler.h"
66
67#include "sound_engine.h"
68#include "ogg_player.h"
69
70#include "class_list.h"
71
72#include "cd_engine.h"
73#include "npc.h"
74#include "npc2.h"
75#include "shader.h"
76
77SHELL_COMMAND(speed, World, setSpeed);
78
79using namespace std;
80
81//! This creates a Factory to fabricate a World
82CREATE_FACTORY(World);
83
84World::World(const TiXmlElement* root)
85{
86  this->constuctorInit("", -1);
87  this->path = NULL;
88
89  this->loadParams(root);
90}
91
92/**
93  *  create a new World
94
95    This creates a new empty world!
96*/
97World::World (const char* name)
98{
99  this->path = NULL;
100  this->constuctorInit(name, -1);
101  //NullParent* np = NullParent::getInstance();
102}
103
104/**
105 *  creates a new World...
106 * @param worldID with this ID
107*/
108World::World (int worldID)
109{
110  this->path = NULL;
111  this->constuctorInit(NULL, worldID);
112}
113
114/**
115 *  remove the World from memory
116
117    delete everything explicitly, that isn't contained in the parenting tree!
118    things contained in the tree are deleted automaticaly
119 */
120World::~World ()
121{
122  delete this->shell;
123  PRINTF(3)("World::~World() - deleting current world\n");
124
125  // here everything that is alocated by the World is deleted
126  delete this->entities;
127  State::setWorldEntityList(NULL);
128
129
130  // delete all the initialized Engines.
131  delete LightManager::getInstance();
132  delete TrackManager::getInstance();
133  delete ParticleEngine::getInstance();
134  delete AnimationPlayer::getInstance();
135  delete PhysicsEngine::getInstance();
136
137  // external engines initialized by the orxonox-class get deleted
138  SoundEngine::getInstance()->flushAllBuffers();
139  SoundEngine::getInstance()->flushAllSources();
140  FastFactory::flushAll(true);
141
142
143  // erease everything that is left.
144  delete NullParent::getInstance();
145  Shader::suspendShader();
146
147  // unload the resources !!
148  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
149
150  delete[] this->path;
151}
152
153/**
154 * initializes the world.
155 * @param name the name of the world
156 * @param worldID the ID of this world
157 *
158 * set all stuff here that is world generic and does not use to much memory
159 * because the real init() function StoryEntity::init() will be called
160 * shortly before start of the game.
161 * since all worlds are initiated/referenced before they will be started.
162 * NO LEVEL LOADING HERE - NEVER!
163*/
164void World::constuctorInit(const char* name, int worldID)
165{
166  this->setClassID(CL_WORLD, "World");
167
168  this->setName(name);
169  this->debugWorldNr = worldID;
170  this->gameTime = 0.0f;
171  this->setSpeed(1.0);
172  this->music = NULL;
173  this->shell = NULL;
174  this->entities = NULL;
175}
176
177/**
178 * loads the parameters of a World from an XML-element
179 * @param root the XML-element to load from
180 */
181void World::loadParams(const TiXmlElement* root)
182{
183  PRINTF(4)("Creating a World\n");
184
185  LoadParam<World>(root, "identifier", this, &World::setStoryID)
186    .describe("Sets the StoryID of this world");
187
188  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
189    .describe("Sets the ID of the next world");
190
191  LoadParam<World>(root, "path", this, &World::setPath)
192    .describe("The Filename of this World (relative from the data-dir)");
193}
194
195/**
196 * this is executed just before load
197 *
198 * since the load function sometimes needs data, that has been initialized
199 * before the load and after the proceeding storyentity has finished
200*/
201ErrorMessage World::preLoad()
202{
203  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
204  this->cycle = 0;
205
206  /* init the world interface */
207  this->shell = new Shell();
208
209  LightManager::getInstance();
210  NullParent::getInstance ();
211
212  AnimationPlayer::getInstance(); // initializes the animationPlayer
213  PhysicsEngine::getInstance();
214
215  this->localCamera = new Camera();
216  this->localCamera->setName ("World-Camera");
217
218  State::setCamera(this->localCamera, this->localCamera->getTarget());
219
220  GraphicsEngine::getInstance()->displayFPS(true);
221
222  CDEngine::getInstance()->setEntityList( this->entities);
223}
224
225
226/**
227 *  loads the World by initializing all resources, and set their default values.
228*/
229ErrorMessage World::load()
230{
231  PRINTF(3)("> Loading world: '%s'\n", getPath());
232  TiXmlElement* element;
233  GameLoader* loader = GameLoader::getInstance();
234
235  if( getPath() == NULL)
236    {
237      PRINTF(1)("World has no path specified for loading");
238      this->loadDebugWorld(this->getStoryID());
239      return (ErrorMessage){213,"Path not specified","World::load()"};
240    }
241
242  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
243  // load the campaign document
244  if( !XMLDoc->LoadFile())
245  {
246    // report an error
247    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
248    delete XMLDoc;
249    return (ErrorMessage){213,"XML File parsing error","World::load()"};
250  }
251
252  // check basic validity
253  TiXmlElement* root = XMLDoc->RootElement();
254  assert( root != NULL);
255
256  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
257    {
258      // report an error
259      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
260      delete XMLDoc;
261      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
262    }
263
264  // load the parameters
265  // name
266  const char* string = grabParameter( root, "name");
267  if( string == NULL)
268    {
269      PRINTF(2)("World is missing a proper 'name'\n");
270      this->setName("Unknown");
271    }
272  else
273    {
274      this->setName(string);
275    }
276
277  ////////////////
278  // LOADSCREEN //
279  ////////////////
280  element = root->FirstChildElement("LoadScreen");
281  if (element == NULL)
282    {
283      PRINTF(2)("no LoadScreen specified, loading default\n");
284
285      glmis->setBackgroundImage("pictures/load_screen.jpg");
286      this->glmis->setMaximum(8);
287      this->glmis->draw();
288    }
289  else
290    {
291      this->glmis->loadParams(element);
292      this->glmis->draw();
293    }
294  this->glmis->draw();
295
296  ////////////////////////
297  // find WorldEntities //
298  ////////////////////////
299
300  element = root->FirstChildElement("WorldEntities");
301
302  if( element == NULL)
303    {
304      PRINTF(1)("World is missing 'WorldEntities'\n");
305    }
306  else
307    {
308      element = element->FirstChildElement();
309      // load Players/Objects/Whatever
310      PRINTF(4)("Loading WorldEntities\n");
311      while( element != NULL)
312        {
313          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
314          if( created != NULL) this->spawn( created);
315          // if we load a 'Player' we use it as localPlayer
316          //todo do this more elegant
317          if( element->Value() != NULL && !strcmp( element->Value(), "Player"))
318          {
319            localPlayer = (Player*) created;
320            CDEngine::getInstance()->setPlayer(localPlayer);
321          }
322          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
323          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
324          {
325            terrain = (Terrain*) created;
326            CDEngine::getInstance()->setTerrain(terrain);
327          }
328          element = element->NextSiblingElement();
329          glmis->step(); //! @todo temporary
330        }
331      PRINTF(4)("Done loading WorldEntities\n");
332    }
333
334    //////////////////////////////
335    // LOADING ADDITIONAL STUFF //
336    //////////////////////////////
337
338    LoadParam<LightManager>(root, "LightManager", LightManager::getInstance(), &LightManager::loadParams);
339
340    LoadParam<ParticleEngine>(root, "ParticleEngine", ParticleEngine::getInstance(), &ParticleEngine::loadParams);
341    LoadParam<PhysicsEngine>(root, "PhysicsEngine", PhysicsEngine::getInstance(), &PhysicsEngine::loadParams);
342
343  // find Track
344  element = root->FirstChildElement( "Track");
345  if( element == NULL)
346    {
347      PRINTF(0)("World is missing a 'Track'\n");
348    }
349  else
350    {
351      //load track
352      PRINTF(4)("Loading Track\n");
353
354      TrackManager::getInstance()->loadParams( element);
355      TrackManager::getInstance()->finalize();
356    }
357
358  // free the XML data
359
360  delete XMLDoc;
361  /* GENERIC LOADING PROCESS FINISHED */
362
363  // bind input
364  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
365  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
366  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
367  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
368  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
369  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
370  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
371
372  // bind camera
373  //this->localCamera->bind (localPlayer);
374 // this->localPlayer->addChild (this->localCamera);
375
376
377  //        TrackManager::getInstance()->setBindSlave(env);
378  PNode* tn = TrackManager::getInstance()->getTrackNode();
379  tn->addChild(this->localPlayer);
380
381  //localCamera->setParent(TrackNode::getInstance());
382  tn->addChild(this->localCamera);
383  localCamera->lookAt(tn);
384  localCamera->setClipRegion(1, 10000.0);
385  this->localPlayer->setParentMode(PNODE_ALL);
386  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
387
388  if (sky != NULL)
389  {
390    this->sky->setParent(this->localCamera);
391    this->sky->setParentMode(PNODE_MOVEMENT);
392  }
393
394  // initialize debug coord system
395  objectList = glGenLists(1);
396  glNewList (objectList, GL_COMPILE);
397
398  //TrackManager::getInstance()->drawGraph(.01);
399  //TrackManager::getInstance()->debug(2);
400  glEndList();
401
402  SoundEngine::getInstance()->setListener(this->localCamera);
403
404
405
406  ////////////
407  // STATIC //
408  ////////////
409
410  Gravity* test = new Gravity();
411
412  // SYSTEM TRAILING THE PLAYER
413  // Creating a Test Particle System
414
415  //new PhysicsConnection(system, gravity);
416  //    new PhysicsConnection(this->localPlayer, gravity);
417
418//   TestEntity* testEntity = new TestEntity();
419//   testEntity->setRelCoor(Vector(570, 10, -15));
420//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
421//   this->spawn(testEntity);
422
423//   TestEntity* testEntity2 = new TestEntity();
424//   testEntity2->setAnim(STAND);
425//   testEntity2->setRelCoor(Vector(2400.0, 10.0, -30.0));
426//   testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
427//   //testEntity2->setParent(this->localPlayer);
428//   this->spawn(testEntity2);
429//
430//   TestEntity* testEntity3 = new TestEntity();
431//   testEntity3->setAnim(BOOM);
432//   testEntity3->setRelCoor(Vector(2450.0, 10.0, -40.0));
433//   testEntity3->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
434//   this->spawn(testEntity3);
435//
436//   TestEntity* testEntity4 = new TestEntity();
437//   testEntity4->setAnim(FLIP);
438//   testEntity4->setRelCoor(Vector(2500.0, 10.0, -22.0));
439//   testEntity4->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
440//   this->spawn(testEntity4);
441//
442//   TestEntity* testEntity5 = new TestEntity();
443//   testEntity5->setAnim(WAVE);
444//   testEntity5->setRelCoor(Vector(2420.0, 10.0, -50.0));
445//   testEntity5->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
446//   this->spawn(testEntity5);
447//
448//   TestEntity* testEntity6 = new TestEntity();
449//   testEntity6->setAnim(WAVE);
450//   testEntity6->setRelCoor(Vector(2420.0, 10.0, -20.0));
451//   testEntity6->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
452//   this->spawn(testEntity6);
453//
454//   TestEntity* testEntity7 = new TestEntity();
455//   testEntity7->setAnim(WAVE);
456//   testEntity7->setRelCoor(Vector(2500.0, 10.0, -50.0));
457//   testEntity7->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
458//   this->spawn(testEntity7);
459
460
461
462//  PhysicsEngine::getInstance()->debug();
463
464
465
466  for(int i = 0; i < 100; i++)
467  {
468    WorldEntity* tmp = new NPC2();
469    char npcChar[10];
470    sprintf (npcChar, "NPC_%d", i);
471        tmp->setName(npcChar);
472    tmp->setAbsCoor(((float)rand()/RAND_MAX) * 5000, 50/*+ (float)rand()/RAND_MAX*20*/, ((float)rand()/RAND_MAX -.5) *30);
473    this->spawn(tmp);
474
475
476  }
477
478
479
480//  ClassList::debug();
481
482  this->music = NULL;//(OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);
483  //music->playback();
484}
485
486
487
488/**
489 * creates a debug world: only for experimental stuff
490*/
491void World::loadDebugWorld(int worldID)
492{
493  /*monitor progress*/
494  this->glmis->step();
495  // stuff beyond this point remains to be loaded properly
496
497  // initializing the TrackManager
498  TrackManager::getInstance()->addPointV(Vector(150, -35, 5));
499  TrackManager::getInstance()->addPointV(Vector(200,-35, 5));
500  TrackManager::getInstance()->addPointV(Vector(250, -35, 5));
501  TrackManager::getInstance()->addPointV(Vector(320,-33,-.55));
502  TrackManager::getInstance()->setDuration(1);
503  TrackManager::getInstance()->setSavePoint();
504
505  TrackManager::getInstance()->addPointV(Vector(410, 0, 0));
506  TrackManager::getInstance()->addPointV(Vector(510, 20, -10));
507  TrackManager::getInstance()->addPointV(Vector(550, 20, -10));
508  TrackManager::getInstance()->addPointV(Vector(570, 20, -10));
509  TrackManager::getInstance()->setDuration(2);
510
511  TrackManager::getInstance()->forkS("testFork1,testFork2");
512  TrackManager::getInstance()->workOnS("testFork1");
513  TrackManager::getInstance()->addPointV(Vector(640, 25, -30));
514  TrackManager::getInstance()->addPointV(Vector(700, 40, -120));
515  TrackManager::getInstance()->addPointV(Vector(800, 50, -150));
516  TrackManager::getInstance()->addPointV(Vector(900, 60, -100));
517  TrackManager::getInstance()->addPointV(Vector(900, 60, -70));
518  TrackManager::getInstance()->addPointV(Vector(990, 65, -15));
519  TrackManager::getInstance()->addPointV(Vector(1050, 65, -10));
520  TrackManager::getInstance()->addPointV(Vector(1100, 65, -20));
521  TrackManager::getInstance()->setDuration(4);
522
523  TrackManager::getInstance()->workOnS("testFork2");
524  TrackManager::getInstance()->addPointV(Vector(640, 25, 20));
525  TrackManager::getInstance()->addPointV(Vector(670, 50, 120));
526  TrackManager::getInstance()->addPointV(Vector(700, 70, 80));
527  TrackManager::getInstance()->addPointV(Vector(800, 70, 65));
528  TrackManager::getInstance()->addPointV(Vector(850, 65, 65));
529  TrackManager::getInstance()->addPointV(Vector(920, 35, 40));
530  TrackManager::getInstance()->addPointV(Vector(945, 40, 40));
531  TrackManager::getInstance()->addPointV(Vector(970, 24, 40));
532  TrackManager::getInstance()->addPointV(Vector(1000, 40, -7));
533
534  TrackManager::getInstance()->setDuration(4);
535
536
537  TrackManager::getInstance()->joinS("testFork1,testFork2");
538
539  TrackManager::getInstance()->addPointV(Vector(1200, 60, -50));
540  TrackManager::getInstance()->addPointV(Vector(1300, 50, -50));
541  TrackManager::getInstance()->addPointV(Vector(1400, 40, -50));
542  TrackManager::getInstance()->addPointV(Vector(1500, 40, -60));
543  TrackManager::getInstance()->addPointV(Vector(1600, 35, -55));
544  TrackManager::getInstance()->addPointV(Vector(1700, 45, -40));
545  TrackManager::getInstance()->addPointV(Vector(1750, 60, -40));
546  TrackManager::getInstance()->addPointV(Vector(1770, 80, -40));
547  TrackManager::getInstance()->addPointV(Vector(1800, 100, -40));
548  TrackManager::getInstance()->setDuration(10);
549
550  TrackManager::getInstance()->finalize();
551
552
553  // LIGHT initialisation
554  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
555//  LightManager::getInstance()->addLight();
556  LightManager::getInstance()->debug();
557
558  switch(this->debugWorldNr)
559    {
560      /*
561        this loads the hard-coded debug world. this only for simplicity and will be
562        removed by a reald world-loader, which interprets a world-file.
563        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
564        make whatever you want...
565      */
566    case DEBUG_WORLD_0:
567      {
568        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
569
570
571        this->localPlayer = new Player ();
572        this->localPlayer->setName ("player");
573        this->spawn (this->localPlayer);
574        this->localPlayer->setRelCoor(Vector(5,0,0));
575        /*monitor progress*/
576        this->glmis->step();
577
578
579        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
580        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
581        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
582
583        /*
584        Field* testField = new Gravity();
585        testField->setMagnitude(10);
586        new PhysicsConnection(this->localPlayer, testField);
587        */
588
589        // bind camera
590        this->localCamera = new Camera();
591        this->localCamera->setName ("camera");
592        /*monitor progress*/
593        this->glmis->step();
594
595
596        // Create SkySphere
597        this->sky = new Skysphere("pictures/sky-replace.jpg");
598        this->sky->setName("SkySphere");
599        this->spawn(this->sky);
600        this->localCamera->addChild(this->sky);
601        this->sky->setParentMode(PNODE_MOVEMENT);
602        /*monitor progress*/
603        this->glmis->step();
604
605
606        terrain = new Terrain("worlds/newGround.obj");
607        terrain->setRelCoor(Vector(0,-10,0));
608        this->spawn(terrain);
609        /*monitor progress*/
610        this->glmis->step();
611
612        this->pilotNode = new PilotNode();
613        this->spawn(this->pilotNode);
614        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
615        this->pilotNode->addChild(this->localPlayer);
616        this->pilotNode->addChild(this->localCamera);
617        this->localCamera->lookAt(this->localPlayer);
618
619        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
620        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
621        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
622        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
623        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
624
625        /*
626        PNode* tn = TrackManager::getInstance()->getTrackNode();
627        tn->addChild(this->localPlayer);
628        this->localCamera->lookAt(tn);
629
630        tn->addChild(this->localCamera);
631        this->localPlayer->setParentMode(PNODE_ALL);
632        TrackManager::getInstance()->condition(2, LEFTRIGHT, this->localPlayer);
633        */
634        this->glmis->step();
635        break;
636      }
637    case DEBUG_WORLD_1:
638      {
639
640        break;
641      }
642    case DEBUG_WORLD_2:
643      {
644
645        break;
646      }
647    default:
648      break;
649    }
650}
651
652/**
653 *  initializes a new World shortly before start
654 *
655 * this is the function, that will be loaded shortly before the world is
656 * started
657*/
658ErrorMessage World::init()
659{
660  this->bPause = false;
661  this->pilotNode = NULL;
662
663  /* update the object position before game start - so there are no wrong coordinates used in the first processing */
664  NullParent::getInstance()->update (0.001f);
665  NullParent::getInstance()->update (0.001f);
666
667}
668
669
670/**
671 *  starts the World
672*/
673ErrorMessage World::start()
674{
675  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
676  this->bQuitOrxonox = false;
677  this->bQuitCurrentGame = false;
678  this->mainLoop();
679}
680
681/**
682 *  stops the world.
683
684   This happens, when the player decides to end the Level.
685*/
686ErrorMessage World::stop()
687{
688  PRINTF(3)("World::stop() - got stop signal\n");
689  this->bQuitCurrentGame = true;
690}
691
692/**
693 *  pauses the Game
694*/
695ErrorMessage World::pause()
696{
697  this->isPaused = true;
698}
699
700/**
701 *  ends the pause Phase
702*/
703ErrorMessage World::resume()
704{
705  this->isPaused = false;
706}
707
708/**
709 *  destroys the World
710*/
711ErrorMessage World::destroy()
712{
713
714}
715
716/**
717 *  shows the loading screen
718*/
719void World::displayLoadScreen ()
720{
721  PRINTF(3)("World::displayLoadScreen - start\n");
722
723  //GLMenuImageScreen*
724  this->glmis = new GLMenuImageScreen();
725  this->glmis->setMaximum(8);
726
727  PRINTF(3)("World::displayLoadScreen - end\n");
728}
729
730/**
731 *  removes the loadscreen, and changes over to the game
732
733   @todo take out the delay
734*/
735void World::releaseLoadScreen ()
736{
737  PRINTF(3)("World::releaseLoadScreen - start\n");
738  this->glmis->setValue(this->glmis->getMaximum());
739  PRINTF(3)("World::releaseLoadScreen - end\n");
740  delete this->glmis;
741}
742
743
744/**
745 *  gets the list of entities from the world
746 * @returns entity list
747*/
748tList<WorldEntity>* World::getEntities()
749{
750  return this->entities;
751}
752
753
754/**
755 *  this returns the current game time
756 * @returns elapsed game time
757*/
758double World::getGameTime()
759{
760  return this->gameTime;
761}
762
763
764/**
765 *  function to put your own debug stuff into it. it can display informations about
766   the current class/procedure
767*/
768void World::debug()
769{
770  PRINTF(0)("Printing out the List of alive WorldEntities:\n");
771  tIterator<WorldEntity>* iterator = this->entities->getIterator();
772  WorldEntity* entity = iterator->firstElement();
773  while( entity != NULL)
774  {
775    PRINTF(0)("%s::%s\n", entity->getClassName(), entity->getName());
776    entity = iterator->nextElement();
777  }
778  delete iterator;
779}
780
781
782/**
783  \brief main loop of the world: executing all world relevant function
784
785  in this loop we synchronize (if networked), handle input events, give the heart-beat to
786  all other member-entities of the world (tick to player, enemies etc.), checking for
787  collisions drawing everything to the screen.
788*/
789void World::mainLoop()
790{
791  this->lastFrame = SDL_GetTicks ();
792  PRINTF(3)("World::mainLoop() - Entering main loop\n");
793
794  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
795    {
796      ++this->cycle;
797      PRINTF(4)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
798      // Network
799      this->synchronize ();
800      // Process input
801      this->handleInput ();
802      if( this->bQuitCurrentGame || this->bQuitOrxonox)
803          break;
804      // Process time
805      this->tick ();
806      // Process collision
807      this->collide ();
808      // Update the state
809      this->update ();
810      // Draw
811      this->display ();
812    }
813
814  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
815}
816
817
818/**
819 *  synchronize local data with remote data
820*/
821void World::synchronize ()
822{
823  // Get remote input
824  // Update synchronizables
825}
826
827
828/**
829 *  run all input processing
830
831   the command node is the central input event dispatcher. the node uses the even-queue from
832   sdl and has its own event-passing-queue.
833*/
834void World::handleInput ()
835{
836  // localinput
837  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
838  //cn->process();
839
840  EventHandler::getInstance()->process();
841
842  // remoteinput
843}
844
845
846/**
847 *  advance the timeline
848
849   this calculates the time used to process one frame (with all input handling, drawing, etc)
850   the time is mesured in ms and passed to all world-entities and other classes that need
851   a heart-beat.
852*/
853void World::tick ()
854{
855  Uint32 currentFrame = SDL_GetTicks();
856  if(!this->bPause)
857    {
858      this->dt = currentFrame - this->lastFrame;
859
860      if( this->dt > 10)
861        {
862          float fps = 1000/dt;
863
864          // temporary, only for showing how fast the text-engine is
865          char tmpChar[20];
866          sprintf(tmpChar, "fps: %4.0f", fps);
867        }
868      else
869        {
870          /* the frame-rate is limited to 100 frames per second, all other things are for
871             nothing.
872          */
873          PRINTF(3)("fps = 1000 - frame rate is adjusted\n");
874          SDL_Delay(10-dt);
875          this->dt = 10;
876        }
877
878      this->dtS = (float)this->dt / 1000.0 * this->speed;
879      this->gameTime += this->dtS;
880
881      tIterator<WorldEntity>* iterator = this->entities->getIterator();
882      WorldEntity* entity = iterator->firstElement();
883      while( entity != NULL)
884        {
885          entity->tick (this->dtS);
886          entity = iterator->nextElement();
887        }
888      delete iterator;
889
890      /* update tick the rest */
891      TrackManager::getInstance()->tick(this->dtS);
892      this->localCamera->tick(this->dtS);
893      // tick the engines
894      AnimationPlayer::getInstance()->tick(this->dtS);
895//      if (this->cycle > 5)
896        PhysicsEngine::getInstance()->tick(this->dtS);
897
898      ParticleEngine::getInstance()->tick(this->dtS);
899      GarbageCollector::getInstance()->tick(this->dtS);
900
901
902      /** actualy the Graphics Engine should tick the world not the other way around...
903         but since we like the things not too complicated we got it this way around
904         until there is need or time to do it the other way around.
905         @todo: GraphicsEngine ticks world: separation of processes and data...
906
907        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
908         beceause graphics have nothing(or at least not much) to do with Motion.
909      */
910      GraphicsEngine::getInstance()->tick(this->dtS);
911    }
912  this->lastFrame = currentFrame;
913}
914
915
916/**
917 *  this function gives the world a consistant state
918
919   after ticking (updating the world state) this will give a constistant
920   state to the whole system.
921*/
922void World::update()
923{
924  GarbageCollector::getInstance()->update();
925  NullParent::getInstance()->update (this->dtS);
926  GraphicsEngine::getInstance()->update(this->dtS);
927
928  SoundEngine::getInstance()->update();
929  //music->update();
930}
931
932
933void World::collide()
934{
935  CDEngine::getInstance()->checkCollisions();
936}
937
938/**
939 *  render the current frame
940
941   clear all buffers and draw the world
942*/
943void World::display ()
944{
945  // clear buffer
946  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
947  // set camera
948  this->localCamera->apply ();
949  // draw world
950  this->draw();
951  // draw HUD
952  /** @todo draw HUD */
953  // flip buffers
954  GraphicsEngine::swapBuffers();
955  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
956  //SDL_Flip (screen);
957}
958
959
960/**
961 *  runs through all entities calling their draw() methods
962 */
963void World::draw ()
964{
965  /* draw entities */
966  WorldEntity* entity;
967  glLoadIdentity();
968  tIterator<WorldEntity>* iterator = this->entities->getIterator();
969  entity = iterator->firstElement();
970  while( entity != NULL )
971  {
972    if( entity->isVisible() ) entity->draw();
973    //entity->drawBVTree(2, 226);  // to draw the bounding boxes of the objects at level 2 for debug purp
974    entity = iterator->nextElement();
975  }
976  delete iterator;
977
978  glCallList (objectList);
979
980  ParticleEngine::getInstance()->draw();
981
982  GraphicsEngine::getInstance()->draw();
983  //TextEngine::getInstance()->draw();
984}
985
986/**
987 *  add and spawn a new entity to this world
988 * @param entity to be added
989*/
990void World::spawn(WorldEntity* entity)
991{
992  this->entities->add (entity);
993  entity->postSpawn ();
994}
995
996
997/**
998 *  add and spawn a new entity to this world
999 * @param entity to be added
1000 * @param absCoor At what coordinates to add this entity.
1001 * @param absDir In which direction should it look.
1002*/
1003void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1004{
1005  this->entities->add (entity);
1006
1007  entity->setAbsCoor (*absCoor);
1008  entity->setAbsDir (*absDir);
1009
1010  entity->postSpawn ();
1011}
1012
1013
1014/**
1015 *  add and spawn a new entity to this world
1016 * @param entity to be added
1017 * @param entity to be added to (PNode)
1018 * @param At what relative  coordinates to add this entity.
1019 * @param In which relative direction should it look.
1020*/
1021void World::spawn(WorldEntity* entity, PNode* parentNode,
1022                  Vector* relCoor, Quaternion* relDir)
1023{
1024  NullParent::getInstance();
1025  if( parentNode != NULL)
1026    {
1027      parentNode->addChild (entity);
1028
1029      entity->setRelCoor (*relCoor);
1030      entity->setRelDir (*relDir);
1031
1032      this->entities->add (entity);
1033
1034      entity->postSpawn ();
1035    }
1036}
1037
1038
1039
1040/**
1041  \brief commands that the world must catch
1042  @returns false if not used by the world
1043*/
1044bool World::command(Command* cmd)
1045{
1046  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1047  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1048  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1049  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1050  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1051  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1052  return false;
1053}
1054
1055void World::setPath( const char* name)
1056{
1057  if (this->path)
1058    delete this->path;
1059  if (ResourceManager::isFile(name))
1060  {
1061    this->path = new char[strlen(name)+1];
1062    strcpy(this->path, name);
1063  }
1064  else
1065    {
1066      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1067      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1068    }
1069}
1070
1071const char* World::getPath( void)
1072{
1073  return path;
1074}
Note: See TracBrowser for help on using the repository browser.