Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4917 was 4917, checked in by patrick, 19 years ago

orxonox/trunk: some very little cleanup in the World - make it a better place

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