Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: cleanup is almost perfect now

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
23#include "state.h"
24
25#include "p_node.h"
26#include "null_parent.h"
27#include "pilot_node.h"
28#include "track_node.h"
29#include "world_entity.h"
30#include "player.h"
31#include "camera.h"
32#include "environment.h"
33#include "skysphere.h"
34#include "skybox.h"
35#include "satellite.h"
36#include "test_entity.h"
37#include "terrain.h"
38#include "light.h"
39#include "text_engine.h"
40#include "load_param.h"
41
42#include "track_manager.h"
43#include "garbage_collector.h"
44#include "fast_factory.h"
45#include "animation_player.h"
46#include "particle_engine.h"
47#include "graphics_engine.h"
48#include "physics_engine.h"
49#include "fields.h"
50
51#include "md2Model.h"
52
53#include "glmenu_imagescreen.h"
54#include "list.h"
55#include "game_loader.h"
56
57#include "animation3d.h"
58
59#include "substring.h"
60
61#include "factory.h"
62
63#include "projectile.h"
64#include "event_handler.h"
65
66#include "sound_engine.h"
67#include "ogg_player.h"
68
69#include "class_list.h"
70
71#include "cd_engine.h"
72#include "npc.h"
73
74using namespace std;
75
76//! This creates a Factory to fabricate a World
77CREATE_FACTORY(World);
78
79World::World(const TiXmlElement* root)
80{
81  this->constuctorInit("", -1);
82  this->path = NULL;
83
84  this->loadParams(root);
85}
86
87/**
88  *  create a new World
89
90    This creates a new empty world!
91*/
92World::World (const char* name)
93{
94  this->path = NULL;
95  this->constuctorInit(name, -1);
96  //NullParent* np = NullParent::getInstance();
97}
98
99/**
100 *  creates a new World...
101 * @param worldID with this ID
102*/
103World::World (int worldID)
104{
105  this->path = NULL;
106  this->constuctorInit(NULL, worldID);
107}
108
109/**
110 *  remove the World from memory
111
112    delete everything explicitly, that isn't contained in the parenting tree!
113    things contained in the tree are deleted automaticaly
114 */
115World::~World ()
116{
117  delete Shell::getInstance();
118  PRINTF(3)("World::~World() - deleting current world\n");
119
120  // here everything that is alocated by the World is deleted
121  delete this->entities;
122  State::setWorldEntityList(NULL);
123
124
125  delete LightManager::getInstance();
126  delete TrackManager::getInstance();
127  delete ParticleEngine::getInstance();
128  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
129  delete PhysicsEngine::getInstance();
130
131  // external engines initialized by the orxonox-class get deleted
132  SoundEngine::getInstance()->flushAllBuffers();
133  SoundEngine::getInstance()->flushAllSources();
134  FastFactory::flushAll(true);
135
136
137  // erease everything that is left.
138  delete NullParent::getInstance();
139
140
141  // unload the resources !!
142  ResourceManager::getInstance()->unload(this->music);
143  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
144}
145
146/**
147 * initializes the world.
148 * @param name the name of the world
149 * @param worldID the ID of this world
150 *
151 * set all stuff here that is world generic and does not use to much memory
152 * because the real init() function StoryEntity::init() will be called
153 * shortly before start of the game.
154 * since all worlds are initiated/referenced before they will be started.
155 * NO LEVEL LOADING HERE - NEVER!
156*/
157void World::constuctorInit(const char* name, int worldID)
158{
159  this->setClassID(CL_WORLD, "World");
160
161  this->setName(name);
162  this->debugWorldNr = worldID;
163
164  this->music = NULL;
165}
166
167/**
168 * loads the parameters of a World from an XML-element
169 * @param root the XML-element to load from
170 */
171void World::loadParams(const TiXmlElement* root)
172{
173  PRINTF(4)("Creating a World\n");
174
175  LoadParam<World>(root, "identifier", this, &World::setStoryID)
176    .describe("Sets the StoryID of this world");
177
178  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
179    .describe("Sets the ID of the next world");
180
181  LoadParam<World>(root, "path", this, &World::setPath)
182    .describe("The Filename of this World (relative from the data-dir)");
183}
184
185/**
186 * this is executed just before load
187 *
188 * since the load function sometimes needs data, that has been initialized
189 * before the load and after the proceeding storyentity has finished
190*/
191ErrorMessage World::preLoad()
192{
193  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
194  this->cycle = 0;
195
196  /* init the world interface */
197  Shell::getInstance();
198
199  LightManager::getInstance();
200  NullParent::getInstance ();
201
202  AnimationPlayer::getInstance(); // initializes the animationPlayer
203  PhysicsEngine::getInstance();
204
205  this->localCamera = new Camera();
206  this->localCamera->setName ("World-Camera");
207
208  State::setCamera(this->localCamera, this->localCamera->getTarget());
209
210  GraphicsEngine::getInstance()->displayFPS(true);
211
212  CDEngine::getInstance()->setEntityList( this->entities);
213}
214
215
216/**
217 *  loads the World by initializing all resources, and set their default values.
218*/
219ErrorMessage World::load()
220{
221  PRINTF(3)("> Loading world: '%s'\n", getPath());
222  TiXmlElement* element;
223  GameLoader* loader = GameLoader::getInstance();
224
225  if( getPath() == NULL)
226    {
227      PRINTF(1)("World has no path specified for loading");
228      this->loadDebugWorld(this->getStoryID());
229      return (ErrorMessage){213,"Path not specified","World::load()"};
230    }
231
232  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
233  // load the campaign document
234  if( !XMLDoc->LoadFile())
235  {
236    // report an error
237    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
238    delete XMLDoc;
239    return (ErrorMessage){213,"XML File parsing error","World::load()"};
240  }
241
242  // check basic validity
243  TiXmlElement* root = XMLDoc->RootElement();
244  assert( root != NULL);
245
246  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
247    {
248      // report an error
249      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
250      delete XMLDoc;
251      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
252    }
253
254  // load the parameters
255  // name
256  char* temp;
257  const char* string = grabParameter( root, "name");
258  if( string == NULL)
259    {
260      PRINTF(2)("World is missing a proper 'name'\n");
261      string = "Unknown";
262      temp = new char[strlen(string + 2)];
263      strcpy( temp, string);
264      this->setName(temp);
265    }
266  else
267    {
268      temp = new char[strlen(string + 2)];
269      strcpy( temp, string);
270      this->setName(temp);
271    }
272
273  ////////////////
274  // LOADSCREEN //
275  ////////////////
276  element = root->FirstChildElement("LoadScreen");
277  if (element == NULL)
278    {
279      PRINTF(2)("no LoadScreen specified, loading default\n");
280
281      glmis->setBackgroundImage("pictures/load_screen.jpg");
282      this->glmis->setMaximum(8);
283      this->glmis->draw();
284    }
285  else
286    {
287      this->glmis->loadParams(element);
288      this->glmis->draw();
289    }
290  this->glmis->draw();
291
292  ////////////////////////
293  // find WorldEntities //
294  ////////////////////////
295
296  element = root->FirstChildElement("WorldEntities");
297
298  if( element == NULL)
299    {
300      PRINTF(1)("World is missing 'WorldEntities'\n");
301    }
302  else
303    {
304      element = element->FirstChildElement();
305      // load Players/Objects/Whatever
306      PRINTF(4)("Loading WorldEntities\n");
307      while( element != NULL)
308        {
309          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
310          if( created != NULL) this->spawn( created);
311          // if we load a 'Player' we use it as localPlayer
312          //todo do this more elegant
313          if( element->Value() != NULL && !strcmp( element->Value(), "Player"))
314          {
315            localPlayer = (Player*) created;
316            CDEngine::getInstance()->setPlayer(localPlayer);
317          }
318          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
319          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
320          {
321            terrain = (Terrain*) created;
322            CDEngine::getInstance()->setTerrain(terrain);
323          }
324          element = element->NextSiblingElement();
325          glmis->step(); //! @todo temporary
326        }
327      PRINTF(4)("Done loading WorldEntities\n");
328    }
329
330    //////////////////////////////
331    // LOADING ADDITIONAL STUFF //
332    //////////////////////////////
333
334    LoadParam<LightManager>(root, "LightManager", LightManager::getInstance(), &LightManager::loadParams);
335
336    LoadParam<ParticleEngine>(root, "ParticleEngine", ParticleEngine::getInstance(), &ParticleEngine::loadParams);
337    LoadParam<PhysicsEngine>(root, "PhysicsEngine", PhysicsEngine::getInstance(), &PhysicsEngine::loadParams);
338
339  // find Track
340  element = root->FirstChildElement( "Track");
341  if( element == NULL)
342    {
343      PRINTF(0)("World is missing a 'Track'\n");
344    }
345  else
346    {
347      //load track
348      PRINTF(4)("Loading Track\n");
349
350      TrackManager::getInstance()->loadParams( element);
351      TrackManager::getInstance()->finalize();
352    }
353
354  // free the XML data
355
356  delete XMLDoc;
357  /* GENERIC LOADING PROCESS FINISHED */
358
359  // bind input
360  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
361  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
362  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
363  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
364  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
365  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
366  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
367
368  // bind camera
369  //this->localCamera->bind (localPlayer);
370 // this->localPlayer->addChild (this->localCamera);
371
372
373  //        TrackManager::getInstance()->setBindSlave(env);
374  PNode* tn = TrackManager::getInstance()->getTrackNode();
375  tn->addChild(this->localPlayer);
376
377  //localCamera->setParent(TrackNode::getInstance());
378  tn->addChild(this->localCamera);
379  localCamera->lookAt(tn);
380  localCamera->setClipRegion(1, 10000.0);
381  this->localPlayer->setParentMode(PNODE_ALL);
382  Vector* cameraOffset = new Vector (0, 5, -10);
383  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
384
385  this->sky->setParent(this->localCamera);
386
387  // initialize debug coord system
388  objectList = glGenLists(1);
389  glNewList (objectList, GL_COMPILE);
390
391  //TrackManager::getInstance()->drawGraph(.01);
392  //TrackManager::getInstance()->debug(2);
393  glEndList();
394
395  SoundEngine::getInstance()->setListener(this->localCamera);
396
397
398
399  ////////////
400  // STATIC //
401  ////////////
402
403  Gravity* test = new Gravity();
404
405  // SYSTEM TRAILING THE PLAYER
406  // Creating a Test Particle System
407
408  //new PhysicsConnection(system, gravity);
409  //    new PhysicsConnection(this->localPlayer, gravity);
410
411//   TestEntity* testEntity = new TestEntity();
412//   testEntity->setRelCoor(Vector(570, 10, -15));
413//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
414//   this->spawn(testEntity);
415
416  TestEntity* testEntity2 = new TestEntity();
417  testEntity2->setAnim(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 = (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;
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.