Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more fixes due to valgrind

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