Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: valgrind's second fruits….. the char-arrays
some time in the near future i will hopefully be faster in interpreting this WALLgrind… but it is great, i can tell you (or at least anyone that reads this :))

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