Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Shell is running, but only in orxonox-world, not all-over
I do not know why this behaviour occurs, but maybe it is because of some errors in other pointers…
who knows

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 *  starts the World
644*/
645ErrorMessage World::start()
646{
647  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
648  this->bQuitOrxonox = false;
649  this->bQuitCurrentGame = false;
650  this->mainLoop();
651}
652
653/**
654 *  stops the world.
655
656   This happens, when the player decides to end the Level.
657*/
658ErrorMessage World::stop()
659{
660  PRINTF(3)("World::stop() - got stop signal\n");
661  this->bQuitCurrentGame = true;
662}
663
664/**
665 *  pauses the Game
666*/
667ErrorMessage World::pause()
668{
669  this->isPaused = true;
670}
671
672/**
673 *  ends the pause Phase
674*/
675ErrorMessage World::resume()
676{
677  this->isPaused = false;
678}
679
680/**
681 *  destroys the World
682*/
683ErrorMessage World::destroy()
684{
685
686}
687
688/**
689 *  shows the loading screen
690*/
691void World::displayLoadScreen ()
692{
693  PRINTF(3)("World::displayLoadScreen - start\n");
694
695  //GLMenuImageScreen*
696  this->glmis = new GLMenuImageScreen();
697  this->glmis->setMaximum(8);
698
699  PRINTF(3)("World::displayLoadScreen - end\n");
700}
701
702/**
703 *  removes the loadscreen, and changes over to the game
704
705   @todo take out the delay
706*/
707void World::releaseLoadScreen ()
708{
709  PRINTF(3)("World::releaseLoadScreen - start\n");
710  this->glmis->setValue(this->glmis->getMaximum());
711  PRINTF(3)("World::releaseLoadScreen - end\n");
712  delete this->glmis;
713}
714
715
716/**
717 *  gets the list of entities from the world
718 * @returns entity list
719*/
720tList<WorldEntity>* World::getEntities()
721{
722  return this->entities;
723}
724
725
726/**
727 *  this returns the current game time
728 * @returns elapsed game time
729*/
730double World::getGameTime()
731{
732  return this->gameTime;
733}
734
735
736/**
737 *  function to put your own debug stuff into it. it can display informations about
738   the current class/procedure
739*/
740void World::debug()
741{
742}
743
744
745/**
746  \brief main loop of the world: executing all world relevant function
747
748  in this loop we synchronize (if networked), handle input events, give the heart-beat to
749  all other member-entities of the world (tick to player, enemies etc.), checking for
750  collisions drawing everything to the screen.
751*/
752void World::mainLoop()
753{
754  this->lastFrame = SDL_GetTicks ();
755  PRINTF(3)("World::mainLoop() - Entering main loop\n");
756
757  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
758    {
759      ++this->cycle;
760      PRINTF(4)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
761      // Network
762      this->synchronize ();
763      // Process input
764      this->handleInput ();
765      if( this->bQuitCurrentGame || this->bQuitOrxonox)
766          break;
767      // Process time
768      this->tick ();
769      // Process collision
770      this->collide ();
771      // Update the state
772      this->update ();
773      // Draw
774      this->display ();
775    }
776
777  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
778}
779
780
781/**
782 *  synchronize local data with remote data
783*/
784void World::synchronize ()
785{
786  // Get remote input
787  // Update synchronizables
788}
789
790
791/**
792 *  run all input processing
793
794   the command node is the central input event dispatcher. the node uses the even-queue from
795   sdl and has its own event-passing-queue.
796*/
797void World::handleInput ()
798{
799  // localinput
800  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
801  //cn->process();
802
803  EventHandler::getInstance()->process();
804
805  // remoteinput
806}
807
808
809/**
810 *  advance the timeline
811
812   this calculates the time used to process one frame (with all input handling, drawing, etc)
813   the time is mesured in ms and passed to all world-entities and other classes that need
814   a heart-beat.
815*/
816void World::tick ()
817{
818  Uint32 currentFrame = SDL_GetTicks();
819  if(!this->bPause)
820    {
821      this->dt = currentFrame - this->lastFrame;
822
823      if( this->dt > 10)
824        {
825          float fps = 1000/dt;
826
827          // temporary, only for showing how fast the text-engine is
828          char tmpChar[20];
829          sprintf(tmpChar, "fps: %4.0f", fps);
830        }
831      else
832        {
833          /* the frame-rate is limited to 100 frames per second, all other things are for
834             nothing.
835          */
836          PRINTF(3)("fps = 1000 - frame rate is adjusted\n");
837          SDL_Delay(10-dt);
838          this->dt = 10;
839        }
840
841      this->dtS = (float)this->dt / 1000.0;
842      this->gameTime += this->dtS;
843
844      tIterator<WorldEntity>* iterator = this->entities->getIterator();
845      WorldEntity* entity = iterator->nextElement();
846      while( entity != NULL)
847        {
848          entity->tick (this->dtS);
849          entity = iterator->nextElement();
850        }
851      delete iterator;
852
853      /* update tick the rest */
854      TrackManager::getInstance()->tick(this->dtS);
855      this->localCamera->tick(this->dtS);
856      // tick the engines
857      AnimationPlayer::getInstance()->tick(this->dtS);
858//      if (this->cycle > 5)
859        PhysicsEngine::getInstance()->tick(this->dtS);
860
861      ParticleEngine::getInstance()->tick(this->dtS);
862      GarbageCollector::getInstance()->tick(this->dtS);
863
864
865      /** actualy the Graphics Engine should tick the world not the other way around...
866         but since we like the things not too complicated we got it this way around
867         until there is need or time to do it the other way around.
868         @todo: GraphicsEngine ticks world: separation of processes and data...
869
870        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
871         beceause graphics have nothing(or at least not much) to do with Motion.
872      */
873      GraphicsEngine::getInstance()->tick(this->dtS);
874    }
875  this->lastFrame = currentFrame;
876}
877
878
879/**
880 *  this function gives the world a consistant state
881
882   after ticking (updating the world state) this will give a constistant
883   state to the whole system.
884*/
885void World::update()
886{
887  GarbageCollector::getInstance()->update();
888  NullParent::getInstance()->update (this->dtS);
889
890  SoundEngine::getInstance()->update();
891  //music->update();
892}
893
894
895void World::collide()
896{
897  CDEngine::getInstance()->checkCollisions();
898}
899
900/**
901 *  render the current frame
902
903   clear all buffers and draw the world
904*/
905void World::display ()
906{
907  // clear buffer
908  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
909  // set camera
910  this->localCamera->apply ();
911  // draw world
912  this->draw();
913  // draw HUD
914  /** @todo draw HUD */
915  // flip buffers
916  GraphicsEngine::swapBuffers();
917  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
918  //SDL_Flip (screen);
919}
920
921
922/**
923 *  runs through all entities calling their draw() methods
924 */
925void World::draw ()
926{
927  /* draw entities */
928  WorldEntity* entity;
929  glLoadIdentity();
930  tIterator<WorldEntity>* iterator = this->entities->getIterator();
931  entity = iterator->nextElement();
932  while( entity != NULL )
933  {
934    if( entity->isVisible() ) entity->draw();
935    //entity->drawBVTree(2, 226);  // to draw the bounding boxes of the objects at level 2 for debug purp
936    entity = iterator->nextElement();
937  }
938  delete iterator;
939
940  glCallList (objectList);
941
942  ParticleEngine::getInstance()->draw();
943
944  GraphicsEngine::getInstance()->draw();
945  //TextEngine::getInstance()->draw();
946}
947
948/**
949 *  add and spawn a new entity to this world
950 * @param entity to be added
951*/
952void World::spawn(WorldEntity* entity)
953{
954  this->entities->add (entity);
955  entity->postSpawn ();
956}
957
958
959/**
960 *  add and spawn a new entity to this world
961 * @param entity to be added
962 * @param absCoor At what coordinates to add this entity.
963 * @param absDir In which direction should it look.
964*/
965void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
966{
967  this->entities->add (entity);
968
969  entity->setAbsCoor (*absCoor);
970  entity->setAbsDir (*absDir);
971
972  entity->postSpawn ();
973}
974
975
976/**
977 *  add and spawn a new entity to this world
978 * @param entity to be added
979 * @param entity to be added to (PNode)
980 * @param At what relative  coordinates to add this entity.
981 * @param In which relative direction should it look.
982*/
983void World::spawn(WorldEntity* entity, PNode* parentNode,
984                  Vector* relCoor, Quaternion* relDir)
985{
986  NullParent::getInstance();
987  if( parentNode != NULL)
988    {
989      parentNode->addChild (entity);
990
991      entity->setRelCoor (*relCoor);
992      entity->setRelDir (*relDir);
993
994      this->entities->add (entity);
995
996      entity->postSpawn ();
997    }
998}
999
1000
1001
1002/**
1003  \brief commands that the world must catch
1004  @returns false if not used by the world
1005*/
1006bool World::command(Command* cmd)
1007{
1008  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1009  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1010  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1011  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1012  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1013  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1014  return false;
1015}
1016
1017void World::setPath( const char* name)
1018{
1019  if (this->path)
1020    delete this->path;
1021  if (ResourceManager::isFile(name))
1022  {
1023    this->path = new char[strlen(name)+1];
1024    strcpy(this->path, name);
1025  }
1026  else
1027    {
1028      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1029      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1030    }
1031}
1032
1033const char* World::getPath( void)
1034{
1035  return path;
1036}
Note: See TracBrowser for help on using the repository browser.