Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: flush
i am going into the weekend now
@patrick: ther might be some strange behaviour, and i noticed, that the CD-engine is iterating more through the entities, than it should
I hope, this is just a minor bug, because it almost killed me in the process of developing
i do not exactly know if it is from the CD-engine, but it is producing different outputs when i start the game five times in a row

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