Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5248 was 5218, checked in by bensch, 19 years ago

orxonox/trunk: more error-fixes… thanks Valgrind team :)

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