Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: CDEngine knows player and gets the array offsets

File size: 29.2 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "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  CDEngine::getInstance()->setEntityList( this->entities);
280}
281
282
283/**
284 *  loads the World by initializing all resources, and set their default values.
285*/
286ErrorMessage World::load()
287{
288  PRINTF(3)("> Loading world: '%s'\n", getPath());
289  TiXmlElement* element;
290  GameLoader* loader = GameLoader::getInstance();
291
292  if( getPath() == NULL)
293    {
294      PRINTF(1)("World has no path specified for loading");
295      this->loadDebugWorld(this->getStoryID());
296      return (ErrorMessage){213,"Path not specified","World::load()"};
297    }
298
299  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
300  // load the campaign document
301  if( !XMLDoc->LoadFile())
302  {
303    // report an error
304    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
305    delete XMLDoc;
306    return (ErrorMessage){213,"XML File parsing error","World::load()"};
307  }
308
309  // check basic validity
310  TiXmlElement* root = XMLDoc->RootElement();
311  assert( root != NULL);
312
313  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
314    {
315      // report an error
316      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
317      delete XMLDoc;
318      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
319    }
320
321  // load the parameters
322  // name
323  char* temp;
324  const char* string = grabParameter( root, "name");
325  if( string == NULL)
326    {
327      PRINTF(2)("World is missing a proper 'name'\n");
328      string = "Unknown";
329      temp = new char[strlen(string + 2)];
330      strcpy( temp, string);
331      this->worldName = temp;
332    }
333  else
334    {
335      temp = new char[strlen(string + 2)];
336      strcpy( temp, string);
337      this->worldName = temp;
338    }
339  ////////////////
340  // LOADSCREEN //
341  ////////////////
342  element = root->FirstChildElement("LoadScreen");
343  if (element == NULL)
344    {
345      PRINTF(2)("no LoadScreen specified, loading default\n");
346
347      glmis->setBackgroundImage("pictures/load_screen.jpg");
348      this->glmis->setMaximum(8);
349      this->glmis->draw();
350    }
351  else
352    {
353      this->glmis->loadParams(element);
354      this->glmis->draw();
355    }
356  this->glmis->draw();
357
358  ////////////////////////
359  // find WorldEntities //
360  ////////////////////////
361
362  element = root->FirstChildElement("WorldEntities");
363
364  if( element == NULL)
365    {
366      PRINTF(1)("World is missing 'WorldEntities'\n");
367    }
368  else
369    {
370      element = element->FirstChildElement();
371      // load Players/Objects/Whatever
372      PRINTF(4)("Loading WorldEntities\n");
373      while( element != NULL)
374        {
375          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
376          if( created != NULL) this->spawn( created);
377          // if we load a 'Player' we use it as localPlayer
378          //todo do this more elegant
379          if( element->Value() != NULL && !strcmp( element->Value(), "Player"))
380          {
381            localPlayer = (Player*) created;
382            CDEngine::getInstance()->setPlayer(localPlayer);
383          }
384          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
385          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
386          {
387            terrain = (Terrain*) created;
388            CDEngine::getInstance()->setTerrain(terrain);
389          }
390          element = element->NextSiblingElement();
391          glmis->step(); //! @todo temporary
392        }
393      PRINTF(4)("Done loading WorldEntities\n");
394    }
395
396    //////////////////////////////
397    // LOADING ADDITIONAL STUFF //
398    //////////////////////////////
399
400    LoadParam<LightManager>(root, "LightManager", LightManager::getInstance(), &LightManager::loadParams);
401
402    LoadParam<ParticleEngine>(root, "ParticleEngine", ParticleEngine::getInstance(), &ParticleEngine::loadParams);
403    LoadParam<PhysicsEngine>(root, "PhysicsEngine", PhysicsEngine::getInstance(), &PhysicsEngine::loadParams);
404
405  // find Track
406  element = root->FirstChildElement( "Track");
407  if( element == NULL)
408    {
409      PRINTF(0)("World is missing a 'Track'\n");
410    }
411  else
412    {
413      //load track
414      PRINTF(4)("Loading Track\n");
415
416      TrackManager::getInstance()->loadParams( element);
417      TrackManager::getInstance()->finalize();
418    }
419
420  // free the XML data
421
422  delete XMLDoc;
423  /* GENERIC LOADING PROCESS FINISHED */
424
425  // bind input
426  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
427  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
428  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
429  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
430  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
431  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
432  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
433
434  // bind camera
435  //this->localCamera->bind (localPlayer);
436  this->localPlayer->addChild (this->localCamera);
437
438
439//   lightMan->setAmbientColor(.1,.1,.1);
440//   lightMan->addLight();
441//   //      lightMan->setAttenuation(1.0, .01, 0.0);
442//   //      lightMan->setDiffuseColor(1,1,1);
443//   //  lightMan->addLight(1);
444//   //  lightMan->setPosition(20, 10, -20);
445//   //  lightMan->setDiffuseColor(0,0,0);
446//   //lightMan->debug();
447//   lightMan->setPosition(-5.0, 50.0, -40.0);
448//   lightMan->addLight();
449//   lightMan->setPosition(100, 80, 60);
450
451  //        TrackManager::getInstance()->setBindSlave(env);
452  PNode* tn = TrackManager::getInstance()->getTrackNode();
453  tn->addChild(this->localPlayer);
454
455  //localCamera->setParent(TrackNode::getInstance());
456  tn->addChild(this->localCamera);
457  localCamera->lookAt(tn);
458  localCamera->setParentMode(PNODE_MOVEMENT);
459  localCamera->setClipRegion(1, 10000.0);
460  this->localPlayer->setParentMode(PNODE_ALL);
461  Vector* cameraOffset = new Vector (0, 5, -10);
462  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
463
464  this->sky->setParent(this->localCamera);
465
466  // initialize debug coord system
467  objectList = glGenLists(1);
468  glNewList (objectList, GL_COMPILE);
469
470  //TrackManager::getInstance()->drawGraph(.01);
471  //TrackManager::getInstance()->debug(2);
472  glEndList();
473
474  SoundEngine::getInstance()->setListener(this->localCamera);
475
476
477
478
479  ////////////
480  // STATIC //
481  ////////////
482
483  Gravity* test = new Gravity();
484
485  // SYSTEM TRAILING THE PLAYER
486  // Creating a Test Particle System
487
488  //new PhysicsConnection(system, gravity);
489  //    new PhysicsConnection(this->localPlayer, gravity);
490
491//   TestEntity* testEntity = new TestEntity();
492//   testEntity->setRelCoor(Vector(570, 10, -15));
493//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
494//   this->spawn(testEntity);
495
496  TestEntity* testEntity2 = new TestEntity();
497  testEntity2->setAnim(RUN);
498  testEntity2->setRelCoor(Vector(2400, 25, 260));
499  testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
500  this->spawn(testEntity2);
501
502  TestEntity* testEntity3 = new TestEntity();
503  testEntity3->setAnim(RUN);
504  testEntity3->setRelCoor(Vector(2400, 25, 280));
505  testEntity3->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
506  this->spawn(testEntity3);
507
508  TestEntity* testEntity4 = new TestEntity();
509  testEntity4->setAnim(RUN);
510  testEntity4->setRelCoor(Vector(2430, 25, 250));
511  testEntity4->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
512  this->spawn(testEntity4);
513
514
515  PhysicsEngine::getInstance()->debug();
516
517
518  ClassList::debug();
519}
520
521
522
523/**
524 *  loads the debug world: only for experimental stuff
525*/
526void World::loadDebugWorld(int worldID)
527{
528  /*monitor progress*/
529  this->glmis->step();
530  // stuff beyond this point remains to be loaded properly
531
532  // initializing the TrackManager
533  TrackManager::getInstance()->addPointV(Vector(150, -35, 5));
534  TrackManager::getInstance()->addPointV(Vector(200,-35, 5));
535  TrackManager::getInstance()->addPointV(Vector(250, -35, 5));
536  TrackManager::getInstance()->addPointV(Vector(320,-33,-.55));
537  TrackManager::getInstance()->setDuration(1);
538  TrackManager::getInstance()->setSavePoint();
539
540  TrackManager::getInstance()->addPointV(Vector(410, 0, 0));
541  TrackManager::getInstance()->addPointV(Vector(510, 20, -10));
542  TrackManager::getInstance()->addPointV(Vector(550, 20, -10));
543  TrackManager::getInstance()->addPointV(Vector(570, 20, -10));
544  TrackManager::getInstance()->setDuration(2);
545
546  TrackManager::getInstance()->forkS("testFork1,testFork2");
547  TrackManager::getInstance()->workOnS("testFork1");
548  TrackManager::getInstance()->addPointV(Vector(640, 25, -30));
549  TrackManager::getInstance()->addPointV(Vector(700, 40, -120));
550  TrackManager::getInstance()->addPointV(Vector(800, 50, -150));
551  TrackManager::getInstance()->addPointV(Vector(900, 60, -100));
552  TrackManager::getInstance()->addPointV(Vector(900, 60, -70));
553  TrackManager::getInstance()->addPointV(Vector(990, 65, -15));
554  TrackManager::getInstance()->addPointV(Vector(1050, 65, -10));
555  TrackManager::getInstance()->addPointV(Vector(1100, 65, -20));
556  TrackManager::getInstance()->setDuration(4);
557
558  TrackManager::getInstance()->workOnS("testFork2");
559  TrackManager::getInstance()->addPointV(Vector(640, 25, 20));
560  TrackManager::getInstance()->addPointV(Vector(670, 50, 120));
561  TrackManager::getInstance()->addPointV(Vector(700, 70, 80));
562  TrackManager::getInstance()->addPointV(Vector(800, 70, 65));
563  TrackManager::getInstance()->addPointV(Vector(850, 65, 65));
564  TrackManager::getInstance()->addPointV(Vector(920, 35, 40));
565  TrackManager::getInstance()->addPointV(Vector(945, 40, 40));
566  TrackManager::getInstance()->addPointV(Vector(970, 24, 40));
567  TrackManager::getInstance()->addPointV(Vector(1000, 40, -7));
568
569  TrackManager::getInstance()->setDuration(4);
570
571
572  TrackManager::getInstance()->joinS("testFork1,testFork2");
573
574  TrackManager::getInstance()->addPointV(Vector(1200, 60, -50));
575  TrackManager::getInstance()->addPointV(Vector(1300, 50, -50));
576  TrackManager::getInstance()->addPointV(Vector(1400, 40, -50));
577  TrackManager::getInstance()->addPointV(Vector(1500, 40, -60));
578  TrackManager::getInstance()->addPointV(Vector(1600, 35, -55));
579  TrackManager::getInstance()->addPointV(Vector(1700, 45, -40));
580  TrackManager::getInstance()->addPointV(Vector(1750, 60, -40));
581  TrackManager::getInstance()->addPointV(Vector(1770, 80, -40));
582  TrackManager::getInstance()->addPointV(Vector(1800, 100, -40));
583  TrackManager::getInstance()->setDuration(10);
584
585  TrackManager::getInstance()->finalize();
586
587
588  // LIGHT initialisation
589  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
590//  LightManager::getInstance()->addLight();
591  LightManager::getInstance()->debug();
592
593  switch(this->debugWorldNr)
594    {
595      /*
596        this loads the hard-coded debug world. this only for simplicity and will be
597        removed by a reald world-loader, which interprets a world-file.
598        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
599        make whatever you want...
600      */
601    case DEBUG_WORLD_0:
602      {
603        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
604
605
606        this->localPlayer = new Player ();
607        this->localPlayer->setName ("player");
608        this->spawn (this->localPlayer);
609        this->localPlayer->setRelCoor(Vector(5,0,0));
610        /*monitor progress*/
611        this->glmis->step();
612
613
614        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
615        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
616        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
617
618        /*
619        Field* testField = new Gravity();
620        testField->setMagnitude(10);
621        new PhysicsConnection(this->localPlayer, testField);
622        */
623
624        // bind camera
625        this->localCamera = new Camera();
626        this->localCamera->setName ("camera");
627        /*monitor progress*/
628        this->glmis->step();
629
630
631        // Create SkySphere
632        this->sky = new Skysphere("pictures/sky-replace.jpg");
633        this->sky->setName("SkySphere");
634        this->spawn(this->sky);
635        this->localCamera->addChild(this->sky);
636        this->sky->setParentMode(PNODE_MOVEMENT);
637        /*monitor progress*/
638        this->glmis->step();
639
640
641        terrain = new Terrain("worlds/newGround.obj");
642        terrain->setRelCoor(Vector(0,-10,0));
643        this->spawn(terrain);
644        /*monitor progress*/
645        this->glmis->step();
646
647        this->pilotNode = new PilotNode();
648        this->spawn(this->pilotNode);
649        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
650        this->pilotNode->addChild(this->localPlayer);
651        this->pilotNode->addChild(this->localCamera);
652        this->localCamera->lookAt(this->localPlayer);
653
654        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
655        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
656        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
657        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
658        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
659
660        // bind input
661        Orxonox *orx = Orxonox::getInstance ();
662        //orx->getLocalInput()->bind (this->pilotNode);
663
664        /*
665        PNode* tn = TrackManager::getInstance()->getTrackNode();
666        tn->addChild(this->localPlayer);
667        this->localCamera->lookAt(tn);
668
669        tn->addChild(this->localCamera);
670        this->localPlayer->setParentMode(PNODE_ALL);
671        TrackManager::getInstance()->condition(2, LEFTRIGHT, this->localPlayer);
672        */
673        this->glmis->step();
674        break;
675      }
676    case DEBUG_WORLD_1:
677      {
678
679        break;
680      }
681    case DEBUG_WORLD_2:
682      {
683
684        break;
685      }
686    default:
687      break;
688    }
689}
690
691
692
693/**
694 *  initializes a new World shortly before start
695
696   this is the function, that will be loaded shortly before the world is
697   started
698*/
699ErrorMessage World::init()
700{
701  this->bPause = false;
702  this->pilotNode = NULL;
703}
704
705
706/**
707 *  starts the World
708*/
709ErrorMessage World::start()
710{
711  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
712  this->bQuitOrxonox = false;
713  this->bQuitCurrentGame = false;
714  this->mainLoop();
715}
716
717/**
718 *  stops the world.
719
720   This happens, when the player decides to end the Level.
721*/
722ErrorMessage World::stop()
723{
724  PRINTF(3)("World::stop() - got stop signal\n");
725  this->bQuitCurrentGame = true;
726}
727
728/**
729 *  pauses the Game
730*/
731ErrorMessage World::pause()
732{
733  this->isPaused = true;
734}
735
736/**
737 *  ends the pause Phase
738*/
739ErrorMessage World::resume()
740{
741  this->isPaused = false;
742}
743
744/**
745 *  destroys the World
746*/
747ErrorMessage World::destroy()
748{
749
750}
751
752/**
753 *  shows the loading screen
754*/
755void World::displayLoadScreen ()
756{
757  PRINTF(3)("World::displayLoadScreen - start\n");
758
759  //GLMenuImageScreen*
760  this->glmis = new GLMenuImageScreen();
761  this->glmis->setMaximum(8);
762
763  PRINTF(3)("World::displayLoadScreen - end\n");
764}
765
766/**
767 *  removes the loadscreen, and changes over to the game
768
769   @todo take out the delay
770*/
771void World::releaseLoadScreen ()
772{
773  PRINTF(3)("World::releaseLoadScreen - start\n");
774  this->glmis->setValue(this->glmis->getMaximum());
775  PRINTF(3)("World::releaseLoadScreen - end\n");
776  delete this->glmis;
777}
778
779
780/**
781 *  gets the list of entities from the world
782 * @returns entity list
783*/
784tList<WorldEntity>* World::getEntities()
785{
786  return this->entities;
787}
788
789
790/**
791 *  this returns the current game time
792 * @returns elapsed game time
793*/
794double World::getGameTime()
795{
796  return this->gameTime;
797}
798
799
800/**
801 *  function to put your own debug stuff into it. it can display informations about
802   the current class/procedure
803*/
804void World::debug()
805{
806}
807
808
809/**
810  \brief main loop of the world: executing all world relevant function
811
812  in this loop we synchronize (if networked), handle input events, give the heart-beat to
813  all other member-entities of the world (tick to player, enemies etc.), checking for
814  collisions drawing everything to the screen.
815*/
816void World::mainLoop()
817{
818  this->lastFrame = SDL_GetTicks ();
819  PRINTF(3)("World::mainLoop() - Entering main loop\n");
820  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
821    {
822      ++this->cycle;
823      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
824      // Network
825      this->synchronize ();
826      // Process input
827      this->handleInput ();
828      if( this->bQuitCurrentGame || this->bQuitOrxonox)
829          break;
830      // Process time
831      this->tick ();
832      // Update the state
833      this->update ();
834      // Process collision
835      this->collide ();
836      // Draw
837      this->display ();
838
839      //      for( int i = 0; i < 5000000; i++) {}
840      /* @todo this is to slow down the program for openGl Software emulator computers, reimplement*/
841    }
842  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
843}
844
845
846/**
847 *  synchronize local data with remote data
848*/
849void World::synchronize ()
850{
851  // Get remote input
852  // Update synchronizables
853}
854
855
856/**
857 *  run all input processing
858
859   the command node is the central input event dispatcher. the node uses the even-queue from
860   sdl and has its own event-passing-queue.
861*/
862void World::handleInput ()
863{
864  // localinput
865  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
866  //cn->process();
867
868  EventHandler::getInstance()->process();
869
870  // remoteinput
871}
872
873
874/**
875 *  advance the timeline
876
877   this calculates the time used to process one frame (with all input handling, drawing, etc)
878   the time is mesured in ms and passed to all world-entities and other classes that need
879   a heart-beat.
880*/
881void World::tick ()
882{
883  Uint32 currentFrame = SDL_GetTicks();
884  if(!this->bPause)
885    {
886      this->dt = currentFrame - this->lastFrame;
887
888      if( this->dt > 10)
889        {
890          float fps = 1000/dt;
891
892          // temporary, only for showing how fast the text-engine is
893          char tmpChar[20];
894          sprintf(tmpChar, "fps: %4.0f", fps);
895        }
896      else
897        {
898          /* the frame-rate is limited to 100 frames per second, all other things are for
899             nothing.
900          */
901          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
902          SDL_Delay(10-dt);
903          this->dt = 10;
904        }
905
906      this->dtS = (float)this->dt / 1000.0;
907      this->gameTime += this->dtS;
908
909      tIterator<WorldEntity>* iterator = this->entities->getIterator();
910      WorldEntity* entity = iterator->nextElement();
911      while( entity != NULL)
912        {
913          entity->tick (this->dtS);
914          entity = iterator->nextElement();
915        }
916      delete iterator;
917
918      /* update tick the rest */
919      TrackManager::getInstance()->tick(this->dtS);
920      this->localCamera->tick(this->dtS);
921      // tick the engines
922      AnimationPlayer::getInstance()->tick(this->dtS);
923      if (this->cycle > 5)
924        PhysicsEngine::getInstance()->tick(this->dtS);
925
926      ParticleEngine::getInstance()->tick(this->dtS);
927      GarbageCollector::getInstance()->tick(this->dtS);
928
929
930      /** actualy the Graphics Engine should tick the world not the other way around...
931         but since we like the things not too complicated we got it this way around
932         until there is need or time to do it the other way around.
933         @todo: GraphicsEngine ticks world: separation of processes and data...
934
935        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
936         beceause graphics have nothing(or at least not much) to do with Motion.
937      */
938      GraphicsEngine::getInstance()->tick(this->dtS);
939    }
940  this->lastFrame = currentFrame;
941}
942
943
944/**
945 *  this function gives the world a consistant state
946
947   after ticking (updating the world state) this will give a constistant
948   state to the whole system.
949*/
950void World::update()
951{
952  GarbageCollector::getInstance()->update();
953  this->nullParent->update (this->dtS);
954
955  SoundEngine::getInstance()->update();
956}
957
958
959void World::collide()
960{
961  CDEngine::getInstance()->checkCollisions();
962}
963
964/**
965 *  render the current frame
966
967   clear all buffers and draw the world
968*/
969void World::display ()
970{
971  // clear buffer
972  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
973  // set camera
974  this->localCamera->apply ();
975  // draw world
976  this->draw();
977  // draw HUD
978  /** @todo draw HUD */
979  // flip buffers
980  GraphicsEngine::swapBuffers();
981  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
982  //SDL_Flip (screen);
983}
984
985
986/**
987 *  runs through all entities calling their draw() methods
988 */
989void World::draw ()
990{
991  /* draw entities */
992  WorldEntity* entity;
993  glLoadIdentity();
994  //entity = this->entities->enumerate();
995  tIterator<WorldEntity>* iterator = this->entities->getIterator();
996  entity = iterator->nextElement();
997  while( entity != NULL )
998  {
999    if( entity->isVisible() ) entity->draw();
1000      //entity = this->entities->nextElement();
1001    entity = iterator->nextElement();
1002  }
1003  delete iterator;
1004
1005  glCallList (objectList);
1006
1007  ParticleEngine::getInstance()->draw();
1008
1009  GraphicsEngine::getInstance()->draw();
1010  //TextEngine::getInstance()->draw();
1011}
1012
1013/**
1014 *  add and spawn a new entity to this world
1015 * @param entity to be added
1016*/
1017void World::spawn(WorldEntity* entity)
1018{
1019  this->entities->add (entity);
1020  entity->postSpawn ();
1021}
1022
1023
1024/**
1025 *  add and spawn a new entity to this world
1026 * @param entity to be added
1027 * @param absCoor At what coordinates to add this entity.
1028 * @param absDir In which direction should it look.
1029*/
1030void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1031{
1032  this->entities->add (entity);
1033
1034  entity->setAbsCoor (*absCoor);
1035  entity->setAbsDir (*absDir);
1036
1037  entity->postSpawn ();
1038}
1039
1040
1041/**
1042 *  add and spawn a new entity to this world
1043 * @param entity to be added
1044 * @param entity to be added to (PNode)
1045 * @param At what relative  coordinates to add this entity.
1046 * @param In which relative direction should it look.
1047*/
1048void World::spawn(WorldEntity* entity, PNode* parentNode,
1049                  Vector* relCoor, Quaternion* relDir)
1050{
1051  this->nullParent = NullParent::getInstance();
1052  if( parentNode != NULL)
1053    {
1054      parentNode->addChild (entity);
1055
1056      entity->setRelCoor (*relCoor);
1057      entity->setRelDir (*relDir);
1058
1059      this->entities->add (entity);
1060
1061      entity->postSpawn ();
1062    }
1063}
1064
1065
1066
1067/**
1068  \brief commands that the world must catch
1069  @returns false if not used by the world
1070*/
1071bool World::command(Command* cmd)
1072{
1073  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1074  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1075  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1076  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1077  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1078  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1079  return false;
1080}
1081
1082void World::setPath( const char* name)
1083{
1084  if (this->path)
1085    delete this->path;
1086  if (ResourceManager::isFile(name))
1087  {
1088    this->path = new char[strlen(name)+1];
1089    strcpy(this->path, name);
1090  }
1091  else
1092    {
1093      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1094      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1095    }
1096}
1097
1098const char* World::getPath( void)
1099{
1100  return path;
1101}
Note: See TracBrowser for help on using the repository browser.